mirror of
https://github.com/Bluewhale1337/ElvUIModernized.git
synced 2026-07-27 16:34:45 +00:00
1
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
## Interface: 11200
|
||||
## Title: !Compatibility
|
||||
## Notes: Compatibility functions for Vanilla
|
||||
## Version: 1.0
|
||||
|
||||
api\api.xml
|
||||
debugTools.lua
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="wowLua.lua"/>
|
||||
<Script file="wowAPI.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,103 @@
|
||||
--Cache global variables
|
||||
local _G = getfenv()
|
||||
local assert = assert
|
||||
local error = error
|
||||
local type = type
|
||||
local unpack = unpack
|
||||
local date = date
|
||||
local gsub = string.gsub
|
||||
|
||||
function hooksecurefunc(arg1, arg2, arg3)
|
||||
if type(arg1) == "string" then
|
||||
arg1, arg2, arg3 = _G, arg1, arg2
|
||||
end
|
||||
|
||||
local orig = arg1[arg2]
|
||||
if type(orig) ~= "function" then
|
||||
error("The function "..arg2.." does not exist", 2)
|
||||
end
|
||||
|
||||
arg1[arg2] = function(...)
|
||||
local tmp = {orig(unpack(arg))}
|
||||
arg3(unpack(arg))
|
||||
return unpack(tmp)
|
||||
end
|
||||
end
|
||||
|
||||
local function noop() end
|
||||
function HookScript(frame, method, func)
|
||||
assert(frame, "HookScript: frame argument missing")
|
||||
|
||||
local orig = frame:GetScript(method) or noop
|
||||
frame:SetScript(method, function(...)
|
||||
local tmp = {orig(unpack(arg))}
|
||||
func(unpack(arg))
|
||||
return unpack(tmp)
|
||||
end)
|
||||
end
|
||||
|
||||
function BetterDate(formatString, timeVal)
|
||||
local dateTable = date("*t", timeVal)
|
||||
local amString = (dateTable.hour >= 12) and "PM" or "AM"
|
||||
|
||||
--First, we'll replace %p with the appropriate AM or PM.
|
||||
formatString = gsub(formatString, "^%%p", amString) --Replaces %p at the beginning of the string with the am/pm token
|
||||
formatString = gsub(formatString, "([^%%])%%p", "%1"..amString) -- Replaces %p anywhere else in the string, but doesn't replace %%p (since the first % escapes the second)
|
||||
|
||||
return date(formatString, timeVal)
|
||||
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)
|
||||
local levelDiff = level - UnitLevel("player")
|
||||
local color
|
||||
if levelDiff >= 5 then
|
||||
return QuestDifficultyColors["impossible"]
|
||||
elseif levelDiff >= 3 then
|
||||
return QuestDifficultyColors["verydifficult"]
|
||||
elseif levelDiff >= -2 then
|
||||
return QuestDifficultyColors["difficult"]
|
||||
elseif -levelDiff <= GetQuestGreenRange() then
|
||||
return QuestDifficultyColors["standard"]
|
||||
else
|
||||
return QuestDifficultyColors["trivial"]
|
||||
end
|
||||
end
|
||||
|
||||
function EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay)
|
||||
if displayMode == "MENU" then
|
||||
menuFrame.displayMode = displayMode
|
||||
end
|
||||
UIDropDownMenu_Initialize(menuFrame, EasyMenu_Initialize, displayMode)
|
||||
ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList)
|
||||
end
|
||||
|
||||
function EasyMenu_Initialize()
|
||||
print(level, info)
|
||||
for index = 1, getn(menuList) do
|
||||
local value = menuList[index]
|
||||
if value.text then
|
||||
value.index = index;
|
||||
UIDropDownMenu_AddButton(value, level)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,142 @@
|
||||
--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
|
||||
@@ -0,0 +1,69 @@
|
||||
--Cache global variables
|
||||
local strmatch = strmatch
|
||||
--WoW API
|
||||
local GetCVar = GetCVar
|
||||
local IsAddOnLoaded = IsAddOnLoaded
|
||||
local LoadAddOn = LoadAddOn
|
||||
local UIParentLoadAddOn = UIParentLoadAddOn
|
||||
|
||||
local _ERROR_COUNT = 0
|
||||
local _ERROR_LIMIT = 1000
|
||||
|
||||
function _ERRORMESSAGE_NEW(message)
|
||||
debuginfo()
|
||||
|
||||
LoadAddOn("!DebugTools")
|
||||
local loaded = IsAddOnLoaded("!DebugTools")
|
||||
|
||||
-- if (GetCVar("scriptErrors") == 1) then
|
||||
if (not loaded or DEBUG_DEBUGTOOLS) then
|
||||
ScriptErrors_Message:SetText(message)
|
||||
ScriptErrors:Show()
|
||||
if (DEBUG_DEBUGTOOLS) then
|
||||
ScriptErrorsFrame_OnError(message)
|
||||
end
|
||||
else
|
||||
ScriptErrorsFrame_OnError(message)
|
||||
end
|
||||
-- elseif (loaded) then
|
||||
-- ScriptErrorsFrame_OnError(message, true)
|
||||
-- end
|
||||
|
||||
_ERROR_COUNT = _ERROR_COUNT + 1
|
||||
if (_ERROR_COUNT == _ERROR_LIMIT) then
|
||||
StaticPopup_Show("TOO_MANY_LUA_ERRORS")
|
||||
end
|
||||
|
||||
return message
|
||||
end
|
||||
|
||||
seterrorhandler(_ERRORMESSAGE_NEW)
|
||||
|
||||
function message(text)
|
||||
if (not ScriptErrors:IsShown()) then
|
||||
ScriptErrors_Message:SetText(text)
|
||||
ScriptErrors:Show()
|
||||
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,12 @@
|
||||
## Interface: 20400
|
||||
## Title: !DebugTools
|
||||
## Notes: Tools for developing addons (Blizzard UI Debug Tools)
|
||||
## Author: Blizzard Entertainment
|
||||
## Special Thanks: Iriel, Kirov, Esamynn
|
||||
## Version: 1.0
|
||||
## Dependencies: !Compatibility
|
||||
|
||||
Compatibility.lua
|
||||
Dump.lua
|
||||
Blizzard_DebugTools.lua
|
||||
Blizzard_DebugTools.xml
|
||||
@@ -0,0 +1,729 @@
|
||||
local _G = getfenv()
|
||||
|
||||
EVENT_TRACE_EVENT_HEIGHT = 16;
|
||||
EVENT_TRACE_MAX_ENTRIES = 1000;
|
||||
|
||||
DEBUGLOCALS_LEVEL = 4;
|
||||
local _normalFontColor = {1, .82, 0, 1};
|
||||
|
||||
EVENT_TRACE_SYSTEM_TIMES = {};
|
||||
EVENT_TRACE_SYSTEM_TIMES["System"] = true;
|
||||
EVENT_TRACE_SYSTEM_TIMES["Elapsed"] = true;
|
||||
|
||||
EVENT_TRACE_EVENT_COLORS = {};
|
||||
EVENT_TRACE_EVENT_COLORS["System"] = _normalFontColor;
|
||||
EVENT_TRACE_EVENT_COLORS["Elapsed"] = {.6, .6, .6, 1};
|
||||
|
||||
local _EventTraceFrame;
|
||||
|
||||
local _framesSinceLast = 0;
|
||||
local _timeSinceLast = 0;
|
||||
|
||||
local _timer = CreateFrame("FRAME");
|
||||
_timer:SetScript("OnUpdate", function () _framesSinceLast = _framesSinceLast + 1; _timeSinceLast = _timeSinceLast + arg1; end);
|
||||
|
||||
function EventTraceFrame_OnLoad(self)
|
||||
local frameName = self:GetName()
|
||||
_G[frameName.."Scroll"].thumb = _G[frameName.."ScrollThumb"]
|
||||
_G[frameName.."DialogBG"]:SetVertexColor(0, 0, 0)
|
||||
_G[frameName.."DialogBG"]:SetAlpha(0.75)
|
||||
|
||||
self.buttons = {};
|
||||
self.events = {};
|
||||
self.times = {};
|
||||
self.rawtimes = {};
|
||||
self.eventids = {};
|
||||
self.eventtimes = {};
|
||||
self.numhandlers = {};
|
||||
self.slowesthandlers = {};
|
||||
self.slowesthandlertimes = {}
|
||||
self.timeSinceLast = {};
|
||||
self.framesSinceLast = {};
|
||||
self.args = {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
|
||||
self.ignoredEvents = {};
|
||||
self.lastIndex = 0;
|
||||
self.visibleButtons = 0;
|
||||
_EventTraceFrame = self;
|
||||
self:SetScript("OnSizeChanged", function() EventTraceFrame_OnSizeChanged(this, arg1, arg2) end);
|
||||
EventTraceFrame_OnSizeChanged(self, self:GetWidth(), self:GetHeight());
|
||||
self:EnableMouse(true);
|
||||
self:EnableMouseWheel(true);
|
||||
self:SetScript("OnMouseWheel", function() EventTraceFrame_OnMouseWheel(tris, arg1) end);
|
||||
end
|
||||
|
||||
local _workTable = {};
|
||||
function EventTraceFrame_OnEvent (self, event, ...)
|
||||
if (not self.ignoredEvents[event]) then
|
||||
if (_framesSinceLast ~= 0 and event ~= "On Update") then
|
||||
EventTraceFrame_OnEvent(self, "On Update");
|
||||
end
|
||||
|
||||
local nextIndex = self.lastIndex + 1;
|
||||
if (nextIndex > EVENT_TRACE_MAX_ENTRIES) then
|
||||
local staleIndex = nextIndex - EVENT_TRACE_MAX_ENTRIES;
|
||||
self.events[staleIndex] = nil;
|
||||
self.times[staleIndex] = nil;
|
||||
self.rawtimes[staleIndex] = nil;
|
||||
self.timeSinceLast[staleIndex] = nil;
|
||||
self.framesSinceLast[staleIndex] = nil;
|
||||
self.eventids[staleIndex] = nil;
|
||||
self.eventtimes[staleIndex] = nil;
|
||||
self.numhandlers[staleIndex] = nil;
|
||||
self.slowesthandlers[staleIndex] = nil;
|
||||
self.slowesthandlertimes[staleIndex] = nil;
|
||||
for k, v in next, self.args do
|
||||
self.args[k][staleIndex] = nil;
|
||||
end
|
||||
end
|
||||
|
||||
if (event == "Begin Capture" or event == "End Capture") then
|
||||
self.times[nextIndex] = "System";
|
||||
if (self.eventsToCapture) then
|
||||
self.events[nextIndex] = string.format("%s (%s events)", event, tostring(self.eventsToCapture));
|
||||
else
|
||||
self.events[nextIndex] = event;
|
||||
end
|
||||
self.timeSinceLast[nextIndex] = 0;
|
||||
self.framesSinceLast[nextIndex] = 0;
|
||||
elseif (event == "On Update") then
|
||||
self.times[nextIndex] = "Elapsed";
|
||||
self.events[nextIndex] = string.format("%.3f sec - %d frame(s)", _timeSinceLast, _framesSinceLast);
|
||||
self.timeSinceLast[nextIndex] = _timeSinceLast;
|
||||
self.framesSinceLast[nextIndex] = _framesSinceLast;
|
||||
_timeSinceLast = 0;
|
||||
_framesSinceLast = 0;
|
||||
else
|
||||
self.events[nextIndex] = event;
|
||||
local seconds = GetTime();
|
||||
local minutes = math.floor(math.floor(seconds) / 60);
|
||||
local hours = math.floor(minutes / 60);
|
||||
seconds = seconds - 60 * minutes;
|
||||
minutes = minutes - 60 * hours;
|
||||
hours = math.mod(hours, 1000);
|
||||
self.times[nextIndex] = string.format("%.2d:%.2d:%06.3f", hours, minutes, seconds);
|
||||
self.timeSinceLast[nextIndex] = 0;
|
||||
self.framesSinceLast[nextIndex] = 0;
|
||||
self.eventids[nextIndex] = GetCurrentEventID();
|
||||
|
||||
local numArgs = select("#", unpack(arg));
|
||||
for i=1, numArgs do
|
||||
if (not self.args[i]) then
|
||||
self.args[i] = {};
|
||||
end
|
||||
self.args[i][nextIndex] = select(i, unpack(arg));
|
||||
end
|
||||
|
||||
if (self.eventsToCapture) then
|
||||
self.eventsToCapture = self.eventsToCapture - 1;
|
||||
end
|
||||
end
|
||||
|
||||
self.rawtimes[nextIndex] = GetTime();
|
||||
self.lastIndex = nextIndex;
|
||||
if (self.eventsToCapture and self.eventsToCapture <= 0) then
|
||||
self.eventsToCapture = nil;
|
||||
EventTraceFrame_StopEventCapture();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnShow()
|
||||
wipe(this.ignoredEvents);
|
||||
local scrollBar = _G["EventTraceFrameScroll"];
|
||||
local minValue, maxValue = scrollBar:GetMinMaxValues();
|
||||
scrollBar:SetValue(maxValue);
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnUpdate ()
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnSizeChanged (self, width, height)
|
||||
local numButtonsToDisplay = math.floor((height - 36)/EVENT_TRACE_EVENT_HEIGHT);
|
||||
local numButtonsCreated = getn(self.buttons)
|
||||
|
||||
if (numButtonsCreated < numButtonsToDisplay) then
|
||||
for i = numButtonsCreated + 1, numButtonsToDisplay do
|
||||
local button = CreateFrame("BUTTON", "EventTraceFrameButton" .. i, self, "EventTraceEventTemplate");
|
||||
button:SetPoint("BOTTOMLEFT", 12, (16 * (i - 1)) + 12);
|
||||
button:SetPoint("RIGHT", -28, 0);
|
||||
tinsert(self.buttons, button);
|
||||
end
|
||||
for i = self.visibleButtons + 1, numButtonsToDisplay do
|
||||
self.buttons[i]:Show();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
EventTraceFrame_Update();
|
||||
elseif (self.visibleButtons < numButtonsToDisplay) then
|
||||
for i = self.visibleButtons + 1, numButtonsToDisplay do
|
||||
self.buttons[i]:Show();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
EventTraceFrame_Update();
|
||||
elseif (numButtonsToDisplay < self.visibleButtons) then
|
||||
for i = numButtonsToDisplay + 1, self.visibleButtons do
|
||||
-- self.buttons[i]:Hide();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_Update ()
|
||||
local offset = 0;
|
||||
|
||||
local scrollBar = _G["EventTraceFrameScroll"];
|
||||
local scrollBarValue = scrollBar:GetValue();
|
||||
local minValue, maxValue = scrollBar:GetMinMaxValues();
|
||||
|
||||
local firstID = max(1, _EventTraceFrame.lastIndex - EVENT_TRACE_MAX_ENTRIES + 1);
|
||||
local lastID = _EventTraceFrame.lastIndex or 1;
|
||||
|
||||
if (firstID >= lastID) then
|
||||
scrollBar:SetMinMaxValues(firstID-1, lastID);
|
||||
else
|
||||
scrollBar:SetMinMaxValues(firstID, lastID);
|
||||
end
|
||||
if (scrollBarValue < firstID) then
|
||||
scrollBar:SetValue(firstID);
|
||||
scrollBarValue = firstID;
|
||||
end
|
||||
|
||||
if (scrollBarValue < 1) then
|
||||
scrollBarValue = 1;
|
||||
elseif (not _EventTraceFrame.selectedEvent) then
|
||||
if (scrollBarValue == maxValue) then
|
||||
scrollBar:SetValue(_EventTraceFrame.lastIndex);
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, _EventTraceFrame.visibleButtons do
|
||||
local button = _EventTraceFrame.buttons[i];
|
||||
if (button) then
|
||||
local index = scrollBarValue - (i - 1);
|
||||
local event = _EventTraceFrame.events[index];
|
||||
if (event) then
|
||||
local timeString = _EventTraceFrame.times[index]
|
||||
button.index = index;
|
||||
button.time:SetText(timeString);
|
||||
button.event:SetText(event);
|
||||
if (_EventTraceFrame.eventids[index] and not _EventTraceFrame.eventtimes[index]) then
|
||||
local eventTime, numHandlers, slowestHandler, slowestHandlerTime = GetEventTime(_EventTraceFrame.eventids[index]);
|
||||
_EventTraceFrame.eventtimes[index] = eventTime;
|
||||
_EventTraceFrame.numhandlers[index] = numHandlers;
|
||||
_EventTraceFrame.slowesthandlers[index] = slowestHandler;
|
||||
_EventTraceFrame.slowesthandlertimes[index] = slowestHandlerTime;
|
||||
end
|
||||
local color = EVENT_TRACE_EVENT_COLORS[event] or EVENT_TRACE_EVENT_COLORS[timeString];
|
||||
if (color) then
|
||||
button.time:SetTextColor(unpack(color));
|
||||
button.event:SetTextColor(unpack(color));
|
||||
else
|
||||
local eventTime = _EventTraceFrame.eventtimes[index];
|
||||
if (eventTime and eventTime > 50.0) then
|
||||
button.time:SetTextColor(1, 0, 0, 1);
|
||||
button.event:SetTextColor(1, 0, 0, 1);
|
||||
elseif (eventTime and eventTime > 20.0) then
|
||||
button.time:SetTextColor(1, .5, 0, 1);
|
||||
button.event:SetTextColor(1, .5, 0, 1);
|
||||
elseif (eventTime and eventTime > 10.0) then
|
||||
button.time:SetTextColor(1, .8, 0, 1);
|
||||
button.event:SetTextColor(1, .8, 0, 1);
|
||||
elseif (eventTime and eventTime > 5.0) then
|
||||
button.time:SetTextColor(1, 1, .6, 1);
|
||||
button.event:SetTextColor(1, 1, .6, 1);
|
||||
else
|
||||
button.time:SetTextColor(1, 1, 1, 1);
|
||||
button.event:SetTextColor(1, 1, 1, 1);
|
||||
end
|
||||
end
|
||||
button:Show();
|
||||
if (_EventTraceFrame.selectedEvent) then
|
||||
if (index == _EventTraceFrame.selectedEvent) then
|
||||
EventTraceFrameEvent_DisplayTooltip(button);
|
||||
button:GetHighlightTexture():SetVertexColor(.15, .25, 1, .35);
|
||||
button:LockHighlight(true);
|
||||
button.wasSelected = true;
|
||||
elseif (button.wasSelected) then
|
||||
button.wasSelected = nil;
|
||||
button:GetHighlightTexture():SetVertexColor(.8, .8, 1, .15);
|
||||
button:UnlockHighlight();
|
||||
end
|
||||
else
|
||||
if (button.wasSelected) then
|
||||
button.wasSelected = nil;
|
||||
button:GetHighlightTexture():SetVertexColor(.8, .8, 1, .15);
|
||||
button:UnlockHighlight();
|
||||
end
|
||||
end
|
||||
if (button == GetMouseFocus()) then
|
||||
EventTraceFrameEvent_OnEnter(button);
|
||||
else
|
||||
button.HideButton:Hide();
|
||||
end
|
||||
else
|
||||
button.index = index;
|
||||
button:Hide();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EventTraceFrame_UpdateKeyboardStatus();
|
||||
end
|
||||
|
||||
function EventTraceFrame_StartEventCapture()
|
||||
if (_EventTraceFrame.started) then
|
||||
return;
|
||||
end
|
||||
|
||||
EventHandler_Enable()
|
||||
|
||||
_EventTraceFrame.started = true;
|
||||
_framesSinceLast = 0;
|
||||
_timeSinceLast = 0;
|
||||
_EventTraceFrame:RegisterAllEvents();
|
||||
EventTraceFrame_OnEvent(_EventTraceFrame, "Begin Capture");
|
||||
end
|
||||
|
||||
function EventTraceFrame_StopEventCapture()
|
||||
if (not _EventTraceFrame.started) then
|
||||
return;
|
||||
end
|
||||
|
||||
EventHandler_Disable()
|
||||
|
||||
_EventTraceFrame.started = false;
|
||||
_framesSinceLast = 0;
|
||||
_timeSinceLast = 0;
|
||||
_EventTraceFrame:UnregisterAllEvents();
|
||||
EventTraceFrame_OnEvent(_EventTraceFrame, "End Capture");
|
||||
end
|
||||
|
||||
function EventTraceFrame_HandleSlashCmd(msg)
|
||||
msg = strlower(msg);
|
||||
if (msg == "start") then
|
||||
EventTraceFrame_StartEventCapture();
|
||||
elseif (msg == "stop") then
|
||||
EventTraceFrame_StopEventCapture();
|
||||
elseif (tonumber(msg) and tonumber(msg) > 0) then
|
||||
if (not _EventTraceFrame.started) then
|
||||
_EventTraceFrame.eventsToCapture = tonumber(msg);
|
||||
EventTraceFrame_StartEventCapture();
|
||||
end
|
||||
elseif (msg == "") then
|
||||
if (not _EventTraceFrame:IsShown()) then
|
||||
_EventTraceFrame:Show();
|
||||
if (_EventTraceFrame.started == nil) then
|
||||
EventTraceFrame_StartEventCapture();
|
||||
end
|
||||
else
|
||||
_EventTraceFrame:Hide();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnMouseWheel(self, delta)
|
||||
local scrollBar = _G["EventTraceFrameScroll"];
|
||||
local minVal, maxVal = scrollBar:GetMinMaxValues();
|
||||
local currentValue = scrollBar:GetValue();
|
||||
|
||||
local newValue = currentValue - (delta * 3);
|
||||
newValue = max(newValue, minVal);
|
||||
newValue = min(newValue, maxVal);
|
||||
if (newValue ~= currentValue) then
|
||||
scrollBar:SetValue(newValue);
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_UpdateKeyboardStatus()
|
||||
if (_EventTraceFrame.selectedEvent) then
|
||||
local focus = GetMouseFocus();
|
||||
if (focus == _EventTraceFrame or (focus and focus:GetParent() == _EventTraceFrame)) then
|
||||
_EventTraceFrame:EnableKeyboard(true);
|
||||
return;
|
||||
end
|
||||
end
|
||||
_EventTraceFrame:EnableKeyboard(false);
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnKeyUp(self, key)
|
||||
if (key == "ESCAPE") then
|
||||
self.selectedEvent = nil;
|
||||
EventTraceTooltip:Hide();
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_RemoveEvent(i)
|
||||
if (i >= 1 and i <= EventTraceFrame.lastIndex) then
|
||||
tremove(EventTraceFrame.events, i);
|
||||
tremove(EventTraceFrame.times, i);
|
||||
tremove(EventTraceFrame.rawtimes, i);
|
||||
tremove(EventTraceFrame.timeSinceLast, i);
|
||||
tremove(EventTraceFrame.framesSinceLast, i);
|
||||
tremove(EventTraceFrame.eventtimes, i);
|
||||
tremove(EventTraceFrame.eventids, i);
|
||||
tremove(EventTraceFrame.numhandlers, i);
|
||||
tremove(EventTraceFrame.slowesthandlers, i);
|
||||
tremove(EventTraceFrame.slowesthandlertimes, i);
|
||||
|
||||
for k, v in next, EventTraceFrame.args do
|
||||
for j = i, EventTraceFrame.lastIndex do
|
||||
EventTraceFrame.args[k][j] = EventTraceFrame.args[k][j+1];
|
||||
end
|
||||
end
|
||||
EventTraceFrame.lastIndex = EventTraceFrame.lastIndex-1;
|
||||
end
|
||||
end
|
||||
|
||||
local TIME_LABEL = "Time:";
|
||||
local DETAILS_LABEL = "Details:";
|
||||
local SLOWEST_LABEL = "Slowest:";
|
||||
local ARGUMENT_LABEL_FORMAT = "arg %d:";
|
||||
local NUM_HANDLERS_FORMAT = "(%d handlers)";
|
||||
local EVENT_TIME_FORMAT = "%.2fms";
|
||||
|
||||
local function EventTrace_FormatArgValue (val)
|
||||
if (type(val) == "string") then
|
||||
return string.format('"%s"', val);
|
||||
elseif (type(val) == "number") then
|
||||
return tostring(val);
|
||||
elseif (type(val) == "boolean") then
|
||||
return string.format('|cffaaaaff%s|r', tostring(val));
|
||||
elseif (type(val) == "table" or type(val) == "bool") then
|
||||
return string.format('|cffffaaaa%s|r', tostring(val));
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_DisplayTooltip (eventButton)
|
||||
local index = eventButton.index;
|
||||
if (not index) then
|
||||
return;
|
||||
end
|
||||
|
||||
local tooltip = _G["EventTraceTooltip"];
|
||||
tooltip:SetOwner(eventButton, "ANCHOR_NONE");
|
||||
tooltip:SetPoint("TOPLEFT", eventButton, "TOPRIGHT", 24, 2);
|
||||
local timeString = _EventTraceFrame.times[index]
|
||||
if (EVENT_TRACE_SYSTEM_TIMES[timeString]) then
|
||||
tooltip:AddLine(timeString, 1, 1, 1);
|
||||
tooltip:AddDoubleLine(TIME_LABEL, _EventTraceFrame.rawtimes[index], 1, .82, 0, 1, 1, 1);
|
||||
tooltip:AddDoubleLine(DETAILS_LABEL, _EventTraceFrame.events[index], 1, .82, 0, 1, 1, 1);
|
||||
else
|
||||
tooltip:AddLine(_EventTraceFrame.events[index], 1, 1, 1);
|
||||
local eventTime = _EventTraceFrame.eventtimes[index];
|
||||
if (eventTime) then
|
||||
if (eventTime < 0) then
|
||||
eventTime = "?";
|
||||
else
|
||||
eventTime = format(EVENT_TIME_FORMAT, eventTime);
|
||||
end
|
||||
tooltip:AddDoubleLine(TIME_LABEL, eventTime .. " " .. format(NUM_HANDLERS_FORMAT, _EventTraceFrame.numhandlers[index] or 0), 1, .82, 0, 1, 1, 1);
|
||||
else
|
||||
tooltip:AddDoubleLine(TIME_LABEL, _EventTraceFrame.rawtimes[index], 1, .82, 0, 1, 1, 1);
|
||||
end
|
||||
if (_EventTraceFrame.slowesthandlers[index]) then
|
||||
tooltip:AddDoubleLine(SLOWEST_LABEL, format("%s (%.2fms)", _EventTraceFrame.slowesthandlers[index], _EventTraceFrame.slowesthandlertimes[index]), 1, .82, 0, 1, 1, 1);
|
||||
end
|
||||
for k, v in ipairs(EventTraceFrame.args) do
|
||||
if (v[index]) then
|
||||
tooltip:AddDoubleLine(format(ARGUMENT_LABEL_FORMAT, k), EventTrace_FormatArgValue(v[index]), 1, .82, 0, 1, 1, 1);
|
||||
end
|
||||
end
|
||||
end
|
||||
tooltip:Show();
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnEnter (self)
|
||||
if (not EVENT_TRACE_SYSTEM_TIMES[EventTraceFrame.times[self.index]]) then
|
||||
self.HideButton:Show();
|
||||
else
|
||||
self.HideButton:Hide();
|
||||
end
|
||||
if (_EventTraceFrame.selectedEvent) then
|
||||
return;
|
||||
else
|
||||
EventTraceFrameEvent_DisplayTooltip(self);
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnLeave (self)
|
||||
if (not self.HideButton == GetMouseFocus()) then
|
||||
self.HideButton:Hide();
|
||||
end
|
||||
if (not _EventTraceFrame.selectedEvent) then
|
||||
EventTraceTooltip:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnClick (self)
|
||||
if (_EventTraceFrame.selectedEvent == self.index) then
|
||||
_EventTraceFrame.selectedEvent = nil;
|
||||
else
|
||||
_EventTraceFrame.selectedEvent = self.index;
|
||||
end
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
|
||||
function EventTraceFrameEventHideButton_OnClick (button)
|
||||
local eventName = button:GetParent().event:GetText();
|
||||
EventTraceFrame.ignoredEvents[eventName] = 1;
|
||||
EventTraceFrame.selectedEvent = nil;
|
||||
|
||||
for i = EventTraceFrame.lastIndex, 1, -1 do
|
||||
if (EventTraceFrame.events[i] == eventName) then
|
||||
EventTraceFrame_RemoveEvent(i);
|
||||
end
|
||||
end
|
||||
|
||||
local lastWasElapsed = false;
|
||||
for i = EventTraceFrame.lastIndex, 1, -1 do
|
||||
if (EventTraceFrame.times[i] == "Elapsed") then
|
||||
if (lastWasElapsed) then
|
||||
EventTraceFrame.timeSinceLast[i] = EventTraceFrame.timeSinceLast[i] + EventTraceFrame.timeSinceLast[i+1];
|
||||
EventTraceFrame.framesSinceLast[i] = EventTraceFrame.framesSinceLast[i] + EventTraceFrame.framesSinceLast[i+1];
|
||||
EventTraceFrame.events[i] = string.format(string.format("%.3f sec", EventTraceFrame.timeSinceLast[i]) .. " - %d frame(s)", EventTraceFrame.framesSinceLast[i]);
|
||||
EventTraceFrame_RemoveEvent(i+1);
|
||||
end
|
||||
lastWasElapsed = true;
|
||||
else
|
||||
lastWasElapsed = false;
|
||||
end
|
||||
end
|
||||
|
||||
EventTraceFrame_Update();
|
||||
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 WARNING_AS_ERROR_FORMAT = "|cffffd200Message:|r|cffffffff %s|r\n|cffffd200Time:|r|cffffffff %s|r\n|cffffd200Count:|r|cffffffff %s|r";
|
||||
|
||||
local WARNING_FORMAT = "Lua Warning:\n"..WARNING_AS_ERROR_FORMAT;
|
||||
|
||||
local INDEX_ORDER_FORMAT = "%d / %d"
|
||||
|
||||
local _ScriptErrorsFrame;
|
||||
|
||||
function ScriptErrorsFrame_OnLoad (self)
|
||||
local frameName = self:GetName()
|
||||
self.title = _G[frameName.."Title"]
|
||||
self.indexLabel = _G[frameName.."IndexLabel"]
|
||||
self.reload = _G[frameName.."Reload"]
|
||||
self.previous = _G[frameName.."Previous"]
|
||||
self.next = _G[frameName.."Next"]
|
||||
self.close = _G[frameName.."CloseButton"]
|
||||
|
||||
self.title:SetText(LUA_ERROR);
|
||||
self:RegisterForDrag("LeftButton");
|
||||
self.seen = {};
|
||||
self.order = {};
|
||||
self.count = {};
|
||||
self.messages = {};
|
||||
self.times = {};
|
||||
_ScriptErrorsFrame = self;
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_OnShow (self)
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_OnError (message, keepHidden)
|
||||
local stack = debugstack(DEBUGLOCALS_LEVEL);
|
||||
|
||||
local messageStack = message..stack;
|
||||
|
||||
if (_ScriptErrorsFrame) then
|
||||
local index = _ScriptErrorsFrame.seen[messageStack];
|
||||
if (index) then
|
||||
_ScriptErrorsFrame.count[index] = _ScriptErrorsFrame.count[index] + 1;
|
||||
_ScriptErrorsFrame.messages[index] = message;
|
||||
_ScriptErrorsFrame.times[index] = date();
|
||||
else
|
||||
tinsert(_ScriptErrorsFrame.order, stack);
|
||||
index = getn(_ScriptErrorsFrame.order);
|
||||
_ScriptErrorsFrame.count[index] = 1;
|
||||
_ScriptErrorsFrame.messages[index] = message;
|
||||
_ScriptErrorsFrame.times[index] = date();
|
||||
_ScriptErrorsFrame.seen[messageStack] = index;
|
||||
end
|
||||
|
||||
if (not _ScriptErrorsFrame:IsShown() and not keepHidden) then
|
||||
_ScriptErrorsFrame.index = index;
|
||||
_ScriptErrorsFrame:Show();
|
||||
else
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_Update ()
|
||||
local editBox = ScriptErrorsFrameScrollFrameText;
|
||||
local index = _ScriptErrorsFrame.index;
|
||||
if (not index or not _ScriptErrorsFrame.order[index]) then
|
||||
index = getn(_ScriptErrorsFrame.order);
|
||||
_ScriptErrorsFrame.index = index;
|
||||
end
|
||||
|
||||
if (index == 0) then
|
||||
editBox:SetText("");
|
||||
ScriptErrorsFrame_UpdateButtons();
|
||||
return;
|
||||
end
|
||||
|
||||
local text = string.format(
|
||||
ERROR_FORMAT,
|
||||
_ScriptErrorsFrame.messages[index],
|
||||
_ScriptErrorsFrame.times[index],
|
||||
_ScriptErrorsFrame.count[index],
|
||||
_ScriptErrorsFrame.order[index]
|
||||
);
|
||||
|
||||
local parent = editBox:GetParent();
|
||||
local prevText = editBox.text;
|
||||
editBox.text = text;
|
||||
if (prevText ~= text) then
|
||||
editBox:SetText(text);
|
||||
editBox:HighlightText(0);
|
||||
--editBox:SetCursorPosition(0);
|
||||
else
|
||||
ScriptErrorsFrameScrollFrame:UpdateScrollChildRect();
|
||||
end
|
||||
parent:SetVerticalScroll(0);
|
||||
|
||||
ScriptErrorsFrame_UpdateButtons();
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_UpdateButtons ()
|
||||
local index = _ScriptErrorsFrame.index;
|
||||
local numErrors = getn(_ScriptErrorsFrame.order);
|
||||
if (index == 0) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
else
|
||||
if (numErrors == 1) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
elseif (index == 1) then
|
||||
_ScriptErrorsFrame.next:Enable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
elseif (index == numErrors) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Enable();
|
||||
else
|
||||
_ScriptErrorsFrame.next:Enable();
|
||||
_ScriptErrorsFrame.previous:Enable();
|
||||
end
|
||||
end
|
||||
|
||||
_ScriptErrorsFrame.indexLabel:SetText(string.format(INDEX_ORDER_FORMAT, index, numErrors));
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_DeleteError (index)
|
||||
if (_ScriptErrorsFrame.order[index]) then
|
||||
_ScriptErrorsFrame.seen[_ScriptErrorsFrame.messages[index] .. _ScriptErrorsFrame.order[index]] = nil;
|
||||
tremove(_ScriptErrorsFrame.order, index);
|
||||
tremove(_ScriptErrorsFrame.messages, index);
|
||||
tremove(_ScriptErrorsFrame.times, index);
|
||||
tremove(_ScriptErrorsFrame.count, index);
|
||||
end
|
||||
end
|
||||
|
||||
function ScriptErrorsFrameButton_OnClick (self)
|
||||
local id = self:GetID();
|
||||
|
||||
if (id == 1) then
|
||||
_ScriptErrorsFrame.index = _ScriptErrorsFrame.index + 1;
|
||||
else
|
||||
_ScriptErrorsFrame.index = _ScriptErrorsFrame.index - 1;
|
||||
end
|
||||
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
|
||||
function DebugTooltip_OnLoad(self)
|
||||
self:SetFrameLevel(self:GetFrameLevel() + 2)
|
||||
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
|
||||
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
|
||||
self.statusBar2 = getglobal(self:GetName().."StatusBar2")
|
||||
self.statusBar2Text = getglobal(self:GetName().."StatusBar2Text")
|
||||
end
|
||||
|
||||
function FrameStackTooltip_OnDisplaySizeChanged(self)
|
||||
local height = GetScreenHeight()
|
||||
if (height > 768) then
|
||||
self:SetScale(768 / height)
|
||||
else
|
||||
self:SetScale(1)
|
||||
end
|
||||
end
|
||||
|
||||
function FrameStackTooltip_OnLoad(self)
|
||||
DebugTooltip_OnLoad(self)
|
||||
|
||||
FrameStackTooltip_OnDisplaySizeChanged(self)
|
||||
self:RegisterEvent("DISPLAY_SIZE_CHANGED")
|
||||
end
|
||||
|
||||
function FrameStackTooltip_OnEvent(self, event, ...)
|
||||
if (event == "DISPLAY_SIZE_CHANGED") then
|
||||
FrameStackTooltip_OnDisplaySizeChanged(self)
|
||||
end
|
||||
end
|
||||
|
||||
function FrameStackTooltip_Toggle(showHidden)
|
||||
local tooltip = _G["FrameStackTooltip"]
|
||||
if (tooltip:IsVisible()) then
|
||||
tooltip:Hide()
|
||||
FrameStackHighlight:Hide()
|
||||
else
|
||||
tooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
tooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -CONTAINER_OFFSET_X - 13, CONTAINER_OFFSET_Y)
|
||||
tooltip.default = 1
|
||||
tooltip.showHidden = showHidden
|
||||
UpdateFrameStack(tooltip, showHidden)
|
||||
end
|
||||
end
|
||||
|
||||
FRAMESTACK_UPDATE_TIME = .1
|
||||
local _timeSinceLast = 0
|
||||
function FrameStackTooltip_OnUpdate(self, elapsed)
|
||||
_timeSinceLast = _timeSinceLast - elapsed
|
||||
if (_timeSinceLast <= 0) then
|
||||
_timeSinceLast = FRAMESTACK_UPDATE_TIME
|
||||
local highlightFrame = UpdateFrameStack(self, self.showHidden)
|
||||
|
||||
FrameStackHighlight:ClearAllPoints();
|
||||
if (highlightFrame) then
|
||||
FrameStackHighlight:SetPoint("BOTTOMLEFT", highlightFrame);
|
||||
FrameStackHighlight:SetPoint("TOPRIGHT", highlightFrame);
|
||||
FrameStackHighlight:Show();
|
||||
else
|
||||
FrameStackHighlight:Hide();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function FrameStackTooltip_OnShow(self)
|
||||
local parent = self:GetParent() or UIParent
|
||||
local ps = parent:GetEffectiveScale()
|
||||
local px, py = parent:GetCenter()
|
||||
px, py = px * ps, py * ps
|
||||
|
||||
local x, y = GetCursorPosition()
|
||||
self:ClearAllPoints()
|
||||
|
||||
if (x > px) then
|
||||
if (y > py) then
|
||||
self:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT", 20, 20)
|
||||
else
|
||||
self:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -20)
|
||||
end
|
||||
else
|
||||
if (y > py) then
|
||||
self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -20, 20)
|
||||
else
|
||||
self:SetPoint("TOPRIGHT", parent, "TOPRIGHT", -20, -20)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
FrameStackTooltip_OnEnter = FrameStackTooltip_OnShow
|
||||
@@ -0,0 +1,568 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Font name="GameFontHighlightSmall" inherits="GameFontNormalSmall" virtual="true">
|
||||
<Color r="1.0" g="1.0" b="1.0"/>
|
||||
</Font>
|
||||
<Font name="GameFontHighlightSmallLeft" inherits="GameFontHighlightSmall" justifyH="LEFT" virtual="true"/>
|
||||
<Font name="GameFontNormalCenter" inherits="GameFontNormal" justifyH="CENTER" virtual="true"/>
|
||||
<FontString name="EventTraceTimeFont" font="fonts\arialn.ttf" justifyH="RIGHT" virtual="true">
|
||||
<FontHeight val="10"/>
|
||||
<Color r="1" g="1" b="1" a="1"/>
|
||||
</FontString>
|
||||
|
||||
<Button name="EventTraceEventTemplate" virtual="true">
|
||||
<Size x="0" y="16"/>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentTime" inherits="EventTraceTimeFont">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
<Anchor point="TOPRIGHT" relativePoint="TOPLEFT">
|
||||
<Offset x="72" y="0"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOM"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString name="$parentEvent" inherits="GameFontHighlightSmallLeft">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="80" y="0"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOM"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentHideButton" hidden="true">
|
||||
<Size x="16" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
EventTraceFrameEventHideButton_OnClick(this);
|
||||
</OnClick>
|
||||
<OnLeave>
|
||||
EventTraceFrameEvent_OnLeave(this:GetParent());
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
<ButtonText text="X" inherits="GameFontRedSmall">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT"/>
|
||||
</Anchors>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
local frameName = this:GetName();
|
||||
this.time = getglobal(frameName.."Time");
|
||||
this.event = getglobal(frameName.."Event");
|
||||
this.HideButton = getglobal(frameName.."HideButton");
|
||||
this:GetHighlightTexture():SetAlpha(.15);
|
||||
</OnLoad>
|
||||
<OnEnter>
|
||||
EventTraceFrameEvent_OnEnter(this);
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
EventTraceFrameEvent_OnLeave(this);
|
||||
</OnLeave>
|
||||
<OnClick>
|
||||
EventTraceFrameEvent_OnClick(this);
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
<HighlightTexture setAllPoints="true" alphaMode="ADD">
|
||||
<Color r=".8" g=".8" b="1" a="1"/>
|
||||
</HighlightTexture>
|
||||
</Button>
|
||||
|
||||
<Frame name="UIPanelDialogTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentTopLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.501953125" right="0.625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTopRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.625" right="0.75" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTop" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.25" right="0.369140625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.751953125" right="0.875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.875" right="1" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottom" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.376953125" right="0.498046875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.001953125" right="0.125" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.1171875" right="0.2421875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentTitleBG" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Title-Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="8" y="-7"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
|
||||
<Offset x="-8" y="-24"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentDialogBG" file="Interface\PaperDollInfoFrame\UI-Character-CharacterTab-L1">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="8" y="-24"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-6" y="8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0.255" right="1" top="0.29" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parentTitle" inherits="GameFontNormal">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="12" y="-8"/>
|
||||
</Anchor>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="-32" y="-24"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentClose" inherits="UIPanelCloseButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="2" y="1"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Button>
|
||||
</Frames>
|
||||
</Frame>
|
||||
|
||||
<Frame name="EventTraceFrame" parent="UIParent" movable="true" enableMouse="true" clampedToScreen="true" hidden="true" frameStrata="MEDIUM" toplevel="true">
|
||||
<Size x="326" y="505"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="64" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentTitleBG" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Title-Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="9" y="-6"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
|
||||
<Offset x="-28" y="-24"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentDialogBG" file="Interface\Tooltips\UI-Tooltip-Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="8" y="-24"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-6" y="8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Color r="0" g="0" b="0" a=".75"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentTopLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.501953125" right="0.625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTopRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.625" right="0.75" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTop" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.25" right="0.369140625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.751953125" right="0.875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.875" right="1" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottom" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.376953125" right="0.498046875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentLeft" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.001953125" right="0.125" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentRight" file="Interface\AddOns\!DebugTools\media\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.1171875" right="0.2421875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parentTitle" inherits="GameFontNormal" text="EVENTS_LABEL">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="12" y="-8"/>
|
||||
</Anchor>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="-32" y="-8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentCloseButton" inherits="UIPanelCloseButton">
|
||||
<Size>
|
||||
<AbsDimension x="32" y="32"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="2" y="1"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Button>
|
||||
<Frame name="$parentTitleButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTitleBG"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentTitleBG"/>
|
||||
</Anchors>
|
||||
<Frames>
|
||||
<Frame name="$parentHighlight" setAllPoints="true" hidden="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture file="Interface\Buttons\UI-ListBox-Highlight" setAllPoints="true">
|
||||
<Color r="1" g="1" b="1" a="0.4"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:RegisterForDrag("LeftButton");
|
||||
</OnLoad>
|
||||
<OnDragStart>
|
||||
local eventTraceFrame = getglobal("EventTraceFrame");
|
||||
eventTraceFrame.moving = true;
|
||||
eventTraceFrame:StartMoving();
|
||||
</OnDragStart>
|
||||
<OnDragStop>
|
||||
local eventTraceFrame = getglobal("EventTraceFrame");
|
||||
eventTraceFrame.moving = nil;
|
||||
eventTraceFrame:StopMovingOrSizing();
|
||||
</OnDragStop>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Slider name="$parentScroll">
|
||||
<Size x="16" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="-7" y="-28"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-7" y="10"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBG" setAllPoints="true">
|
||||
<Color r=".8" g=".8" b="1" a="0.1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetFrameLevel(this:GetFrameLevel() + 1);
|
||||
this:SetValue(0);
|
||||
this:SetValueStep(1);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
<ThumbTexture name="$parentThumb" file="Interface\Buttons\UI-ScrollBar-Knob">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.25" right="0.75" top="0.25" bottom="0.75"/>
|
||||
</ThumbTexture>
|
||||
</Slider>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
EventTraceFrame_OnLoad(this);
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
EventTraceFrame_OnShow(this);
|
||||
</OnShow>
|
||||
<OnEvent>
|
||||
EventTraceFrame_OnEvent(this, unpack(arg));
|
||||
</OnEvent>
|
||||
<OnUpdate>
|
||||
EventTraceFrame_OnUpdate(this, arg1);
|
||||
</OnUpdate>
|
||||
<OnKeyUp>
|
||||
EventTraceFrame_OnKeyUp(this, arg1);
|
||||
</OnKeyUp>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<Frame name="ScriptErrorsFrame" inherits="UIPanelDialogTemplate" frameStrata="TOOLTIP" movable="true" enableMouse="true" clampedToScreen="true" hidden="true" toplevel="true">
|
||||
<Size x="384" y="260"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parentIndexLabel" font="GameFontNormalCenter">
|
||||
<Size x="70" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM">
|
||||
<Offset x="0" y="16"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="$parentTitleButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTitleBG"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentTitleBG"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:RegisterForDrag("LeftButton");
|
||||
</OnLoad>
|
||||
<OnDragStart>
|
||||
local frame = getglobal("ScriptErrorsFrame");
|
||||
frame.moving = true;
|
||||
frame:StartMoving();
|
||||
</OnDragStart>
|
||||
<OnDragStop>
|
||||
local frame = getglobal("ScriptErrorsFrame");
|
||||
frame.moving = nil;
|
||||
frame:StopMovingOrSizing();
|
||||
</OnDragStop>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<ScrollFrame name="$parentScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||||
<Size x="343" y="194"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="12" y="-30"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<ScrollChild>
|
||||
<EditBox name="$parentText" multiLine="true" letters="4000" autoFocus="false">
|
||||
<Size x="343" y="194"/>
|
||||
<Scripts>
|
||||
<OnCursorChanged>
|
||||
ScrollingEdit_OnCursorChanged(this);
|
||||
</OnCursorChanged>
|
||||
<OnUpdate>
|
||||
ScrollingEdit_OnUpdate(this, arg1, this:GetParent());
|
||||
</OnUpdate>
|
||||
<OnEditFocusGained>
|
||||
this:HighlightText(0);
|
||||
</OnEditFocusGained>
|
||||
<OnEscapePressed>
|
||||
this:ClearFocus();
|
||||
</OnEscapePressed>
|
||||
</Scripts>
|
||||
<FontString inherits="GameFontHighlightSmall"/>
|
||||
</EditBox>
|
||||
</ScrollChild>
|
||||
</ScrollFrame>
|
||||
<Button name="$parentReload" inherits="UIPanelButtonTemplate" text="RELOADUI">
|
||||
<Size x="96" y="24"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parent">
|
||||
<Offset x="10" y="12" />
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
ReloadUI();
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentPrevious" id="2">
|
||||
<Size x="32" y="32"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM">
|
||||
<Offset x="-50" y="8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
|
||||
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Up"/>
|
||||
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Down"/>
|
||||
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled"/>
|
||||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||||
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
ScriptErrorsFrameButton_OnClick(this);
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentNext" id="1">
|
||||
<Size x="32" y="32" />
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM">
|
||||
<Offset x="50" y="8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
|
||||
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Up"/>
|
||||
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Down"/>
|
||||
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled"/>
|
||||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||||
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
ScriptErrorsFrameButton_OnClick(this);
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentCloseButton" inherits="UIPanelButtonTemplate" text="CLOSE">
|
||||
<Size x="96" y="24"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-8" y="12"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
HideUIPanel(this:GetParent());
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
ScriptErrorsFrame_OnLoad(this);
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
ScriptErrorsFrame_OnShow(this);
|
||||
</OnShow>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<GameTooltip name="FrameStackTooltip" frameStrata="TOOLTIP" hidden="true" inherits="GameTooltipTemplate">
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
FrameStackTooltip_OnLoad(this);
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
FrameStackTooltip_OnShow(this);
|
||||
</OnShow>
|
||||
<OnEnter>
|
||||
FrameStackTooltip_OnEnter(this);
|
||||
</OnEnter>
|
||||
<OnUpdate>
|
||||
FrameStackTooltip_OnUpdate(this, arg1);
|
||||
</OnUpdate>
|
||||
<OnEvent>
|
||||
FrameStackTooltip_OnEvent(this, unpack(arg));
|
||||
</OnEvent>
|
||||
</Scripts>
|
||||
</GameTooltip>
|
||||
|
||||
<GameTooltip name="EventTraceTooltip" frameStrata="TOOLTIP" hidden="true" parent="EventTraceFrame" inherits="GameTooltipTemplate">
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
DebugTooltip_OnLoad(this)
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</GameTooltip>
|
||||
|
||||
<Frame name="FrameStackHighlight" frameStrata="TOOLTIP">
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentTexture">
|
||||
<Color r="0.0" g="0.8" b="0.0" a=".4"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,197 @@
|
||||
--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 pairs = pairs
|
||||
local tostring = tostring
|
||||
--WoW API
|
||||
local GetTime = GetTime
|
||||
|
||||
DEBUG_FRAMESTACK = "Frame Stack"
|
||||
EVENTS_LABEL = "Events"
|
||||
RELOADUI = "Reload UI"
|
||||
|
||||
local eventList = {}
|
||||
|
||||
local function EventHandler_OnEvent()
|
||||
tinsert(eventList, GetTime())
|
||||
end
|
||||
|
||||
local eventHandler = CreateFrame("Frame", "EventHandler", UIParent)
|
||||
eventHandler:SetScript("OnEvent", EventHandler_OnEvent)
|
||||
|
||||
function GetCurrentEventID()
|
||||
return getn(eventList)
|
||||
end
|
||||
|
||||
function GetEventTime(eventID)
|
||||
return eventList[eventID]
|
||||
end
|
||||
|
||||
function EventHandler_Enable()
|
||||
eventHandler:RegisterAllEvents()
|
||||
end
|
||||
|
||||
function EventHandler_Disable()
|
||||
eventHandler:UnregisterAllEvents()
|
||||
twipe(eventList)
|
||||
end
|
||||
|
||||
local strataLevels = {
|
||||
["UNKNOWN"] = 1,
|
||||
["BACKGROUND"] = 2,
|
||||
["LOW"] = 3,
|
||||
["MEDIUM"] = 4,
|
||||
["HIGH"] = 5,
|
||||
["DIALOG"] = 6,
|
||||
["FULLSCREEN"] = 7,
|
||||
["FULLSCREEN_DIALOG"] = 8,
|
||||
["TOOLTIP"] = 9,
|
||||
}
|
||||
|
||||
local colorSpecs = {
|
||||
"|cff6699ff",
|
||||
"|cff88dddd"
|
||||
}
|
||||
|
||||
local activeColorSpecs = {
|
||||
"|cffff9966",
|
||||
"|cffdddd88"
|
||||
}
|
||||
|
||||
local hiddenColorSpecs = {
|
||||
"|cff666666",
|
||||
"|cff888888"
|
||||
}
|
||||
|
||||
local frameStackStrata = {}
|
||||
local frameStackLevels = {}
|
||||
local frameStackActive = {}
|
||||
local frameStackList = {}
|
||||
|
||||
local function FrameStackSort(b, a)
|
||||
local sa = strataLevels[frameStackStrata[a]] or -1
|
||||
local sb = strataLevels[frameStackStrata[b]] or -1
|
||||
if sa < sb then
|
||||
return true
|
||||
elseif sa > sb then
|
||||
return
|
||||
end
|
||||
|
||||
local sa = frameStackLevels[a] or -1
|
||||
local sb = frameStackLevels[b] or -1
|
||||
if sa < sb then
|
||||
return true
|
||||
elseif sa > sb then
|
||||
return
|
||||
end
|
||||
|
||||
return a < b
|
||||
end
|
||||
|
||||
function UpdateFrameStack(tooltip, showHidden)
|
||||
local x, y = GetCursorPosition()
|
||||
|
||||
for i = 1, getn(frameStackList) do
|
||||
frameStackList[i] = nil
|
||||
end
|
||||
|
||||
for k in pairs(frameStackLevels) do
|
||||
frameStackLevels[k] = nil
|
||||
frameStackStrata[k] = nil
|
||||
frameStackActive[k] = nil
|
||||
end
|
||||
|
||||
local f
|
||||
local nf = EnumerateFrames()
|
||||
|
||||
while nf do
|
||||
f, nf = nf, EnumerateFrames(nf)
|
||||
local es = f:GetEffectiveScale() or 1
|
||||
|
||||
local Fl, Fb, Fr, Ft = f:GetLeft(), f:GetBottom(), f:GetRight(), f:GetTop()
|
||||
Fl = Fl or -1
|
||||
Fb = Fb or -1
|
||||
Fr = Fl + (Fr or -1)
|
||||
Ft = Fb + (Ft or -1)
|
||||
|
||||
if (x >= Fl * es) and (x <= Fr * es) and (y >= Fb * es) and (y <= Ft * es) then
|
||||
local n = f:GetName()
|
||||
if n and _G[n] == f then
|
||||
-- Name is ok
|
||||
elseif n then
|
||||
n = tostring(f) .. " (" .. n .. ")"
|
||||
else
|
||||
n = tostring(f)
|
||||
end
|
||||
|
||||
local s = f:GetFrameStrata() or "nil"
|
||||
local l = f:GetFrameLevel() or -1
|
||||
local a
|
||||
|
||||
if f:IsVisible() then
|
||||
if f:IsMouseEnabled() then
|
||||
a = activeColorSpecs
|
||||
else
|
||||
a = colorSpecs
|
||||
end
|
||||
elseif showHidden then
|
||||
a = hiddenColorSpecs
|
||||
else
|
||||
a = nil
|
||||
end
|
||||
|
||||
if a then
|
||||
frameStackLevels[n] = l
|
||||
frameStackStrata[n] = s
|
||||
frameStackActive[n] = a
|
||||
|
||||
tinsert(frameStackList, n)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
frameStackList[getn(frameStackList) + 1] = nil
|
||||
|
||||
--tsort(frameStackList, FrameStackSort)
|
||||
|
||||
tooltip:ClearLines()
|
||||
tooltip:AddDoubleLine(DEBUG_FRAMESTACK, format("(%.2f,%.2f)", x, y), 1, 1, 1, 1, .82, 0)
|
||||
|
||||
local cs, os, ol = 1, nil, nil
|
||||
local cn = getn(colorSpecs)
|
||||
local highlighted
|
||||
local highlightFrame = GetMouseFocus()
|
||||
|
||||
for _, n in ipairs(frameStackList) do
|
||||
local s, l, a = frameStackStrata[n], frameStackLevels[n], frameStackActive[n]
|
||||
if os ~= s then
|
||||
tooltip:AddLine(s, 1, 1, 1)
|
||||
os = s
|
||||
ol = nil
|
||||
cs = 1
|
||||
end
|
||||
|
||||
if l ~= ol then
|
||||
cs = mod(cs, cn) + 1 or 0
|
||||
ol = l
|
||||
end
|
||||
|
||||
if not highlighted then
|
||||
local frameName = _G[n] --[[or match(n, "%((.+)%)$")]] or n
|
||||
if frameName and frameName == highlightFrame then
|
||||
tooltip:AddLine("-->" .. (a[cs] or "|cff444444") .. "<" .. l .. "> " .. n .. "|r")
|
||||
highlighted = true
|
||||
else
|
||||
tooltip:AddLine(" " .. (a[cs] or "|cff444444") .. "<" .. l .. "> " .. n .. "|r")
|
||||
end
|
||||
else
|
||||
tooltip:AddLine(" " .. (a[cs] or "|cff444444") .. "<" .. l .. "> " .. n .. "|r")
|
||||
end
|
||||
end
|
||||
|
||||
tooltip:Show()
|
||||
|
||||
return highlightFrame
|
||||
end
|
||||
@@ -0,0 +1,387 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Dump.lua
|
||||
--
|
||||
-- Contributed by Iriel, Esamynn and Kirov from DevTools v1.11
|
||||
-- /dump Implementation
|
||||
--
|
||||
-- Globals: DevTools, SLASH_DEVTOOLSDUMP1, DevTools_Dump, DevTools_RunDump
|
||||
-- Globals: DEVTOOLS_MAX_ENTRY_CUTOFF, DEVTOOLS_LONG_STRING_CUTOFF
|
||||
-- Globals: DEVTOOLS_DEPTH_CUTOFF, DEVTOOLS_INDENT
|
||||
-- Globals: DEVTOOLS_USE_TABLE_CACHE, DEVTOOLS_USE_FUNCTION_CACHE
|
||||
-- Globals: DEVTOOLS_USE_USERDATA_CACHE
|
||||
---------------------------------------------------------------------------
|
||||
local DT = {};
|
||||
|
||||
DEVTOOLS_MAX_ENTRY_CUTOFF = 30; -- Maximum table entries shown
|
||||
DEVTOOLS_LONG_STRING_CUTOFF = 200; -- Maximum string size shown
|
||||
DEVTOOLS_DEPTH_CUTOFF = 10; -- Maximum table depth
|
||||
DEVTOOLS_USE_TABLE_CACHE = true; -- Look up table names
|
||||
DEVTOOLS_USE_FUNCTION_CACHE = true; -- Look up function names
|
||||
DEVTOOLS_USE_USERDATA_CACHE = true; -- Look up userdata names
|
||||
DEVTOOLS_INDENT=' '; -- Indentation string
|
||||
|
||||
local DEVTOOLS_TYPE_COLOR="|cff88ff88";
|
||||
local DEVTOOLS_TABLEREF_COLOR="|cffffcc00";
|
||||
local DEVTOOLS_CUTOFF_COLOR="|cffff0000";
|
||||
local DEVTOOLS_TABLEKEY_COLOR="|cff88ccff";
|
||||
|
||||
local FORMATS = {};
|
||||
-- prefix type suffix
|
||||
FORMATS["opaqueTypeVal"] = "%s" .. DEVTOOLS_TYPE_COLOR .. "<%s>|r%s";
|
||||
-- prefix type name suffix
|
||||
FORMATS["opaqueTypeValName"] = "%s" .. DEVTOOLS_TYPE_COLOR .. "<%s %s>|r%s";
|
||||
-- type
|
||||
FORMATS["opaqueTypeKey"] = "<%s>";
|
||||
-- type name
|
||||
FORMATS["opaqueTypeKeyName"] = "<%s %s>";
|
||||
-- value
|
||||
FORMATS["bracketTableKey"] = "[%s]";
|
||||
-- prefix value
|
||||
FORMATS["tableKeyAssignPrefix"] = DEVTOOLS_TABLEKEY_COLOR .. "%s%s|r=";
|
||||
-- prefix cutoff
|
||||
FORMATS["tableEntriesSkipped"] = "%s" .. DEVTOOLS_CUTOFF_COLOR .. "<skipped %s>|r";
|
||||
-- prefix suffix
|
||||
FORMATS["tableTooDeep"] = "%s" .. DEVTOOLS_CUTOFF_COLOR .. "<table (too deep)>|r%s";
|
||||
-- prefix value suffix
|
||||
FORMATS["simpleValue"] = "%s%s%s";
|
||||
-- prefix tablename suffix
|
||||
FORMATS["tableReference"] = "%s" .. DEVTOOLS_TABLEREF_COLOR .. "%s|r%s";
|
||||
|
||||
-- Grab a copy various oft-used functions
|
||||
local rawget = rawget;
|
||||
local type = type;
|
||||
local string_len = string.len;
|
||||
local string_sub = string.sub;
|
||||
local string_gsub = string.gsub;
|
||||
local string_format = string.format;
|
||||
local string_match = string.match;
|
||||
|
||||
local function WriteMessage(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(msg);
|
||||
end
|
||||
|
||||
local function prepSimple(val, context)
|
||||
local valType = type(val);
|
||||
if (valType == "nil") then
|
||||
return "nil";
|
||||
elseif (valType == "number") then
|
||||
return val;
|
||||
elseif (valType == "boolean") then
|
||||
if (val) then
|
||||
return "true";
|
||||
else
|
||||
return "false";
|
||||
end
|
||||
elseif (valType == "string") then
|
||||
local l = string_len(val);
|
||||
if ((l > DEVTOOLS_LONG_STRING_CUTOFF) and
|
||||
(DEVTOOLS_LONG_STRING_CUTOFF > 0)) then
|
||||
local more = l - DEVTOOLS_LONG_STRING_CUTOFF;
|
||||
val = string_sub(val, 1, DEVTOOLS_LONG_STRING_CUTOFF);
|
||||
return string_gsub(string_format("%q...+%s",val,more),"[|]", "||");
|
||||
else
|
||||
return string_gsub(string_format("%q",val),"[|]", "||");
|
||||
end
|
||||
elseif (valType == "function") then
|
||||
local fName = context:GetFunctionName(val);
|
||||
if (fName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, fName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
elseif (valType == "userdata") then
|
||||
local uName = context:GetUserdataName(val);
|
||||
if (uName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, uName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
elseif (valType == 'table') then
|
||||
local tName = context:GetTableName(val);
|
||||
if (tName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, tName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
end
|
||||
error("Bad type '" .. valType .. "' to prepSimple");
|
||||
end
|
||||
|
||||
local function prepSimpleKey(val, context)
|
||||
local valType = type(val);
|
||||
if (valType == "string") then
|
||||
local l = string_len(val);
|
||||
if ((l <= DEVTOOLS_LONG_STRING_CUTOFF) or
|
||||
(DEVTOOLS_LONG_STRING_CUTOFF <= 0)) then
|
||||
if (string_match(val, "^[a-zA-Z_][a-zA-Z0-9_]*$")) then
|
||||
return val;
|
||||
end
|
||||
end
|
||||
end
|
||||
return string_format(FORMATS.bracketTableKey, prepSimple(val, context));
|
||||
end
|
||||
|
||||
local function DevTools_InitFunctionCache(context)
|
||||
local ret = {};
|
||||
|
||||
for _,k in ipairs(DT.functionSymbols) do
|
||||
local v = getglobal(k);
|
||||
if (type(v) == 'function') then
|
||||
ret[v] = '[' .. k .. ']';
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'function') then
|
||||
if (not ret[v]) then
|
||||
ret[v] = '[' .. k .. ']';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret;
|
||||
end
|
||||
|
||||
local function DevTools_InitUserdataCache(context)
|
||||
local ret = {};
|
||||
|
||||
for _,k in ipairs(DT.userdataSymbols) do
|
||||
local v = getglobal(k);
|
||||
if (type(v) == 'table') then
|
||||
local u = rawget(v,0);
|
||||
if (type(u) == 'userdata') then
|
||||
ret[u] = k .. '[0]';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'table') then
|
||||
local u = rawget(v, 0);
|
||||
if (type(u) == 'userdata') then
|
||||
if (not ret[u]) then
|
||||
ret[u] = k .. '[0]';
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Nil(self, value, newName)
|
||||
return nil;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Function(self, value, newName)
|
||||
if (not self.fCache) then
|
||||
self.fCache = DevTools_InitFunctionCache(self);
|
||||
end
|
||||
local name = self.fCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.fCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Userdata(self, value, newName)
|
||||
if (not self.uCache) then
|
||||
self.uCache = DevTools_InitUserdataCache(self);
|
||||
end
|
||||
local name = self.uCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.uCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Table(self, value, newName)
|
||||
if (not self.tCache) then
|
||||
self.tCache = {};
|
||||
end
|
||||
local name = self.tCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.tCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Write(self, msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(msg);
|
||||
end
|
||||
|
||||
local DevTools_DumpValue;
|
||||
|
||||
local function DevTools_DumpTableContents(val, prefix, firstPrefix, context)
|
||||
local showCount = 0;
|
||||
local oldDepth = context.depth;
|
||||
local oldKey = context.key;
|
||||
|
||||
-- Use this to set the cache name
|
||||
context:GetTableName(val, oldKey or 'value');
|
||||
|
||||
local iter = pairs(val);
|
||||
local nextK, nextV = iter(val, nil);
|
||||
|
||||
while (nextK) do
|
||||
local k,v = nextK, nextV;
|
||||
nextK, nextV = iter(val, k);
|
||||
|
||||
showCount = showCount + 1;
|
||||
if ((showCount <= DEVTOOLS_MAX_ENTRY_CUTOFF) or (DEVTOOLS_MAX_ENTRY_CUTOFF <= 0)) then
|
||||
local prepKey = prepSimpleKey(k, context);
|
||||
if (oldKey == nil) then
|
||||
context.key = prepKey;
|
||||
elseif (string_sub(prepKey, 1, 1) == "[") then
|
||||
context.key = oldKey .. prepKey
|
||||
else
|
||||
context.key = oldKey .. "." .. prepKey
|
||||
end
|
||||
context.depth = oldDepth + 1;
|
||||
|
||||
local rp = string_format(FORMATS.tableKeyAssignPrefix, firstPrefix, prepKey);
|
||||
firstPrefix = prefix;
|
||||
DevTools_DumpValue(v, prefix, rp, (nextK and ",") or '', context);
|
||||
end
|
||||
end
|
||||
local cutoff = showCount - DEVTOOLS_MAX_ENTRY_CUTOFF;
|
||||
if ((cutoff > 0) and (DEVTOOLS_MAX_ENTRY_CUTOFF > 0)) then
|
||||
context:Write(string_format(FORMATS.tableEntriesSkipped,firstPrefix, cutoff));
|
||||
end
|
||||
context.key = oldKey;
|
||||
context.depth = oldDepth;
|
||||
return (showCount > 0)
|
||||
end
|
||||
|
||||
-- Return the specified value
|
||||
function DevTools_DumpValue(val, prefix, firstPrefix, suffix, context)
|
||||
local valType = type(val);
|
||||
|
||||
if (valType == "userdata") then
|
||||
local uName = context:GetUserdataName(val, 'value');
|
||||
if (uName) then
|
||||
context:Write(string_format(FORMATS.opaqueTypeValName, firstPrefix, valType, uName, suffix));
|
||||
else
|
||||
context:Write(string_format(FORMATS.opaqueTypeVal, firstPrefix, valType, suffix));
|
||||
end
|
||||
return;
|
||||
elseif (valType == "function") then
|
||||
local fName = context:GetFunctionName(val, 'value');
|
||||
if (fName) then
|
||||
context:Write(string_format(FORMATS.opaqueTypeValName, firstPrefix, valType, fName, suffix));
|
||||
else
|
||||
context:Write(string_format(FORMATS.opaqueTypeVal, firstPrefix, valType, suffix));
|
||||
end
|
||||
return;
|
||||
elseif (valType ~= "table") then
|
||||
context:Write(string_format(FORMATS.simpleValue, firstPrefix,prepSimple(val, context), suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
local cacheName = context:GetTableName(val);
|
||||
if (cacheName) then
|
||||
context:Write(string_format(FORMATS.tableReference, firstPrefix, cacheName, suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
if ((context.depth >= DEVTOOLS_DEPTH_CUTOFF) and (DEVTOOLS_DEPTH_CUTOFF > 0)) then
|
||||
context:Write(string_format(FORMATS.tableTooDeep, firstPrefix, suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
firstPrefix = firstPrefix .. "{";
|
||||
local oldPrefix = prefix;
|
||||
prefix = prefix .. DEVTOOLS_INDENT;
|
||||
|
||||
context:Write(firstPrefix);
|
||||
firstPrefix = prefix;
|
||||
local anyContents = DevTools_DumpTableContents(val, prefix, firstPrefix, context);
|
||||
context:Write(oldPrefix .. "}" .. suffix);
|
||||
end
|
||||
|
||||
local function Pick_Cache_Function(func, setting)
|
||||
if (setting) then
|
||||
return func;
|
||||
else
|
||||
return DevTools_Cache_Nil;
|
||||
end
|
||||
end
|
||||
|
||||
function DevTools_RunDump(value, context)
|
||||
local prefix = "";
|
||||
local firstPrefix = prefix;
|
||||
|
||||
local valType = type(value);
|
||||
if (type(value) == 'table') then
|
||||
local any =
|
||||
DevTools_DumpTableContents(value, prefix, firstPrefix, context);
|
||||
if (context.Result) then
|
||||
return context:Result();
|
||||
end
|
||||
if (not any) then
|
||||
context:Write("empty result");
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
DevTools_DumpValue(value, '', '', '', context);
|
||||
if (context.Result) then
|
||||
return context:Result();
|
||||
end
|
||||
end
|
||||
|
||||
-- Dump the specified list of value
|
||||
function DevTools_Dump(value, startKey)
|
||||
local context = {
|
||||
depth = 0,
|
||||
key = startKey,
|
||||
};
|
||||
|
||||
context.GetTableName = Pick_Cache_Function(DevTools_Cache_Table, DEVTOOLS_USE_TABLE_CACHE);
|
||||
context.GetFunctionName = Pick_Cache_Function(DevTools_Cache_Function, DEVTOOLS_USE_FUNCTION_CACHE);
|
||||
context.GetUserdataName = Pick_Cache_Function(DevTools_Cache_Userdata, DEVTOOLS_USE_USERDATA_CACHE);
|
||||
context.Write = DevTools_Write;
|
||||
|
||||
DevTools_RunDump(value, context);
|
||||
end
|
||||
|
||||
function DevTools_DumpCommand(msg, editBox)
|
||||
if (string_match(msg,"^[A-Za-z_][A-Za-z0-9_]*$")) then
|
||||
WriteMessage("Dump: " .. msg);
|
||||
local val = _G[msg];
|
||||
local tmp = {};
|
||||
if (val == nil) then
|
||||
local key = string_format(FORMATS.tableKeyAssignPrefix, '', prepSimpleKey(msg, {}));
|
||||
WriteMessage(key .. "nil,");
|
||||
else
|
||||
tmp[msg] = val;
|
||||
end
|
||||
DevTools_Dump(tmp);
|
||||
return;
|
||||
end
|
||||
|
||||
WriteMessage("Dump: value=" .. msg);
|
||||
local func,err = loadstring("return " .. msg);
|
||||
if (not func) then
|
||||
WriteMessage("Dump: ERROR: " .. err);
|
||||
else
|
||||
DevTools_Dump({func()}, "value");
|
||||
end
|
||||
end
|
||||
|
||||
DT.functionSymbols = {};
|
||||
DT.userdataSymbols = {};
|
||||
|
||||
local funcSyms = DT.functionSymbols;
|
||||
local userSyms = DT.userdataSymbols;
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'function') then
|
||||
table.insert(funcSyms, k);
|
||||
elseif (type(v) == 'table') then
|
||||
if (type(rawget(v,0)) == 'userdata') then
|
||||
table.insert(userSyms, k);
|
||||
end
|
||||
end
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
<Bindings>
|
||||
<Binding name="Raid Marker" runOnUp="true" header="ELVUI">
|
||||
RaidMark_HotkeyPressed(keystate);
|
||||
</Binding>
|
||||
<Binding name="Farm Mode" runOnUp="false">
|
||||
FarmMode();
|
||||
</Binding>
|
||||
<Binding name="Toggle Chat (Left)" runOnUp="false">
|
||||
HideLeftChat();
|
||||
</Binding>
|
||||
<Binding name="Toggle Chat (Right)" runOnUp="false">
|
||||
HideRightChat();
|
||||
</Binding>
|
||||
<Binding name="Toggle Chat (Both)" runOnUp="false">
|
||||
HideBothChat();
|
||||
</Binding>
|
||||
</Bindings>
|
||||
@@ -0,0 +1,502 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); -- Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
--Cache global variables
|
||||
--Lua functions
|
||||
local _G = getfenv()
|
||||
local type, ipairs, tonumber = type, ipairs, tonumber
|
||||
local floor = math.floor
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local IsAddOnLoaded = IsAddOnLoaded
|
||||
local GetScreenWidth = GetScreenWidth
|
||||
local GetScreenHeight = GetScreenHeight
|
||||
local RESET = RESET
|
||||
|
||||
local grid
|
||||
local selectedValue = "ALL"
|
||||
|
||||
E.ConfigModeLayouts = {
|
||||
"ALL",
|
||||
"GENERAL",
|
||||
"SOLO",
|
||||
"PARTY",
|
||||
"ARENA",
|
||||
"RAID",
|
||||
"ACTIONBARS"
|
||||
}
|
||||
|
||||
E.ConfigModeLocalizedStrings = {
|
||||
ALL = ALL,
|
||||
GENERAL = GENERAL,
|
||||
SOLO = SOLO,
|
||||
PARTY = PARTY,
|
||||
ARENA = ARENA,
|
||||
RAID = RAID,
|
||||
ACTIONBARS = ACTIONBARS_LABEL
|
||||
}
|
||||
|
||||
function E:Grid_Show()
|
||||
if not grid then
|
||||
E:Grid_Create()
|
||||
elseif grid.boxSize ~= E.db.gridSize then
|
||||
grid:Hide()
|
||||
E:Grid_Create()
|
||||
else
|
||||
grid:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function E:Grid_Hide()
|
||||
if grid then
|
||||
grid:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function E:ToggleConfigMode(override, configType)
|
||||
if override ~= nil and override ~= "" then E.ConfigurationMode = override end
|
||||
|
||||
if E.ConfigurationMode ~= true then
|
||||
if not grid then
|
||||
E:Grid_Create()
|
||||
elseif grid.boxSize ~= E.db.gridSize then
|
||||
grid:Hide()
|
||||
E:Grid_Create()
|
||||
else
|
||||
grid:Show()
|
||||
end
|
||||
|
||||
if not ElvUIMoverPopupWindow then
|
||||
E:CreateMoverPopup()
|
||||
end
|
||||
|
||||
ElvUIMoverPopupWindow:Show()
|
||||
if(IsAddOnLoaded("ElvUI_Config")) then
|
||||
LibStub("AceConfigDialog-3.0"):Close("ElvUI")
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
E.ConfigurationMode = true
|
||||
else
|
||||
if ElvUIMoverPopupWindow then
|
||||
ElvUIMoverPopupWindow:Hide()
|
||||
end
|
||||
|
||||
if grid then
|
||||
grid:Hide()
|
||||
end
|
||||
|
||||
E.ConfigurationMode = false
|
||||
end
|
||||
|
||||
if type(configType) ~= "string" then
|
||||
configType = nil
|
||||
end
|
||||
|
||||
self:ToggleMovers(E.ConfigurationMode, configType or "ALL")
|
||||
end
|
||||
|
||||
function E:Grid_Create()
|
||||
grid = CreateFrame("Frame", "EGrid", UIParent)
|
||||
grid.boxSize = E.db.gridSize
|
||||
grid:SetAllPoints(E.UIParent)
|
||||
grid:Show()
|
||||
|
||||
local size = 1
|
||||
local width = E.eyefinity or GetScreenWidth()
|
||||
local ratio = width / GetScreenHeight()
|
||||
local height = GetScreenHeight() * ratio
|
||||
|
||||
local wStep = width / E.db.gridSize
|
||||
local hStep = height / E.db.gridSize
|
||||
|
||||
for i = 0, E.db.gridSize do
|
||||
local tx = grid:CreateTexture(nil, "BACKGROUND")
|
||||
if i == E.db.gridSize / 2 then
|
||||
tx:SetTexture(1, 0, 0)
|
||||
else
|
||||
tx:SetTexture(0, 0, 0)
|
||||
end
|
||||
tx:SetPoint("TOPLEFT", grid, "TOPLEFT", i*wStep - (size/2), 0)
|
||||
tx:SetPoint("BOTTOMRIGHT", grid, "BOTTOMLEFT", i*wStep + (size/2), 0)
|
||||
end
|
||||
height = GetScreenHeight()
|
||||
|
||||
do
|
||||
local tx = grid:CreateTexture(nil, "BACKGROUND")
|
||||
tx:SetTexture(1, 0, 0)
|
||||
tx:SetPoint("TOPLEFT", grid, "TOPLEFT", 0, -(height/2) + (size/2))
|
||||
tx:SetPoint("BOTTOMRIGHT", grid, "TOPRIGHT", 0, -(height/2 + size/2))
|
||||
end
|
||||
|
||||
for i = 1, floor((height/2)/hStep) do
|
||||
local tx = grid:CreateTexture(nil, "BACKGROUND")
|
||||
tx:SetTexture(0, 0, 0)
|
||||
|
||||
tx:SetPoint("TOPLEFT", grid, "TOPLEFT", 0, -(height/2+i*hStep) + (size/2))
|
||||
tx:SetPoint("BOTTOMRIGHT", grid, "TOPRIGHT", 0, -(height/2+i*hStep + size/2))
|
||||
|
||||
tx = grid:CreateTexture(nil, "BACKGROUND")
|
||||
tx:SetTexture(0, 0, 0)
|
||||
|
||||
tx:SetPoint("TOPLEFT", grid, "TOPLEFT", 0, -(height/2-i*hStep) + (size/2))
|
||||
tx:SetPoint("BOTTOMRIGHT", grid, "TOPRIGHT", 0, -(height/2-i*hStep + size/2))
|
||||
end
|
||||
end
|
||||
|
||||
local function ConfigMode_OnClick(self)
|
||||
selectedValue = self.value
|
||||
E:ToggleConfigMode(false, self.value)
|
||||
-- UIDropDownMenu_SetSelectedValue(ElvUIMoverPopupWindowDropDown, self.value)
|
||||
end
|
||||
|
||||
local function ConfigMode_Initialize()
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.func = ConfigMode_OnClick
|
||||
|
||||
for _, configMode in ipairs(E.ConfigModeLayouts) do
|
||||
info.text = E.ConfigModeLocalizedStrings[configMode]
|
||||
info.value = configMode
|
||||
UIDropDownMenu_AddButton(info)
|
||||
end
|
||||
|
||||
--UIDropDownMenu_SetSelectedValue(ElvUIMoverPopupWindowDropDown, selectedValue)
|
||||
end
|
||||
|
||||
function E:NudgeMover(nudgeX, nudgeY)
|
||||
local mover = ElvUIMoverNudgeWindow.child
|
||||
|
||||
local x, y, point = E:CalculateMoverPoints(mover, nudgeX, nudgeY)
|
||||
|
||||
mover:ClearAllPoints()
|
||||
mover:SetPoint(mover.positionOverride or point, E.UIParent, mover.positionOverride and "BOTTOMLEFT" or point, x, y)
|
||||
E:SaveMoverPosition(mover.name)
|
||||
|
||||
E:UpdateNudgeFrame(mover, x, y)
|
||||
end
|
||||
|
||||
function E:UpdateNudgeFrame(mover, x, y)
|
||||
if not(x and y) then
|
||||
x, y = E:CalculateMoverPoints(mover)
|
||||
end
|
||||
|
||||
x = E:Round(x, 0)
|
||||
y = E:Round(y, 0)
|
||||
|
||||
ElvUIMoverNudgeWindow.xOffset:SetText(x)
|
||||
ElvUIMoverNudgeWindow.yOffset:SetText(y)
|
||||
ElvUIMoverNudgeWindow.xOffset.currentValue = x
|
||||
ElvUIMoverNudgeWindow.yOffset.currentValue = y
|
||||
ElvUIMoverNudgeWindowHeader.title:SetText(mover.textString)
|
||||
end
|
||||
|
||||
function E:AssignFrameToNudge()
|
||||
ElvUIMoverNudgeWindow.child = self
|
||||
E:UpdateNudgeFrame(self)
|
||||
end
|
||||
|
||||
function E:CreateMoverPopup()
|
||||
local f = CreateFrame("Frame", "ElvUIMoverPopupWindow", UIParent)
|
||||
f:SetFrameStrata("DIALOG")
|
||||
f:SetToplevel(true)
|
||||
f:EnableMouse(true)
|
||||
f:SetMovable(true)
|
||||
f:SetFrameLevel(99)
|
||||
f:SetClampedToScreen(true)
|
||||
f:SetWidth(360)
|
||||
f:SetHeight(170)
|
||||
E:SetTemplate(f, "Transparent")
|
||||
f:SetPoint("BOTTOM", UIParent, "CENTER", 0, 100)
|
||||
f:SetScript("OnHide", function()
|
||||
if ElvUIMoverPopupWindowDropDown then
|
||||
UIDropDownMenu_SetSelectedValue(ElvUIMoverPopupWindowDropDown, "ALL")
|
||||
end
|
||||
end)
|
||||
f:Hide()
|
||||
|
||||
local S = E:GetModule("Skins")
|
||||
|
||||
local header = CreateFrame("Button", nil, f)
|
||||
E:SetTemplate(header, "Default", true)
|
||||
header:SetWidth(100) header:SetHeight(25)
|
||||
header:SetPoint("CENTER", f, "TOP")
|
||||
header:SetFrameLevel(header:GetFrameLevel() + 2)
|
||||
header:EnableMouse(true)
|
||||
header:RegisterForClicks("AnyUp", "AnyDown")
|
||||
header:SetScript("OnMouseDown", function() f:StartMoving() end)
|
||||
header:SetScript("OnMouseUp", function() f:StopMovingOrSizing() end)
|
||||
|
||||
local title = header:CreateFontString("OVERLAY")
|
||||
E:FontTemplate(title)
|
||||
title:SetPoint("CENTER", header, "CENTER")
|
||||
title:SetText("ElvUI")
|
||||
|
||||
local desc = f:CreateFontString("ARTWORK")
|
||||
desc:SetFontObject("GameFontHighlight")
|
||||
desc:SetJustifyV("TOP")
|
||||
desc:SetJustifyH("LEFT")
|
||||
desc:SetPoint("TOPLEFT", 18, -32)
|
||||
desc:SetPoint("BOTTOMRIGHT", -18, 48)
|
||||
desc:SetText(L["DESC_MOVERCONFIG"])
|
||||
|
||||
local snapping = CreateFrame("CheckButton", f:GetName().."CheckButton", f, "OptionsCheckButtonTemplate")
|
||||
_G[snapping:GetName() .. "Text"]:SetText(L["Sticky Frames"])
|
||||
|
||||
snapping:SetScript("OnShow", function()
|
||||
this:SetChecked(E.db.general.stickyFrames)
|
||||
end)
|
||||
|
||||
snapping:SetScript("OnClick", function()
|
||||
E.db.general.stickyFrames = this:GetChecked()
|
||||
end)
|
||||
|
||||
local lock = CreateFrame("Button", f:GetName().."CloseButton", f, "OptionsButtonTemplate")
|
||||
_G[lock:GetName() .. "Text"]:SetText(L["Lock"])
|
||||
|
||||
lock:SetScript("OnClick", function()
|
||||
E:ToggleConfigMode(true)
|
||||
|
||||
if(IsAddOnLoaded("ElvUI_Config")) then
|
||||
LibStub("AceConfigDialog-3.0-ElvUI"):Open("ElvUI")
|
||||
end
|
||||
|
||||
selectedValue = "ALL"
|
||||
UIDropDownMenu_SetSelectedValue(ElvUIMoverPopupWindowDropDown, selectedValue)
|
||||
end)
|
||||
|
||||
local align = CreateFrame("EditBox", f:GetName().."EditBox", f, "InputBoxTemplate")
|
||||
align:SetWidth(24)
|
||||
align:SetHeight(17)
|
||||
align:SetAutoFocus(false)
|
||||
align:SetScript("OnEscapePressed", function()
|
||||
this:SetText(E.db.gridSize)
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
align:SetScript("OnEnterPressed", function()
|
||||
local text = this:GetText()
|
||||
if tonumber(text) then
|
||||
if tonumber(text) <= 256 and tonumber(text) >= 4 then
|
||||
E.db.gridSize = tonumber(text)
|
||||
else
|
||||
this:SetText(E.db.gridSize)
|
||||
end
|
||||
else
|
||||
this:SetText(E.db.gridSize)
|
||||
end
|
||||
E:Grid_Show()
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
align:SetScript("OnEditFocusLost", function()
|
||||
this:SetText(E.db.gridSize)
|
||||
end)
|
||||
align:SetScript("OnEditFocusGained", align.HighlightText)
|
||||
align:SetScript("OnShow", function()
|
||||
EditBox_ClearFocus(this)
|
||||
this:SetText(E.db.gridSize)
|
||||
end)
|
||||
|
||||
align.text = align:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
align.text:SetPoint("RIGHT", align, "LEFT", -4, 0)
|
||||
align.text:SetText(L["Grid Size:"])
|
||||
|
||||
--position buttons
|
||||
snapping:SetPoint("BOTTOMLEFT", 14, 10)
|
||||
lock:SetPoint("BOTTOMRIGHT", -14, 14)
|
||||
align:SetPoint("TOPRIGHT", lock, "TOPLEFT", -4, -2)
|
||||
|
||||
S:HandleCheckBox(snapping)
|
||||
S:HandleButton(lock)
|
||||
S:HandleEditBox(align)
|
||||
|
||||
f:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
f:SetScript("OnEvent", function()
|
||||
if this:IsShown() then
|
||||
this:Hide()
|
||||
E:Grid_Hide()
|
||||
E:ToggleConfigMode(true)
|
||||
end
|
||||
end)
|
||||
|
||||
local configMode = CreateFrame("Frame", f:GetName().."DropDown", f, "UIDropDownMenuTemplate")
|
||||
configMode:SetPoint("BOTTOMRIGHT", lock, "TOPRIGHT", 8, -5)
|
||||
S:HandleDropDownBox(configMode, 148)
|
||||
configMode.text = configMode:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
configMode.text:SetPoint("RIGHT", configMode.backdrop, "LEFT", -2, 0)
|
||||
configMode.text:SetText(L["Config Mode:"])
|
||||
|
||||
--UIDropDownMenu_Initialize(configMode, ConfigMode_Initialize)
|
||||
|
||||
local nudgeFrame = CreateFrame("Frame", "ElvUIMoverNudgeWindow", E.UIParent)
|
||||
nudgeFrame:SetFrameStrata("DIALOG")
|
||||
nudgeFrame:SetWidth(200)
|
||||
nudgeFrame:SetHeight(110)
|
||||
E:SetTemplate(nudgeFrame, "Transparent")
|
||||
nudgeFrame:SetPoint("TOP", ElvUIMoverPopupWindow, "BOTTOM", 0, -15)
|
||||
nudgeFrame:SetFrameLevel(100)
|
||||
nudgeFrame:Hide()
|
||||
nudgeFrame:EnableMouse(true)
|
||||
nudgeFrame:SetClampedToScreen(true)
|
||||
--ElvUIMoverPopupWindow:HookScript("OnHide", function() ElvUIMoverNudgeWindow:Hide() end)
|
||||
|
||||
header = CreateFrame("Button", "ElvUIMoverNudgeWindowHeader", nudgeFrame)
|
||||
E:SetTemplate(header, "Default", true)
|
||||
header:SetWidth(100) header:SetHeight(25)
|
||||
header:SetPoint("CENTER", nudgeFrame, "TOP")
|
||||
header:SetFrameLevel(header:GetFrameLevel() + 2)
|
||||
|
||||
title = header:CreateFontString("OVERLAY")
|
||||
E:FontTemplate(title)
|
||||
title:SetPoint("CENTER", header, "CENTER")
|
||||
title:SetText(L["Nudge"])
|
||||
header.title = title
|
||||
|
||||
local xOffset = CreateFrame("EditBox", nudgeFrame:GetName().."XEditBox", nudgeFrame, "InputBoxTemplate")
|
||||
xOffset:SetWidth(50)
|
||||
xOffset:SetHeight(17)
|
||||
xOffset:SetAutoFocus(false)
|
||||
xOffset.currentValue = 0
|
||||
xOffset:SetScript("OnEscapePressed", function()
|
||||
this:SetText(E:Round(xOffset.currentValue))
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
xOffset:SetScript("OnEnterPressed", function()
|
||||
local num = this:GetText()
|
||||
if(tonumber(num)) then
|
||||
local diff = num - xOffset.currentValue
|
||||
xOffset.currentValue = num
|
||||
E:NudgeMover(diff)
|
||||
end
|
||||
this:SetText(E:Round(xOffset.currentValue))
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
xOffset:SetScript("OnEditFocusLost", function()
|
||||
this:SetText(E:Round(xOffset.currentValue))
|
||||
end)
|
||||
xOffset:SetScript("OnEditFocusGained", xOffset.HighlightText)
|
||||
xOffset:SetScript("OnShow", function()
|
||||
EditBox_ClearFocus(this)
|
||||
this:SetText(E:Round(xOffset.currentValue))
|
||||
end)
|
||||
|
||||
xOffset.text = xOffset:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
xOffset.text:SetPoint("RIGHT", xOffset, "LEFT", -4, 0)
|
||||
xOffset.text:SetText("X:")
|
||||
xOffset:SetPoint("BOTTOMRIGHT", nudgeFrame, "CENTER", -6, 8)
|
||||
nudgeFrame.xOffset = xOffset
|
||||
S:HandleEditBox(xOffset)
|
||||
|
||||
local yOffset = CreateFrame("EditBox", nudgeFrame:GetName().."YEditBox", nudgeFrame, "InputBoxTemplate")
|
||||
yOffset:SetWidth(50)
|
||||
yOffset:SetHeight(17)
|
||||
yOffset:SetAutoFocus(false)
|
||||
yOffset.currentValue = 0
|
||||
yOffset:SetScript("OnEscapePressed", function()
|
||||
this:SetText(E:Round(yOffset.currentValue))
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
yOffset:SetScript("OnEnterPressed", function()
|
||||
local num = this:GetText()
|
||||
if(tonumber(num)) then
|
||||
local diff = num - yOffset.currentValue
|
||||
yOffset.currentValue = num
|
||||
E:NudgeMover(nil, diff)
|
||||
end
|
||||
this:SetText(E:Round(yOffset.currentValue))
|
||||
EditBox_ClearFocus(this)
|
||||
end)
|
||||
yOffset:SetScript("OnEditFocusLost", function()
|
||||
this:SetText(E:Round(yOffset.currentValue))
|
||||
end)
|
||||
yOffset:SetScript("OnEditFocusGained", yOffset.HighlightText)
|
||||
yOffset:SetScript("OnShow", function()
|
||||
EditBox_ClearFocus(this)
|
||||
this:SetText(E:Round(yOffset.currentValue))
|
||||
end)
|
||||
|
||||
yOffset.text = yOffset:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
yOffset.text:SetPoint("RIGHT", yOffset, "LEFT", -4, 0)
|
||||
yOffset.text:SetText("Y:")
|
||||
yOffset:SetPoint("BOTTOMLEFT", nudgeFrame, "CENTER", 16, 8)
|
||||
nudgeFrame.yOffset = yOffset
|
||||
S:HandleEditBox(yOffset)
|
||||
|
||||
local resetButton = CreateFrame("Button", nudgeFrame:GetName().."ResetButton", nudgeFrame, "UIPanelButtonTemplate")
|
||||
resetButton:SetText(RESET)
|
||||
resetButton:SetPoint("TOP", nudgeFrame, "CENTER", 0, 2)
|
||||
resetButton:SetWidth(100)
|
||||
resetButton:SetHeight(25)
|
||||
resetButton:SetScript("OnClick", function()
|
||||
if(ElvUIMoverNudgeWindow.child.textString) then
|
||||
E:ResetMovers(ElvUIMoverNudgeWindow.child.textString)
|
||||
E:UpdateNudgeFrame(ElvUIMoverNudgeWindow.child)
|
||||
end
|
||||
end)
|
||||
S:HandleButton(resetButton)
|
||||
-- Up Button
|
||||
local upButton = CreateFrame("Button", nudgeFrame:GetName().."PrevButton", nudgeFrame)
|
||||
upButton:SetWidth(26)
|
||||
upButton:SetHeight(26)
|
||||
upButton:SetPoint("BOTTOMRIGHT", nudgeFrame, "BOTTOM", -6, 4)
|
||||
upButton:SetScript("OnClick", function()
|
||||
E:NudgeMover(nil, 1)
|
||||
end)
|
||||
upButton.icon = upButton:CreateTexture(nil, "ARTWORK")
|
||||
upButton.icon:SetWidth(13)
|
||||
upButton.icon:SetHeight(13)
|
||||
upButton.icon:SetPoint("CENTER", 0, 0)
|
||||
upButton.icon:SetTexture([[Interface\AddOns\ElvUI\Media\Textures\SquareButtonTextures.blp]])
|
||||
upButton.icon:SetTexCoord(0.01562500, 0.20312500, 0.01562500, 0.20312500)
|
||||
|
||||
S:SquareButton_SetIcon(upButton, "UP")
|
||||
S:HandleButton(upButton)
|
||||
-- Down Button
|
||||
local downButton = CreateFrame("Button", nudgeFrame:GetName().."DownButton", nudgeFrame)
|
||||
downButton:SetWidth(26)
|
||||
downButton:SetHeight(26)
|
||||
downButton:SetPoint("BOTTOMLEFT", nudgeFrame, "BOTTOM", 6, 4)
|
||||
downButton:SetScript("OnClick", function()
|
||||
E:NudgeMover(nil, -1)
|
||||
end)
|
||||
downButton.icon = downButton:CreateTexture(nil, "ARTWORK")
|
||||
downButton.icon:SetWidth(13)
|
||||
downButton.icon:SetHeight(13)
|
||||
downButton.icon:SetPoint("CENTER", 0, 0)
|
||||
downButton.icon:SetTexture([[Interface\AddOns\ElvUI\Media\Textures\SquareButtonTextures.blp]])
|
||||
downButton.icon:SetTexCoord(0.01562500, 0.20312500, 0.01562500, 0.20312500)
|
||||
|
||||
S:SquareButton_SetIcon(downButton, "DOWN")
|
||||
S:HandleButton(downButton)
|
||||
-- Left Button
|
||||
local leftButton = CreateFrame("Button", nudgeFrame:GetName().."LeftButton", nudgeFrame)
|
||||
leftButton:SetWidth(26)
|
||||
leftButton:SetHeight(26)
|
||||
leftButton:SetPoint("RIGHT", upButton, "LEFT", -6, 0)
|
||||
leftButton:SetScript("OnClick", function()
|
||||
E:NudgeMover(-1)
|
||||
end)
|
||||
leftButton.icon = leftButton:CreateTexture(nil, "ARTWORK")
|
||||
leftButton.icon:SetWidth(13)
|
||||
leftButton.icon:SetHeight(13)
|
||||
leftButton.icon:SetPoint("CENTER", 0, 0)
|
||||
leftButton.icon:SetTexture([[Interface\AddOns\ElvUI\Media\Textures\SquareButtonTextures.blp]])
|
||||
leftButton.icon:SetTexCoord(0.01562500, 0.20312500, 0.01562500, 0.20312500)
|
||||
|
||||
S:SquareButton_SetIcon(leftButton, "LEFT")
|
||||
S:HandleButton(leftButton)
|
||||
-- Right Button
|
||||
local rightButton = CreateFrame("Button", nudgeFrame:GetName().."RightButton", nudgeFrame)
|
||||
rightButton:SetWidth(26)
|
||||
rightButton:SetHeight(26)
|
||||
rightButton:SetPoint("LEFT", downButton, "RIGHT", 6, 0)
|
||||
rightButton:SetScript("OnClick", function()
|
||||
E:NudgeMover(1)
|
||||
end)
|
||||
rightButton.icon = rightButton:CreateTexture(nil, "ARTWORK")
|
||||
rightButton.icon:SetWidth(13)
|
||||
rightButton.icon:SetHeight(13)
|
||||
rightButton.icon:SetPoint("CENTER", 0, 0)
|
||||
rightButton.icon:SetTexture([[Interface\AddOns\ElvUI\Media\Textures\SquareButtonTextures.blp]])
|
||||
rightButton.icon:SetTexCoord(0.01562500, 0.20312500, 0.01562500, 0.20312500)
|
||||
|
||||
S:SquareButton_SetIcon(rightButton, "RIGHT")
|
||||
S:HandleButton(rightButton)
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Math.lua"/>
|
||||
<Script file="core.lua"/>
|
||||
<Script file="fonts.lua"/>
|
||||
<Script file="install.lua"/>
|
||||
<Script file="pixelperfect.lua"/>
|
||||
<Script file="toolkit.lua"/>
|
||||
<Script file="commands.lua"/>
|
||||
<Script file="staticpopups.lua"/>
|
||||
<Script file="Movers.lua"/>
|
||||
<Script file="Config.lua"/>
|
||||
<Script file="tutorials.lua"/>
|
||||
<Script file="distributor.lua"/>
|
||||
<Script file="dropdown.lua"/>
|
||||
<Script file="cooldowns.lua"/>
|
||||
<Script file="aprilfools.lua"/>
|
||||
<Script file="pluginInstaller.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,403 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
--Cache global variables
|
||||
--Lua functions
|
||||
local select, unpack, assert, tonumber, type, pairs = select, unpack, assert, tonumber, type, pairs
|
||||
local getn, tinsert, tremove = table.getn, tinsert, tremove
|
||||
local abs, ceil, floor, modf, mod = math.abs, math.ceil, math.floor, math.modf, math.mod
|
||||
local format, sub, upper, split, utf8sub = string.format, string.sub, string.upper, string.split, string.utf8sub
|
||||
--WoW API / Variables
|
||||
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
function E:ShortValue(v)
|
||||
if E.db.general.numberPrefixStyle == "METRIC" then
|
||||
if abs(v) >= 1e9 then
|
||||
return format("%.1fG", v / 1e9)
|
||||
elseif abs(v) >= 1e6 then
|
||||
return format("%.1fM", v / 1e6)
|
||||
elseif abs(v) >= 1e3 then
|
||||
return format("%.1fk", v / 1e3)
|
||||
else
|
||||
return format("%d", v)
|
||||
end
|
||||
elseif E.db.general.numberPrefixStyle == "CHINESE" then
|
||||
if abs(v) >= 1e8 then
|
||||
return format("%.1fY", v / 1e8)
|
||||
elseif(abs(v) >= 1e4) then
|
||||
return format("%.1fW", v / 1e4)
|
||||
else
|
||||
return format("%d", v)
|
||||
end
|
||||
else
|
||||
if abs(v) >= 1e9 then
|
||||
return format("%.1fB", v / 1e9)
|
||||
elseif abs(v) >= 1e6 then
|
||||
return format("%.1fM", v / 1e6)
|
||||
elseif abs(v) >= 1e3 then
|
||||
return format("%.1fK", v / 1e3)
|
||||
else
|
||||
return format("%d", v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:IsEvenNumber(num)
|
||||
return mod(num, 2) == 0
|
||||
end
|
||||
|
||||
function E:ColorGradient(perc, ...)
|
||||
if not arg[9] then return end
|
||||
|
||||
if perc >= 1 then
|
||||
return arg[7], arg[8], arg[9]
|
||||
elseif perc <= 0 then
|
||||
return arg[1], arg[2], arg[3]
|
||||
end
|
||||
|
||||
local num = getn(arg) / 3
|
||||
local segment, relperc = math.modf(perc*(num-1))
|
||||
|
||||
local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, unpack(arg))
|
||||
|
||||
return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
|
||||
end
|
||||
|
||||
function E:Round(num, idp)
|
||||
if idp and idp > 0 then
|
||||
local mult = 10 ^ idp
|
||||
return floor(num * mult + 0.5) / mult
|
||||
end
|
||||
return floor(num + 0.5)
|
||||
end
|
||||
|
||||
function E:Truncate(v, decimals)
|
||||
return 0
|
||||
end
|
||||
|
||||
function E:RGBToHex(r, g, b)
|
||||
r = r <= 1 and r >= 0 and r or 0
|
||||
g = g <= 1 and g >= 0 and g or 0
|
||||
b = b <= 1 and b >= 0 and b or 0
|
||||
return format("|cff%02x%02x%02x", r*255, g*255, b*255)
|
||||
end
|
||||
|
||||
function E:HexToRGB(hex)
|
||||
local rhex, ghex, bhex = sub(hex, 1, 2), sub(hex, 3, 4), sub(hex, 5, 6)
|
||||
return tonumber(rhex, 16), tonumber(ghex, 16), tonumber(bhex, 16)
|
||||
end
|
||||
|
||||
function E:FramesOverlap(frameA, frameB)
|
||||
if not frameA or not frameB then return end
|
||||
|
||||
local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale()
|
||||
if not sA or not sB then return end
|
||||
|
||||
local frameALeft = frameA:GetLeft()
|
||||
local frameARight = frameA:GetRight()
|
||||
local frameABottom = frameA:GetBottom()
|
||||
local frameATop = frameA:GetTop()
|
||||
|
||||
local frameBLeft = frameB:GetLeft()
|
||||
local frameBRight = frameB:GetRight()
|
||||
local frameBBottom = frameB:GetBottom()
|
||||
local frameBTop = frameB:GetTop()
|
||||
|
||||
if not frameALeft or not frameARight or not frameABottom or not frameATop then return end
|
||||
if not frameBLeft or not frameBRight or not frameBBottom or not frameBTop then return end
|
||||
|
||||
return ((frameALeft*sA) < (frameBRight*sB))
|
||||
and ((frameBLeft*sB) < (frameARight*sA))
|
||||
and ((frameABottom*sA) < (frameBTop*sB))
|
||||
and ((frameBBottom*sB) < (frameATop*sA))
|
||||
end
|
||||
|
||||
function E:GetScreenQuadrant(frame)
|
||||
local x, y = frame:GetCenter()
|
||||
local screenWidth = GetScreenWidth()
|
||||
local screenHeight = GetScreenHeight()
|
||||
local point
|
||||
|
||||
if not frame:GetCenter() then
|
||||
return "UNKNOWN", frame:GetName()
|
||||
end
|
||||
|
||||
if (x > (screenWidth / 3) and x < (screenWidth / 3)*2) and y > (screenHeight / 3)*2 then
|
||||
point = "TOP"
|
||||
elseif x < (screenWidth / 3) and y > (screenHeight / 3)*2 then
|
||||
point = "TOPLEFT"
|
||||
elseif x > (screenWidth / 3)*2 and y > (screenHeight / 3)*2 then
|
||||
point = "TOPRIGHT"
|
||||
elseif (x > (screenWidth / 3) and x < (screenWidth / 3)*2) and y < (screenHeight / 3) then
|
||||
point = "BOTTOM"
|
||||
elseif x < (screenWidth / 3) and y < (screenHeight / 3) then
|
||||
point = "BOTTOMLEFT"
|
||||
elseif x > (screenWidth / 3)*2 and y < (screenHeight / 3) then
|
||||
point = "BOTTOMRIGHT"
|
||||
elseif x < (screenWidth / 3) and (y > (screenHeight / 3) and y < (screenHeight / 3)*2) then
|
||||
point = "LEFT"
|
||||
elseif x > (screenWidth / 3)*2 and y < (screenHeight / 3)*2 and y > (screenHeight / 3) then
|
||||
point = "RIGHT"
|
||||
else
|
||||
point = "CENTER"
|
||||
end
|
||||
return point
|
||||
end
|
||||
|
||||
function E:GetXYOffset(position, override)
|
||||
local default = E.Spacing
|
||||
local x, y = override or default, override or default
|
||||
|
||||
if position == "TOP" then
|
||||
return 0, y
|
||||
elseif position == "TOPLEFT" then
|
||||
return x, y
|
||||
elseif position == "TOPRIGHT" then
|
||||
return -x, y
|
||||
elseif position == "BOTTOM" then
|
||||
return 0, -y
|
||||
elseif(position == "BOTTOMLEFT") then
|
||||
return x, -y
|
||||
elseif position == "BOTTOMRIGHT" then
|
||||
return -x, -y
|
||||
elseif position == "LEFT" then
|
||||
return -x, 0
|
||||
elseif position == "RIGHT" then
|
||||
return x, 0
|
||||
elseif position == "CENTER" then
|
||||
return 0, 0
|
||||
end
|
||||
end
|
||||
|
||||
local styles = {
|
||||
["CURRENT"] = "%s",
|
||||
["CURRENT_MAX"] = "%s - %s",
|
||||
["CURRENT_PERCENT"] = "%s - %.1f%%",
|
||||
["CURRENT_MAX_PERCENT"] = "%s - %s | %.1f%%",
|
||||
["PERCENT"] = "%.1f%%",
|
||||
["DEFICIT"] = "-%s"
|
||||
}
|
||||
|
||||
function E:GetFormattedText(style, min, max)
|
||||
assert(styles[style], "Invalid format style: "..style)
|
||||
assert(min, "You need to provide a current value. Usage: E:GetFormattedText(style, min, max)")
|
||||
assert(max, "You need to provide a maximum value. Usage: E:GetFormattedText(style, min, max)")
|
||||
|
||||
if max == 0 then max = 1 end
|
||||
|
||||
local useStyle = styles[style]
|
||||
|
||||
if style == "DEFICIT" then
|
||||
local deficit = max - min
|
||||
if deficit <= 0 then
|
||||
return ""
|
||||
else
|
||||
return format(useStyle, E:ShortValue(deficit))
|
||||
end
|
||||
elseif style == "PERCENT" then
|
||||
local s = format(useStyle, min / max * 100)
|
||||
return s
|
||||
elseif style == "CURRENT" or ((style == "CURRENT_MAX" or style == "CURRENT_MAX_PERCENT" or style == "CURRENT_PERCENT") and min == max) then
|
||||
return format(styles["CURRENT"], E:ShortValue(min))
|
||||
elseif style == "CURRENT_MAX" then
|
||||
return format(useStyle, E:ShortValue(min), E:ShortValue(max))
|
||||
elseif style == "CURRENT_PERCENT" then
|
||||
local s = format(useStyle, E:ShortValue(min), min / max * 100)
|
||||
return s
|
||||
elseif style == "CURRENT_MAX_PERCENT" then
|
||||
local s = format(useStyle, E:ShortValue(min), E:ShortValue(max), min / max * 100)
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
function E:AbbreviateString(string, allUpper)
|
||||
local newString = ""
|
||||
local words = {split(" ", string)}
|
||||
for _, word in pairs(words) do
|
||||
word = utf8sub(word, 1, 1)
|
||||
if(allUpper) then
|
||||
word = upper(word)
|
||||
end
|
||||
newString = newString..word
|
||||
end
|
||||
|
||||
return newString
|
||||
end
|
||||
|
||||
function E:ShortenString(string, numChars, dots)
|
||||
local bytes = len(string)
|
||||
if bytes <= numChars then
|
||||
return string
|
||||
else
|
||||
local len, pos = 0, 1
|
||||
while pos <= bytes do
|
||||
len = len + 1
|
||||
local c = byte(string, pos)
|
||||
if c > 0 and c <= 127 then
|
||||
pos = pos + 1
|
||||
elseif c >= 192 and c <= 223 then
|
||||
pos = pos + 2
|
||||
elseif c >= 224 and c <= 239 then
|
||||
pos = pos + 3
|
||||
elseif c >= 240 and c <= 247 then
|
||||
pos = pos + 4
|
||||
end
|
||||
if len == numChars then break end
|
||||
end
|
||||
|
||||
if len == numChars and pos <= bytes then
|
||||
return sub(string, 1, pos - 1)..(dots and "..." or "")
|
||||
else
|
||||
return string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local waitTable = {}
|
||||
local waitFrame
|
||||
function E:Delay(delay, func, arg)
|
||||
if type(delay) ~= "number" or type(func) ~= "function" then
|
||||
return false
|
||||
end
|
||||
if waitFrame == nil then
|
||||
waitFrame = CreateFrame("Frame","WaitFrame", E.UIParent)
|
||||
waitFrame:SetScript("onUpdate",function (_, elapse)
|
||||
local count = getn(waitTable)
|
||||
local i = 1
|
||||
while i <= count do
|
||||
local waitRecord = tremove(waitTable, i)
|
||||
local d = tremove(waitRecord, 1)
|
||||
local f = tremove(waitRecord, 1)
|
||||
local p = tremove(waitRecord, 1)
|
||||
if d > elapse then
|
||||
tinsert(waitTable, i, {d-elapse, f, p})
|
||||
i = i + 1
|
||||
else
|
||||
count = count - 1
|
||||
f(unpack(p))
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
tinsert(waitTable, {delay, func, {arg}})
|
||||
return true
|
||||
end
|
||||
|
||||
function E:StringTitle(str)
|
||||
return gsub(str, "(.)", upper, 1)
|
||||
end
|
||||
|
||||
E.TimeColors = {
|
||||
[0] = "|cffeeeeee",
|
||||
[1] = "|cffeeeeee",
|
||||
[2] = "|cffeeeeee",
|
||||
[3] = "|cffeeeeee",
|
||||
[4] = "|cfffe0000"
|
||||
}
|
||||
|
||||
E.TimeFormats = {
|
||||
[0] = {"%dd", "%dd"},
|
||||
[1] = {"%dh", "%dh"},
|
||||
[2] = {"%dm", "%dm"},
|
||||
[3] = {"%ds", "%d"},
|
||||
[4] = {"%.1fs", "%.1f"}
|
||||
}
|
||||
|
||||
local DAY, HOUR, MINUTE = 86400, 3600, 60
|
||||
local DAYISH, HOURISH, MINUTEISH = HOUR * 23.5, MINUTE * 59.5, 59.5
|
||||
local HALFDAYISH, HALFHOURISH, HALFMINUTEISH = DAY/2 + 0.5, HOUR/2 + 0.5, MINUTE/2 + 0.5
|
||||
|
||||
function E:GetTimeInfo(s, threshhold)
|
||||
if s < MINUTE then
|
||||
if s >= threshhold then
|
||||
return floor(s), 3, 0.51
|
||||
else
|
||||
return s, 4, 0.051
|
||||
end
|
||||
elseif s < HOUR then
|
||||
local minutes = floor((s/MINUTE)+.5)
|
||||
return ceil(s / MINUTE), 2, minutes > 1 and (s - (minutes*MINUTE - HALFMINUTEISH)) or (s - MINUTEISH)
|
||||
elseif s < DAY then
|
||||
local hours = floor((s/HOUR)+.5)
|
||||
return ceil(s / HOUR), 1, hours > 1 and (s - (hours*HOUR - HALFHOURISH)) or (s - HOURISH)
|
||||
else
|
||||
local days = floor((s/DAY)+.5)
|
||||
return ceil(s / DAY), 0, days > 1 and (s - (days*DAY - HALFDAYISH)) or (s - DAYISH)
|
||||
end
|
||||
end
|
||||
|
||||
local COLOR_COPPER = "|cffeda55f"
|
||||
local COLOR_SILVER = "|cffc7c7cf"
|
||||
local COLOR_GOLD = "|cffffd700"
|
||||
local ICON_COPPER = "|TInterface\\MoneyFrame\\UI-CopperIcon:12:12|t"
|
||||
local ICON_SILVER = "|TInterface\\MoneyFrame\\UI-SilverIcon:12:12|t"
|
||||
local ICON_GOLD = "|TInterface\\MoneyFrame\\UI-GoldIcon:12:12|t"
|
||||
|
||||
function E:FormatMoney(amount, style, textonly)
|
||||
local coppername = textonly and L.copperabbrev or ICON_COPPER
|
||||
local silvername = textonly and L.silverabbrev or ICON_SILVER
|
||||
local goldname = textonly and L.goldabbrev or ICON_GOLD
|
||||
|
||||
local value = abs(amount)
|
||||
local gold = floor(value / 10000)
|
||||
local silver = floor(mod(value / 100, 100))
|
||||
local copper = floor(mod(value, 100))
|
||||
|
||||
if not style or style == "SMART" then
|
||||
local str = ""
|
||||
if gold > 0 then
|
||||
str = format("%d%s%s", gold, goldname, (silver > 0 or copper > 0) and " " or "")
|
||||
end
|
||||
if silver > 0 then
|
||||
str = format("%s%d%s%s", str, silver, silvername, copper > 0 and " " or "")
|
||||
end
|
||||
if copper > 0 or value == 0 then
|
||||
str = format("%s%d%s", str, copper, coppername)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
if style == "FULL" then
|
||||
if gold > 0 then
|
||||
return format("%d%s %d%s %d%s", gold, goldname, silver, silvername, copper, coppername)
|
||||
elseif silver > 0 then
|
||||
return format("%d%s %d%s", silver, silvername, copper, coppername)
|
||||
else
|
||||
return format("%d%s", copper, coppername)
|
||||
end
|
||||
elseif style == "SHORT" then
|
||||
if gold > 0 then
|
||||
return format("%.1f%s", amount / 10000, goldname)
|
||||
elseif silver > 0 then
|
||||
return format("%.1f%s", amount / 100, silvername)
|
||||
else
|
||||
return format("%d%s", amount, coppername)
|
||||
end
|
||||
elseif style == "SHORTINT" then
|
||||
if gold > 0 then
|
||||
return format("%d%s", gold, goldname)
|
||||
elseif silver > 0 then
|
||||
return format("%d%s", silver, silvername)
|
||||
else
|
||||
return format("%d%s", copper, coppername)
|
||||
end
|
||||
elseif style == "CONDENSED" then
|
||||
if gold > 0 then
|
||||
return format("%s%d|r.%s%02d|r.%s%02d|r", COLOR_GOLD, gold, COLOR_SILVER, silver, COLOR_COPPER, copper)
|
||||
elseif silver > 0 then
|
||||
return format("%s%d|r.%s%02d|r", COLOR_SILVER, silver, COLOR_COPPER, copper)
|
||||
else
|
||||
return format("%s%d|r", COLOR_COPPER, copper)
|
||||
end
|
||||
elseif style == "BLIZZARD" then
|
||||
if gold > 0 then
|
||||
return format("%s%s %d%s %d%s", gold, goldname, silver, silvername, copper, coppername)
|
||||
elseif silver > 0 then
|
||||
return format("%d%s %d%s", silver, silvername, copper, coppername)
|
||||
else
|
||||
return format("%d%s", copper, coppername)
|
||||
end
|
||||
end
|
||||
|
||||
return self:FormatMoney(amount, "SMART")
|
||||
end
|
||||
@@ -0,0 +1,496 @@
|
||||
local E, L, V, P, G = unpack(ElvUI) --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local Sticky = LibStub("LibSimpleSticky-1.0")
|
||||
|
||||
local _G = getfenv()
|
||||
local type, unpack, pairs = type, unpack, pairs
|
||||
local format, split, find = string.format, string.split, string.find
|
||||
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
E.CreatedMovers = {}
|
||||
E.DisabledMovers = {}
|
||||
|
||||
local function SizeChanged()
|
||||
this.mover:SetWidth(this.dirtyWidth and this.dirtyWidth or this:GetWidth())
|
||||
this.mover:SetHeight(this.dirtyHeight and this.dirtyHeight or this:GetHeight())
|
||||
end
|
||||
|
||||
local function GetPoint(obj)
|
||||
local point, anchor, secondaryPoint, x, y = obj:GetPoint()
|
||||
if not anchor then anchor = ElvUIParent end
|
||||
|
||||
return format("%s,%s,%s,%d,%d", point, anchor:GetName(), secondaryPoint, E:Round(x), E:Round(y))
|
||||
end
|
||||
|
||||
local function UpdateCoords()
|
||||
local mover = this.child
|
||||
local x, y, _, nudgePoint, nudgeInversePoint = E:CalculateMoverPoints(mover)
|
||||
|
||||
local coordX, coordY = E:GetXYOffset(nudgeInversePoint, 1)
|
||||
ElvUIMoverNudgeWindow:ClearAllPoints()
|
||||
ElvUIMoverNudgeWindow:SetPoint(nudgePoint, mover, nudgeInversePoint, coordX, coordY)
|
||||
E:UpdateNudgeFrame(mover, x, y)
|
||||
end
|
||||
|
||||
local isDragging = false
|
||||
local coordFrame = CreateFrame("Frame")
|
||||
coordFrame:SetScript("OnUpdate", UpdateCoords)
|
||||
coordFrame:Hide()
|
||||
|
||||
local function CreateMover(parent, name, text, overlay, snapOffset, postdrag, shouldDisable)
|
||||
if not parent then return end --If for some reason the parent isnt loaded yet
|
||||
if E.CreatedMovers[name].Created then return end
|
||||
|
||||
if overlay == nil then overlay = true end
|
||||
local point, anchor, secondaryPoint, x, y = split(",", GetPoint(parent))
|
||||
|
||||
local width = parent.dirtyWidth or parent:GetWidth()
|
||||
local height = parent.dirtyHeight or parent:GetHeight()
|
||||
|
||||
local f = CreateFrame("Button", name, E.UIParent)
|
||||
f:SetClampedToScreen(true)
|
||||
f:RegisterForDrag("LeftButton", "RightButton")
|
||||
f:EnableMouseWheel(true)
|
||||
f:SetMovable(true)
|
||||
f:SetWidth(width)
|
||||
f:SetHeight(height)
|
||||
E:SetTemplate(f, "Transparent", nil, nil, true)
|
||||
f:Hide()
|
||||
f.parent = parent
|
||||
f.name = name
|
||||
f.textString = text
|
||||
f.postdrag = postdrag
|
||||
f.overlay = overlay
|
||||
f.snapOffset = snapOffset or -2
|
||||
f.shouldDisable = shouldDisable
|
||||
|
||||
f:SetFrameLevel(parent:GetFrameLevel() + 1)
|
||||
if(overlay == true) then
|
||||
f:SetFrameStrata("DIALOG")
|
||||
else
|
||||
f:SetFrameStrata("BACKGROUND")
|
||||
end
|
||||
|
||||
E.CreatedMovers[name].mover = f
|
||||
E["snapBars"][getn(E["snapBars"]) + 1] = f
|
||||
|
||||
local fs = f:CreateFontString(nil, "OVERLAY")
|
||||
E:FontTemplate(fs)
|
||||
fs:SetJustifyH("CENTER")
|
||||
fs:SetPoint("CENTER", f)
|
||||
fs:SetText(text or name)
|
||||
fs:SetTextColor(unpack(E["media"].rgbvaluecolor))
|
||||
f:SetFontString(fs)
|
||||
f.text = fs
|
||||
|
||||
if E.db["movers"] and E.db["movers"][name] then
|
||||
if type(E.db["movers"][name]) == "table" then
|
||||
f:SetPoint(E.db["movers"][name]["p"], E.UIParent, E.db["movers"][name]["p2"], E.db["movers"][name]["p3"], E.db["movers"][name]["p4"])
|
||||
E.db["movers"][name] = GetPoint(f)
|
||||
f:ClearAllPoints()
|
||||
end
|
||||
|
||||
local delim
|
||||
local anchorString = E.db["movers"][name]
|
||||
if find(anchorString, "\031") then
|
||||
delim = "\031"
|
||||
elseif find(anchorString, ",") then
|
||||
delim = ","
|
||||
end
|
||||
local point, anchor, secondaryPoint, x, y = split(delim, anchorString)
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
else
|
||||
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
end
|
||||
|
||||
local function OnDragStart()
|
||||
if E.db["general"].stickyFrames then
|
||||
Sticky:StartMoving(this, E["snapBars"], f.snapOffset, f.snapOffset, f.snapOffset, f.snapOffset)
|
||||
else
|
||||
this:StartMoving()
|
||||
end
|
||||
coordFrame.child = this
|
||||
coordFrame:Show()
|
||||
isDragging = true
|
||||
end
|
||||
|
||||
local function OnDragStop()
|
||||
isDragging = false
|
||||
if E.db["general"].stickyFrames then
|
||||
Sticky:StopMoving(this)
|
||||
else
|
||||
this:StopMovingOrSizing()
|
||||
end
|
||||
|
||||
local x, y, point = E:CalculateMoverPoints(this)
|
||||
this:ClearAllPoints()
|
||||
local overridePoint
|
||||
if(this.positionOverride) then
|
||||
if(this.positionOverride == "BOTTOM" or this.positionOverride == "TOP") then
|
||||
overridePoint = "BOTTOM"
|
||||
else
|
||||
overridePoint = "BOTTOMLEFT"
|
||||
end
|
||||
end
|
||||
|
||||
this:SetPoint(this.positionOverride or point, E.UIParent, overridePoint and overridePoint or point, x, y)
|
||||
if(this.positionOverride) then
|
||||
this.parent:ClearAllPoints()
|
||||
this.parent:SetPoint(this.positionOverride, this, this.positionOverride)
|
||||
end
|
||||
|
||||
E:SaveMoverPosition(name)
|
||||
|
||||
if ElvUIMoverNudgeWindow then
|
||||
E:UpdateNudgeFrame(this, x, y)
|
||||
end
|
||||
|
||||
coordFrame.child = nil
|
||||
coordFrame:Hide()
|
||||
|
||||
if postdrag ~= nil and type(postdrag) == "function" then
|
||||
postdrag(this, E:GetScreenQuadrant(this))
|
||||
end
|
||||
|
||||
this:SetUserPlaced(false)
|
||||
end
|
||||
|
||||
local function OnEnter()
|
||||
if isDragging then return end
|
||||
this.text:SetTextColor(1, 1, 1)
|
||||
ElvUIMoverNudgeWindow:Show()
|
||||
E.AssignFrameToNudge(this)
|
||||
coordFrame.child = this
|
||||
coordFrame:GetScript("OnUpdate")(coordFrame)
|
||||
end
|
||||
|
||||
local function OnMouseDown(button)
|
||||
if button == "RightButton" then
|
||||
isDragging = false
|
||||
if E.db["general"].stickyFrames then
|
||||
Sticky:StopMoving(this)
|
||||
else
|
||||
this:StopMovingOrSizing()
|
||||
end
|
||||
if IsControlKeyDown() and this.textString then
|
||||
E:ResetMovers(this.textString)
|
||||
elseif IsShiftKeyDown() then
|
||||
this:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function OnLeave(self)
|
||||
if isDragging then return end
|
||||
this.text:SetTextColor(unpack(E["media"].rgbvaluecolor))
|
||||
end
|
||||
|
||||
local function OnShow(self)
|
||||
this:SetBackdropBorderColor(unpack(E["media"].rgbvaluecolor))
|
||||
end
|
||||
|
||||
local function OnMouseWheel(_, delta)
|
||||
if(IsShiftKeyDown()) then
|
||||
E:NudgeMover(delta)
|
||||
else
|
||||
E:NudgeMover(nil, delta)
|
||||
end
|
||||
end
|
||||
|
||||
f:SetScript("OnDragStart", OnDragStart)
|
||||
f:SetScript("OnMouseUp", E.AssignFrameToNudge)
|
||||
f:SetScript("OnDragStop", OnDragStop)
|
||||
f:SetScript("OnEnter", OnEnter)
|
||||
f:SetScript("OnMouseDown", OnMouseDown)
|
||||
f:SetScript("OnLeave", OnLeave)
|
||||
f:SetScript("OnShow", OnShow)
|
||||
f:SetScript("OnMouseWheel", OnMouseWheel)
|
||||
|
||||
parent:SetScript("OnSizeChanged", SizeChanged)
|
||||
parent.mover = f
|
||||
|
||||
parent:ClearAllPoints()
|
||||
parent:SetPoint(point, f, 0, 0)
|
||||
|
||||
if postdrag ~= nil and type(postdrag) == "function" then
|
||||
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
f:SetScript("OnEvent", function()
|
||||
postdrag(f, E:GetScreenQuadrant(f))
|
||||
this:UnregisterAllEvents()
|
||||
end)
|
||||
end
|
||||
|
||||
E.CreatedMovers[name].Created = true
|
||||
end
|
||||
|
||||
function E:CalculateMoverPoints(mover, nudgeX, nudgeY)
|
||||
local screenWidth, screenHeight, screenCenter = E.UIParent:GetRight(), E.UIParent:GetTop(), E.UIParent:GetCenter()
|
||||
local x, y = mover:GetCenter()
|
||||
|
||||
local LEFT = screenWidth / 3
|
||||
local RIGHT = screenWidth * 2 / 3
|
||||
local TOP = screenHeight / 2
|
||||
local point, nudgePoint, nudgeInversePoint
|
||||
|
||||
if(y >= TOP) then
|
||||
point = "TOP"
|
||||
nudgePoint = "TOP"
|
||||
nudgeInversePoint = "BOTTOM"
|
||||
y = -(screenHeight - mover:GetTop())
|
||||
else
|
||||
point = "BOTTOM"
|
||||
nudgePoint = "BOTTOM"
|
||||
nudgeInversePoint = "TOP"
|
||||
y = mover:GetBottom()
|
||||
end
|
||||
|
||||
if(x >= RIGHT) then
|
||||
point = point .. "RIGHT"
|
||||
nudgePoint = "RIGHT"
|
||||
nudgeInversePoint = "LEFT"
|
||||
x = mover:GetRight() - screenWidth
|
||||
elseif(x <= LEFT) then
|
||||
point = point .. "LEFT"
|
||||
nudgePoint = "LEFT"
|
||||
nudgeInversePoint = "RIGHT"
|
||||
x = mover:GetLeft()
|
||||
else
|
||||
x = x - screenCenter
|
||||
end
|
||||
|
||||
if(mover.positionOverride) then
|
||||
if(mover.positionOverride == "TOPLEFT") then
|
||||
x = mover:GetLeft() - E.diffGetLeft
|
||||
y = mover:GetTop() - E.diffGetTop
|
||||
elseif(mover.positionOverride == "TOPRIGHT") then
|
||||
x = mover:GetRight() - E.diffGetRight
|
||||
y = mover:GetTop() - E.diffGetTop
|
||||
elseif(mover.positionOverride == "BOTTOMLEFT") then
|
||||
x = mover:GetLeft() - E.diffGetLeft
|
||||
y = mover:GetBottom() - E.diffGetBottom
|
||||
elseif(mover.positionOverride == "BOTTOMRIGHT") then
|
||||
x = mover:GetRight() - E.diffGetRight
|
||||
y = mover:GetBottom() - E.diffGetBottom
|
||||
elseif(mover.positionOverride == "BOTTOM") then
|
||||
x = mover:GetCenter() - screenCenter
|
||||
y = mover:GetBottom() - E.diffGetBottom
|
||||
elseif(mover.positionOverride == "TOP") then
|
||||
x = mover:GetCenter() - screenCenter
|
||||
y = mover:GetTop() - E.diffGetTop
|
||||
end
|
||||
end
|
||||
|
||||
x = x + (nudgeX or 0)
|
||||
y = y + (nudgeY or 0)
|
||||
|
||||
return x, y, point, nudgePoint, nudgeInversePoint
|
||||
end
|
||||
|
||||
function E:UpdatePositionOverride(name)
|
||||
if _G[name] and _G[name]:GetScript("OnDragStop") then
|
||||
_G[name]:GetScript("OnDragStop")(_G[name])
|
||||
end
|
||||
end
|
||||
|
||||
function E:HasMoverBeenMoved(name)
|
||||
if E.db["movers"] and E.db["movers"][name] then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function E:SaveMoverPosition(name)
|
||||
if not _G[name] then return end
|
||||
if not E.db.movers then E.db.movers = {} end
|
||||
|
||||
E.db.movers[name] = GetPoint(_G[name])
|
||||
end
|
||||
|
||||
function E:SetMoverSnapOffset(name, offset)
|
||||
if not _G[name] or not E.CreatedMovers[name] then return end
|
||||
E.CreatedMovers[name].mover.snapOffset = offset or -2
|
||||
E.CreatedMovers[name]["snapoffset"] = offset or -2
|
||||
end
|
||||
|
||||
function E:SaveMoverDefaultPosition(name)
|
||||
if not _G[name] then return end
|
||||
|
||||
E.CreatedMovers[name]["point"] = GetPoint(_G[name])
|
||||
E.CreatedMovers[name]["postdrag"](_G[name], E:GetScreenQuadrant(_G[name]))
|
||||
end
|
||||
|
||||
function E:CreateMover(parent, name, text, overlay, snapoffset, postdrag, moverTypes, shouldDisable)
|
||||
if not moverTypes then moverTypes = "ALL,GENERAL" end
|
||||
|
||||
if E.CreatedMovers[name] == nil then
|
||||
E.CreatedMovers[name] = {}
|
||||
E.CreatedMovers[name]["parent"] = parent
|
||||
E.CreatedMovers[name]["text"] = text
|
||||
E.CreatedMovers[name]["overlay"] = overlay
|
||||
E.CreatedMovers[name]["postdrag"] = postdrag
|
||||
E.CreatedMovers[name]["snapoffset"] = snapOffset
|
||||
E.CreatedMovers[name]["point"] = GetPoint(parent)
|
||||
E.CreatedMovers[name]["shouldDisable"] = shouldDisable
|
||||
|
||||
E.CreatedMovers[name]["type"] = {}
|
||||
local types = {split(",", moverTypes)}
|
||||
for i = 1, getn(types) do
|
||||
local moverType = types[i]
|
||||
E.CreatedMovers[name]["type"][moverType] = true
|
||||
end
|
||||
end
|
||||
|
||||
CreateMover(parent, name, text, overlay, snapoffset, postdrag, shouldDisable)
|
||||
end
|
||||
|
||||
function E:ToggleMovers(show, moverType)
|
||||
self.configMode = show
|
||||
|
||||
for name, _ in pairs(E.CreatedMovers) do
|
||||
if not show then
|
||||
_G[name]:Hide()
|
||||
else
|
||||
if E.CreatedMovers[name]["type"][moverType] then
|
||||
_G[name]:Show()
|
||||
else
|
||||
_G[name]:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:DisableMover(name)
|
||||
if(self.DisabledMovers[name]) then return end
|
||||
if(not self.CreatedMovers[name]) then
|
||||
error("mover doesn't exist")
|
||||
end
|
||||
|
||||
self.DisabledMovers[name] = {}
|
||||
for x, y in pairs(self.CreatedMovers[name]) do
|
||||
self.DisabledMovers[name][x] = y
|
||||
end
|
||||
|
||||
if(self.configMode) then
|
||||
_G[name]:Hide()
|
||||
end
|
||||
|
||||
self.CreatedMovers[name] = nil
|
||||
end
|
||||
|
||||
function E:EnableMover(name)
|
||||
if(self.CreatedMovers[name]) then return end
|
||||
if(not self.DisabledMovers[name]) then
|
||||
error("mover doesn't exist")
|
||||
end
|
||||
|
||||
self.CreatedMovers[name] = {}
|
||||
for x, y in pairs(self.DisabledMovers[name]) do
|
||||
self.CreatedMovers[name][x] = y
|
||||
end
|
||||
|
||||
--Commented out, as it created an issue with trying to reset a mover after having used EnableMover on it. Not sure if this code is even needed anymore.
|
||||
--[[
|
||||
if(E.db["movers"] and E.db["movers"][name] and type(E.db["movers"][name]) == "string") then
|
||||
self.CreatedMovers[name]["point"] = E.db["movers"][name]
|
||||
end
|
||||
]]
|
||||
|
||||
if(self.configMode) then
|
||||
_G[name]:Show()
|
||||
end
|
||||
|
||||
self.DisabledMovers[name] = nil
|
||||
end
|
||||
|
||||
function E:ResetMovers(arg)
|
||||
if arg == "" or arg == nil then
|
||||
for name, _ in pairs(E.CreatedMovers) do
|
||||
local f = _G[name]
|
||||
local point, anchor, secondaryPoint, x, y = split(",", E.CreatedMovers[name]["point"])
|
||||
f:ClearAllPoints()
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
|
||||
for key, value in pairs(E.CreatedMovers[name]) do
|
||||
if key == "postdrag" and type(value) == "function" then
|
||||
value(f, E:GetScreenQuadrant(f))
|
||||
end
|
||||
end
|
||||
end
|
||||
self.db.movers = nil
|
||||
else
|
||||
for name, _ in pairs(E.CreatedMovers) do
|
||||
for key, value in pairs(E.CreatedMovers[name]) do
|
||||
if key == "text" then
|
||||
if arg == value then
|
||||
local f = _G[name]
|
||||
local point, anchor, secondaryPoint, x, y = split(",", E.CreatedMovers[name]["point"])
|
||||
f:ClearAllPoints()
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
|
||||
if self.db.movers then
|
||||
self.db.movers[name] = nil
|
||||
end
|
||||
|
||||
if E.CreatedMovers[name]["postdrag"] ~= nil and type(E.CreatedMovers[name]["postdrag"]) == "function" then
|
||||
E.CreatedMovers[name]["postdrag"](f, E:GetScreenQuadrant(f))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Profile Change
|
||||
function E:SetMoversPositions()
|
||||
for name in pairs(E.DisabledMovers) do
|
||||
local shouldDisable = ((E.DisabledMovers[name].shouldDisable and E.DisabledMovers[name]["shouldDisable"]()) or false)
|
||||
if not shouldDisable then
|
||||
E:EnableMover(name)
|
||||
end
|
||||
end
|
||||
|
||||
for name, _ in pairs(E.CreatedMovers) do
|
||||
local f = _G[name]
|
||||
local point, anchor, secondaryPoint, x, y
|
||||
if E.db["movers"] and E.db["movers"][name] and type(E.db["movers"][name]) == "string" then
|
||||
local delim
|
||||
local anchorString = E.db["movers"][name]
|
||||
if(find(anchorString, "\031")) then
|
||||
delim = "\031"
|
||||
elseif(find(anchorString, ",")) then
|
||||
delim = ","
|
||||
end
|
||||
point, anchor, secondaryPoint, x, y = split(delim, anchorString)
|
||||
f:ClearAllPoints()
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
elseif f then
|
||||
point, anchor, secondaryPoint, x, y = split(",", E.CreatedMovers[name]["point"])
|
||||
f:ClearAllPoints()
|
||||
f:SetPoint(point, anchor, secondaryPoint, x, y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Called from core.lua
|
||||
function E:LoadMovers()
|
||||
for n, _ in pairs(E.CreatedMovers) do
|
||||
local p, t, o, so, pd
|
||||
for key, value in pairs(E.CreatedMovers[n]) do
|
||||
if key == "parent" then
|
||||
p = value
|
||||
elseif key == "text" then
|
||||
t = value
|
||||
elseif key == "overlay" then
|
||||
o = value
|
||||
elseif key == "snapoffset" then
|
||||
so = value
|
||||
elseif key == "postdrag" then
|
||||
pd = value
|
||||
end
|
||||
end
|
||||
CreateMover(p, n, t, o, so, pd)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,165 @@
|
||||
local E, L, V, P, G = unpack(ElvUI);
|
||||
|
||||
local _G = getfenv();
|
||||
local tonumber, type = tonumber, type;
|
||||
local format, lower = string.format, string.lower;
|
||||
|
||||
local InCombatLockdown = InCombatLockdown;
|
||||
local UIFrameFadeOut, UIFrameFadeIn = UIFrameFadeOut, UIFrameFadeIn;
|
||||
local EnableAddOn, DisableAddOn, DisableAllAddOns = EnableAddOn, DisableAddOn, DisableAllAddOns;
|
||||
local SetCVar = SetCVar;
|
||||
local ReloadUI = ReloadUI;
|
||||
local debugprofilestart, debugprofilestop = debugprofilestart, debugprofilestop;
|
||||
local UpdateAddOnCPUUsage, GetAddOnCPUUsage = UpdateAddOnCPUUsage, GetAddOnCPUUsage;
|
||||
local ResetCPUUsage = ResetCPUUsage;
|
||||
local GetAddOnInfo = GetAddOnInfo;
|
||||
local ERR_NOT_IN_COMBAT = ERR_NOT_IN_COMBAT;
|
||||
|
||||
function E:EnableAddon(addon)
|
||||
local _, _, _, _, _, reason, _ = GetAddOnInfo(addon);
|
||||
if(reason ~= "MISSING") then
|
||||
EnableAddOn(addon);
|
||||
ReloadUI();
|
||||
else
|
||||
E:Print(format("Addon '%s' not found.", addon));
|
||||
end
|
||||
end
|
||||
|
||||
function E:DisableAddon(addon)
|
||||
local _, _, _, _, _, reason, _ = GetAddOnInfo(addon);
|
||||
if(reason ~= "MISSING") then
|
||||
DisableAddOn(addon);
|
||||
ReloadUI();
|
||||
else
|
||||
E:Print(format("Addon '%s' not found.", addon));
|
||||
end
|
||||
end
|
||||
|
||||
function FarmMode()
|
||||
if E.private.general.minimap.enable ~= true then return end
|
||||
|
||||
if Minimap:IsShown() then
|
||||
UIFrameFadeOut(Minimap, 0.3)
|
||||
UIFrameFadeIn(FarmModeMap, 0.3)
|
||||
Minimap.fadeInfo.finishedFunc = function() Minimap:Hide(); _G.MinimapZoomIn:Click(); _G.MinimapZoomOut:Click(); Minimap:SetAlpha(1) end
|
||||
FarmModeMap.enabled = true;
|
||||
else
|
||||
UIFrameFadeOut(FarmModeMap, 0.3)
|
||||
UIFrameFadeIn(Minimap, 0.3)
|
||||
FarmModeMap.fadeInfo.finishedFunc = function() FarmModeMap:Hide(); _G.MinimapZoomIn:Click(); _G.MinimapZoomOut:Click(); Minimap:SetAlpha(1) end
|
||||
FarmModeMap.enabled = false
|
||||
end
|
||||
end
|
||||
|
||||
function E:FarmMode(msg)
|
||||
if(E.private.general.minimap.enable ~= true) then return; end
|
||||
if(msg and type(tonumber(msg)) == "number" and tonumber(msg) <= 500 and tonumber(msg) >= 20 and not InCombatLockdown()) then
|
||||
E.db.farmSize = tonumber(msg);
|
||||
FarmModeMap:Size(tonumber(msg));
|
||||
end
|
||||
|
||||
FarmMode();
|
||||
end
|
||||
|
||||
function E:Grid(msg)
|
||||
if(msg and type(tonumber(msg)) == "number" and tonumber(msg) <= 256 and tonumber(msg) >= 4) then
|
||||
E.db.gridSize = msg;
|
||||
E:Grid_Show();
|
||||
else
|
||||
if(EGrid) then
|
||||
E:Grid_Hide();
|
||||
else
|
||||
E:Grid_Show();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:LuaError(msg)
|
||||
msg = lower(msg);
|
||||
if(msg == "on") then
|
||||
DisableAllAddOns();
|
||||
EnableAddOn("ElvUI");
|
||||
EnableAddOn("ElvUI_Config");
|
||||
SetCVar("scriptErrors", 1);
|
||||
ReloadUI();
|
||||
elseif(msg == "off") then
|
||||
SetCVar("scriptErrors", 0);
|
||||
E:Print("Lua errors off.");
|
||||
else
|
||||
E:Print("/luaerror on - /luaerror off");
|
||||
end
|
||||
end
|
||||
|
||||
function E:BGStats()
|
||||
local DT = E:GetModule("DataTexts");
|
||||
DT.ForceHideBGStats = nil;
|
||||
DT:LoadDataTexts();
|
||||
|
||||
E:Print(L["Battleground datatexts will now show again if you are inside a battleground."]);
|
||||
end
|
||||
|
||||
local function OnCallback(command)
|
||||
MacroEditBox:GetScript("OnEvent")(MacroEditBox, "EXECUTE_CHAT_LINE", command);
|
||||
end
|
||||
|
||||
function E:DelayScriptCall(msg)
|
||||
local secs, command = msg:match("^([^%s]+)%s+(.*)$");
|
||||
secs = tonumber(secs);
|
||||
if((not secs) or (getn(command) == 0)) then
|
||||
self:Print("usage: /in <seconds> <command>");
|
||||
self:Print("example: /in 1.5 /say hi");
|
||||
else
|
||||
E:ScheduleTimer(OnCallback, secs, command);
|
||||
end
|
||||
end
|
||||
|
||||
local num_frames = 0;
|
||||
local function OnUpdate()
|
||||
num_frames = num_frames + 1;
|
||||
end
|
||||
local f = CreateFrame("Frame");
|
||||
f:Hide();
|
||||
f:SetScript("OnUpdate", OnUpdate);
|
||||
|
||||
local toggleMode = false;
|
||||
function E:GetCPUImpact()
|
||||
if(not toggleMode) then
|
||||
ResetCPUUsage();
|
||||
num_frames = 0;
|
||||
debugprofilestart();
|
||||
f:Show();
|
||||
toggleMode = true;
|
||||
self:Print("CPU Impact being calculated, type /cpuimpact to get results when you are ready.");
|
||||
else
|
||||
f:Hide()
|
||||
local ms_passed = debugprofilestop();
|
||||
UpdateAddOnCPUUsage();
|
||||
|
||||
self:Print("Consumed " .. (GetAddOnCPUUsage("ElvUI") / num_frames) .. " milliseconds per frame. Each frame took " .. (ms_passed / num_frames) .. " to render.");
|
||||
toggleMode = false;
|
||||
end
|
||||
end
|
||||
|
||||
function E:LoadCommands()
|
||||
self:RegisterChatCommand("in", "DelayScriptCall");
|
||||
self:RegisterChatCommand("ec", "ToggleConfig");
|
||||
self:RegisterChatCommand("elvui", "ToggleConfig");
|
||||
self:RegisterChatCommand("cpuimpact", "GetCPUImpact");
|
||||
self:RegisterChatCommand("cpuusage", "GetTopCPUFunc");
|
||||
self:RegisterChatCommand("bgstats", "BGStats");
|
||||
self:RegisterChatCommand("hellokitty", "HelloKittyToggle");
|
||||
self:RegisterChatCommand("hellokittyfix", "HelloKittyFix");
|
||||
self:RegisterChatCommand("harlemshake", "HarlemShakeToggle");
|
||||
self:RegisterChatCommand("luaerror", "LuaError");
|
||||
self:RegisterChatCommand("egrid", "Grid");
|
||||
self:RegisterChatCommand("moveui", "ToggleConfigMode");
|
||||
self:RegisterChatCommand("resetui", "ResetUI");
|
||||
self:RegisterChatCommand("enable", "EnableAddon");
|
||||
self:RegisterChatCommand("disable", "DisableAddon");
|
||||
self:RegisterChatCommand("farmmode", "FarmMode");
|
||||
--self:RegisterChatCommand("aprilfools", "");
|
||||
|
||||
--if E:GetModule("ActionBars") and E.private.actionbar.enable then
|
||||
-- self:RegisterChatCommand("kb", E:GetModule("ActionBars").ActivateBindMode);
|
||||
--end
|
||||
end
|
||||
@@ -0,0 +1,138 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
local floor = math.floor;
|
||||
local GetTime = GetTime;
|
||||
|
||||
local CreateFrame = CreateFrame;
|
||||
local hooksecurefunc = hooksecurefunc;
|
||||
|
||||
local ICON_SIZE = 36 --the normal size for an icon (don't change this)
|
||||
local FONT_SIZE = 20 --the base font size to use at a scale of 1
|
||||
local MIN_SCALE = 0.5 --the minimum scale we want to show cooldown counts at, anything below this will be hidden
|
||||
local MIN_DURATION = 1.5 --the minimum duration to show cooldown text for
|
||||
|
||||
local TimeColors = {
|
||||
[0] = "|cfffefefe",
|
||||
[1] = "|cfffefefe",
|
||||
[2] = "|cfffefefe",
|
||||
[3] = "|cfffefefe",
|
||||
[4] = "|cfffe0000",
|
||||
}
|
||||
|
||||
local function Cooldown_OnUpdate(cd, elapsed)
|
||||
if cd.nextUpdate > 0 then
|
||||
cd.nextUpdate = cd.nextUpdate - elapsed
|
||||
return
|
||||
end
|
||||
|
||||
local remain = cd.duration - (GetTime() - cd.start)
|
||||
|
||||
if remain > 0.05 then
|
||||
if (cd.fontScale * cd:GetEffectiveScale() / UIParent:GetScale()) < MIN_SCALE then
|
||||
cd.text:SetText("")
|
||||
cd.nextUpdate = 500
|
||||
else
|
||||
local timervalue, formatid
|
||||
timervalue, formatid, cd.nextUpdate = E:GetTimeInfo(remain, E.db.cooldown.threshold)
|
||||
cd.text:SetFormattedText(("%s%s|r"):format(TimeColors[formatid], E.TimeFormats[formatid][2]), timervalue)
|
||||
end
|
||||
else
|
||||
E:Cooldown_StopTimer(cd)
|
||||
end
|
||||
end
|
||||
|
||||
function E:Cooldown_OnSizeChanged(cd, width)
|
||||
local fontScale = floor(width +.5) / ICON_SIZE
|
||||
local override = cd:GetParent():GetParent().SizeOverride
|
||||
if override then
|
||||
fontScale = override / FONT_SIZE
|
||||
end
|
||||
|
||||
if fontScale == cd.fontScale then
|
||||
return
|
||||
end
|
||||
|
||||
cd.fontScale = fontScale
|
||||
if fontScale < MIN_SCALE and not override then
|
||||
cd:Hide()
|
||||
else
|
||||
cd:Show()
|
||||
cd.text:FontTemplate(nil, fontScale * FONT_SIZE, "OUTLINE")
|
||||
if cd.enabled then
|
||||
self:Cooldown_ForceUpdate(cd)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:Cooldown_ForceUpdate(cd)
|
||||
cd.nextUpdate = 0
|
||||
cd:Show()
|
||||
end
|
||||
|
||||
function E:Cooldown_StopTimer(cd)
|
||||
cd.enabled = nil
|
||||
cd:Hide()
|
||||
end
|
||||
|
||||
function E:CreateCooldownTimer(parent)
|
||||
local scaler = CreateFrame("Frame", nil, parent)
|
||||
scaler:SetAllPoints()
|
||||
|
||||
local timer = CreateFrame("Frame", nil, scaler);
|
||||
timer:Hide()
|
||||
timer:SetAllPoints()
|
||||
timer:SetScript("OnUpdate", Cooldown_OnUpdate)
|
||||
|
||||
local text = timer:CreateFontString(nil, "OVERLAY")
|
||||
text:SetPoint("CENTER", 1, 1)
|
||||
text:SetJustifyH("CENTER")
|
||||
timer.text = text
|
||||
|
||||
self:Cooldown_OnSizeChanged(timer, parent:GetSize())
|
||||
parent:SetScript("OnSizeChanged", function(_, w, h) self:Cooldown_OnSizeChanged(timer, w, h) end)
|
||||
|
||||
parent.timer = timer
|
||||
return timer
|
||||
end
|
||||
|
||||
function E:OnSetCooldown(start, duration)
|
||||
if(self.noOCC) then return end
|
||||
|
||||
if start > 0 and duration > MIN_DURATION then
|
||||
local timer = self.timer or E:CreateCooldownTimer(self)
|
||||
timer.start = start
|
||||
timer.duration = duration
|
||||
timer.enabled = true
|
||||
timer.nextUpdate = 0
|
||||
if timer.fontScale >= MIN_SCALE then timer:Show() end
|
||||
else
|
||||
local timer = self.timer
|
||||
if timer then
|
||||
E:Cooldown_StopTimer(timer)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:RegisterCooldown(cooldown)
|
||||
if(not E.private.cooldown.enable or cooldown.isHooked) then return end
|
||||
--hooksecurefunc(cooldown, "SetCooldown", E.OnSetCooldown)
|
||||
cooldown.isHooked = true
|
||||
end
|
||||
|
||||
function E:UpdateCooldownSettings()
|
||||
local color = self.db.cooldown.expiringColor
|
||||
TimeColors[4] = E:RGBToHex(color.r, color.g, color.b) -- color for timers that are soon to expire
|
||||
|
||||
color = self.db.cooldown.secondsColor
|
||||
TimeColors[3] = E:RGBToHex(color.r, color.g, color.b) -- color for timers that have seconds remaining
|
||||
|
||||
color = self.db.cooldown.minutesColor
|
||||
TimeColors[2] = E:RGBToHex(color.r, color.g, color.b) -- color for timers that have minutes remaining
|
||||
|
||||
color = self.db.cooldown.hoursColor
|
||||
TimeColors[1] = E:RGBToHex(color.r, color.g, color.b) -- color for timers that have hours remaining
|
||||
|
||||
color = self.db.cooldown.daysColor
|
||||
TimeColors[0] = E:RGBToHex(color.r, color.g, color.b) -- color for timers that have days remaining
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local LSM = LibStub("LibSharedMedia-3.0")
|
||||
|
||||
local SetCVar = SetCVar;
|
||||
|
||||
local function SetFont(obj, font, size, style, r, g, b, sr, sg, sb, sox, soy)
|
||||
if(not obj) then return; end
|
||||
|
||||
obj:SetFont(font, size, style)
|
||||
if sr and sg and sb then obj:SetShadowColor(sr, sg, sb) end
|
||||
if sox and soy then obj:SetShadowOffset(sox, soy) end
|
||||
if r and g and b then obj:SetTextColor(r, g, b)
|
||||
elseif r then obj:SetAlpha(r) end
|
||||
end
|
||||
|
||||
function E:UpdateBlizzardFonts()
|
||||
local NORMAL = self["media"].normFont;
|
||||
local COMBAT = LSM:Fetch("font", self.private.general.dmgfont);
|
||||
local NUMBER = self["media"].normFont;
|
||||
local NAMEFONT = LSM:Fetch("font", self.private.general.namefont);
|
||||
local MONOCHROME = "";
|
||||
|
||||
UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = 12
|
||||
CHAT_FONT_HEIGHTS = {10, 12, 13, 14, 15, 16, 17, 18, 19, 20}
|
||||
|
||||
UNIT_NAME_FONT = NAMEFONT;
|
||||
NAMEPLATE_FONT = NAMEFONT;
|
||||
DAMAGE_TEXT_FONT = COMBAT;
|
||||
STANDARD_TEXT_FONT = NORMAL;
|
||||
|
||||
if self.db.general.font == "Homespun" then
|
||||
MONOCHROME = "MONOCHROME"
|
||||
end
|
||||
|
||||
if self.eyefinity then
|
||||
-- damage are huge on eyefinity, so we disable it
|
||||
InterfaceOptionsCombatTextPanelTargetDamage:Hide()
|
||||
InterfaceOptionsCombatTextPanelPeriodicDamage:Hide()
|
||||
InterfaceOptionsCombatTextPanelPetDamage:Hide()
|
||||
InterfaceOptionsCombatTextPanelHealing:Hide()
|
||||
SetCVar("CombatLogPeriodicSpells",0)
|
||||
SetCVar("PetMeleeDamage",0)
|
||||
SetCVar("CombatDamage",0)
|
||||
SetCVar("CombatHealing",0)
|
||||
|
||||
-- set an invisible font for xp, honor kill, etc
|
||||
local INVISIBLE = "Interface\\Addons\\ElvUI\\Media\\Fonts\\Invisible.ttf"
|
||||
COMBAT = INVISIBLE
|
||||
end
|
||||
|
||||
if(self.private.general.replaceBlizzFonts) then
|
||||
SetFont(GameTooltipHeader, NORMAL, self.db.general.fontSize);
|
||||
SetFont(NumberFont_OutlineThick_Mono_Small, NUMBER, self.db.general.fontSize, "OUTLINE");
|
||||
SetFont(NumberFont_Outline_Huge, NUMBER, 28, MONOCHROME.."THICKOUTLINE", 28);
|
||||
SetFont(NumberFont_Outline_Large, NUMBER, 15, MONOCHROME.."OUTLINE");
|
||||
SetFont(NumberFont_Outline_Med, NUMBER, self.db.general.fontSize, "OUTLINE");
|
||||
SetFont(NumberFont_Shadow_Med, NORMAL, self.db.general.fontSize);
|
||||
SetFont(NumberFont_Shadow_Small, NORMAL, self.db.general.fontSize);
|
||||
SetFont(QuestFont, NORMAL, self.db.general.fontSize);
|
||||
SetFont(QuestFont_Large, NORMAL, 14);
|
||||
SetFont(SystemFont_Large, NORMAL, 15);
|
||||
SetFont(GameFontNormalMed3, NORMAL, 15);
|
||||
SetFont(SystemFont_Shadow_Huge1, NORMAL, 20, MONOCHROME .. "OUTLINE");
|
||||
SetFont(SystemFont_Med1, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_Med3, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_OutlineThick_Huge2, NORMAL, 20, MONOCHROME .. "THICKOUTLINE");
|
||||
SetFont(SystemFont_Outline_Small, NUMBER, self.db.general.fontSize, "OUTLINE");
|
||||
SetFont(SystemFont_Shadow_Large, NORMAL, 15);
|
||||
SetFont(SystemFont_Shadow_Med1, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_Shadow_Med3, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_Shadow_Outline_Huge2, NORMAL, 20, MONOCHROME .. "OUTLINE");
|
||||
SetFont(SystemFont_Shadow_Small, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_Small, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SystemFont_Tiny, NORMAL, self.db.general.fontSize);
|
||||
SetFont(Tooltip_Med, NORMAL, self.db.general.fontSize);
|
||||
SetFont(Tooltip_Small, NORMAL, self.db.general.fontSize);
|
||||
SetFont(FriendsFont_Normal, NORMAL, self.db.general.fontSize);
|
||||
SetFont(FriendsFont_Small, NORMAL, self.db.general.fontSize);
|
||||
SetFont(FriendsFont_Large, NORMAL, self.db.general.fontSize);
|
||||
SetFont(FriendsFont_UserText, NORMAL, self.db.general.fontSize);
|
||||
SetFont(SpellFont_Small, NORMAL, self.db.general.fontSize*0.9);
|
||||
SetFont(ZoneTextString, NORMAL, 32, MONOCHROME .. "OUTLINE");
|
||||
SetFont(SubZoneTextString, NORMAL, 25, MONOCHROME .. "OUTLINE");
|
||||
SetFont(PVPInfoTextString, NORMAL, 22, MONOCHROME .. "OUTLINE");
|
||||
SetFont(PVPArenaTextString, NORMAL, 22, MONOCHROME .. "OUTLINE");
|
||||
SetFont(CombatTextFont, COMBAT, 25, MONOCHROME .. "OUTLINE");
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,137 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
local abs, floor, min, max = math.abs, math.floor, math.min, math.max;
|
||||
local match = string.match;
|
||||
|
||||
local IsMacClient = IsMacClient;
|
||||
local GetCVar, SetCVar = GetCVar, SetCVar;
|
||||
local GetScreenHeight, GetScreenWidth = GetScreenHeight, GetScreenWidth;
|
||||
|
||||
local scale
|
||||
|
||||
function E:UIScale(event)
|
||||
if IsMacClient() and self.global.screenheight and self.global.screenwidth and (self.screenheight ~= self.global.screenheight or self.screenwidth ~= self.global.screenwidth) then
|
||||
self.screenheight = self.global.screenheight
|
||||
self.screenwidth = self.global.screenwidth
|
||||
end
|
||||
|
||||
if(GetCVar("UIScale")) then
|
||||
self.global.uiScale = GetCVar("UIScale");
|
||||
end
|
||||
|
||||
local minScale = self.global.general.minUiScale or 0.64;
|
||||
if(self.global.general.autoScale) then
|
||||
scale = max(minScale, min(1.00, 768/self.screenheight));
|
||||
else
|
||||
scale = max(minScale, min(1.00, self.global.uiScale or UIParent:GetScale() or 768/self.screenheight));
|
||||
end
|
||||
|
||||
if self.screenwidth < 1600 then
|
||||
self.lowversion = true;
|
||||
elseif self.screenwidth >= 3840 and self.global.general.eyefinity then
|
||||
local width = self.screenwidth;
|
||||
local height = self.screenheight;
|
||||
|
||||
-- because some user enable bezel compensation, we need to find the real width of a single monitor.
|
||||
-- I don't know how it really work, but i'm assuming they add pixel to width to compensate the bezel. :P
|
||||
|
||||
-- HQ resolution
|
||||
if width >= 9840 then width = 3280; end -- WQSXGA
|
||||
if width >= 7680 and width < 9840 then width = 2560; end -- WQXGA
|
||||
if width >= 5760 and width < 7680 then width = 1920; end -- WUXGA & HDTV
|
||||
if width >= 5040 and width < 5760 then width = 1680; end -- WSXGA+
|
||||
|
||||
-- adding height condition here to be sure it work with bezel compensation because WSXGA+ and UXGA/HD+ got approx same width
|
||||
if width >= 4800 and width < 5760 and height == 900 then width = 1600; end -- UXGA & HD+
|
||||
|
||||
-- low resolution screen
|
||||
if width >= 4320 and width < 4800 then width = 1440; end -- WSXGA
|
||||
if width >= 4080 and width < 4320 then width = 1360; end -- WXGA
|
||||
if width >= 3840 and width < 4080 then width = 1224; end -- SXGA & SXGA (UVGA) & WXGA & HDTV
|
||||
|
||||
-- yep, now set ElvUI to lower resolution if screen #1 width < 1600
|
||||
if width < 1600 then
|
||||
self.lowversion = true;
|
||||
end
|
||||
|
||||
-- register a constant, we will need it later for launch.lua
|
||||
self.eyefinity = width;
|
||||
end
|
||||
|
||||
for screenwidth, screenheight in string.gfind(GetCVar("gxResolution"), "(.+)x(.+)") do
|
||||
self.mult = 768/screenheight/scale
|
||||
|
||||
self.UIParent:SetWidth(screenwidth)
|
||||
self.UIParent:SetHeight(screenheight)
|
||||
end
|
||||
--self.mult = 1;
|
||||
self.Spacing = self.PixelMode and 0 or self.mult;
|
||||
self.Border = (self.PixelMode and self.mult or self.mult*2);
|
||||
--Set UIScale, NOTE: SetCVar for UIScale can cause taints so only do this when we need to..
|
||||
if E.Round and E:Round(UIParent:GetScale(), 5) ~= E:Round(scale, 5) and (event == "PLAYER_LOGIN") then
|
||||
SetCVar("UseUIScale", 1);
|
||||
SetCVar("UIScale", scale);
|
||||
WorldMapFrame.hasTaint = true;
|
||||
end
|
||||
|
||||
if (event == "PLAYER_LOGIN" or event == "UPDATE_FLOATING_CHAT_WINDOWS") then
|
||||
if IsMacClient() then
|
||||
self.global.screenheight = floor(GetScreenHeight()*100+.5)/100
|
||||
self.global.screenwidth = floor(GetScreenWidth()*100+.5)/100
|
||||
end
|
||||
|
||||
--Resize self.UIParent if Eyefinity is on.
|
||||
if self.eyefinity then
|
||||
local width = self.eyefinity;
|
||||
local height = self.screenheight;
|
||||
|
||||
-- if autoscale is off, find a new width value of self.UIParent for screen #1.
|
||||
if not self.global.general.autoScale or height > 1200 then
|
||||
local h = UIParent:GetHeight();
|
||||
local ratio = self.screenheight / h;
|
||||
local w = self.eyefinity / ratio;
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
end
|
||||
|
||||
self.UIParent:SetWidth(width);
|
||||
self.UIParent:SetHeight(height);
|
||||
else
|
||||
--[[Eyefinity Test mode
|
||||
Resize the E.UIParent to be smaller than it should be, all objects inside should relocate.
|
||||
Dragging moveable frames outside the box and reloading the UI ensures that they are saving position correctly.
|
||||
]]
|
||||
--self.UIParent:SetSize(UIParent:GetWidth() - 250, UIParent:GetHeight() - 250);
|
||||
|
||||
--self.UIParent:SetWidth(UIParent:GetWidth());
|
||||
--self.UIParent:SetHeight(UIParent:GetHeight());
|
||||
end
|
||||
|
||||
self.UIParent:ClearAllPoints();
|
||||
self.UIParent:SetPoint("CENTER", UIParent);
|
||||
|
||||
self.diffGetLeft = E:Round(abs(UIParent:GetLeft() - self.UIParent:GetLeft()));
|
||||
self.diffGetRight = E:Round(abs(UIParent:GetRight() - self.UIParent:GetRight()));
|
||||
self.diffGetTop = E:Round(abs(UIParent:GetTop() - self.UIParent:GetTop()));
|
||||
self.diffGetBottom = E:Round(abs(UIParent:GetBottom() - self.UIParent:GetBottom()));
|
||||
|
||||
local change
|
||||
if E.Round then
|
||||
change = abs((E:Round(UIParent:GetScale(), 5) * 100) - (E:Round(scale, 5) * 100))
|
||||
end
|
||||
|
||||
if event == "UPDATE_FLOATING_CHAT_WINDOWS" and change and change > 1 and self.global.general.autoScale then
|
||||
E:StaticPopup_Show("FAILED_UISCALE")
|
||||
elseif event == "UPDATE_FLOATING_CHAT_WINDOWS" and change and change > 1 then
|
||||
E:StaticPopup_Show("CONFIG_RL")
|
||||
end
|
||||
|
||||
self:UnregisterEvent("PLAYER_LOGIN")
|
||||
end
|
||||
end
|
||||
|
||||
-- pixel perfect script of custom ui scale.
|
||||
function E:Scale(x)
|
||||
return self.mult*floor(x/self.mult+.5);
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,310 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local LSM = LibStub("LibSharedMedia-3.0")
|
||||
|
||||
local _G = getfenv();
|
||||
local unpack, type, select, getmetatable = unpack, type, select, getmetatable;
|
||||
|
||||
local CreateFrame = CreateFrame;
|
||||
local RAID_CLASS_COLORS = RAID_CLASS_COLORS;
|
||||
local CUSTOM_CLASS_COLORS = CUSTOM_CLASS_COLORS;
|
||||
|
||||
--Preload shit..
|
||||
E.mult = 1;
|
||||
local backdropr, backdropg, backdropb, backdropa, borderr, borderg, borderb = 0, 0, 0, 1, 0, 0, 0;
|
||||
|
||||
local function GetTemplate(t, isUnitFrameElement)
|
||||
backdropa = 1
|
||||
if t == "ClassColor" then
|
||||
if(CUSTOM_CLASS_COLORS) then
|
||||
borderr, borderg, borderb = CUSTOM_CLASS_COLORS[E.myclass].r, CUSTOM_CLASS_COLORS[E.myclass].g, CUSTOM_CLASS_COLORS[E.myclass].b;
|
||||
else
|
||||
borderr, borderg, borderb = RAID_CLASS_COLORS[E.myclass].r, RAID_CLASS_COLORS[E.myclass].g, RAID_CLASS_COLORS[E.myclass].b;
|
||||
end
|
||||
|
||||
if t ~= "Transparent" then
|
||||
backdropr, backdropg, backdropb = unpack(E["media"].backdropcolor)
|
||||
else
|
||||
backdropr, backdropg, backdropb, backdropa = unpack(E["media"].backdropfadecolor)
|
||||
end
|
||||
elseif t == "Transparent" then
|
||||
if isUnitFrameElement then
|
||||
borderr, borderg, borderb = unpack(E["media"].unitframeBorderColor)
|
||||
else
|
||||
borderr, borderg, borderb = unpack(E["media"].bordercolor)
|
||||
end
|
||||
backdropr, backdropg, backdropb, backdropa = unpack(E["media"].backdropfadecolor)
|
||||
else
|
||||
if isUnitFrameElement then
|
||||
borderr, borderg, borderb = unpack(E["media"].unitframeBorderColor)
|
||||
else
|
||||
borderr, borderg, borderb = unpack(E["media"].bordercolor)
|
||||
end
|
||||
backdropr, backdropg, backdropb = unpack(E["media"].backdropcolor)
|
||||
end
|
||||
end
|
||||
|
||||
function E:Size(frame, width, height)
|
||||
assert(width);
|
||||
frame:SetSize(E:Scale(width), E:Scale(height or width));
|
||||
end
|
||||
|
||||
function E:Width(frame, width)
|
||||
frame:SetWidth(E:Scale(width))
|
||||
end
|
||||
|
||||
function E:Height(frame, height)
|
||||
assert(height)
|
||||
frame:SetHeight(E:Scale(height));
|
||||
end
|
||||
|
||||
function E:Point(obj, arg1, arg2, arg3, arg4, arg5)
|
||||
if(arg2 == nil) then
|
||||
arg2 = obj:GetParent();
|
||||
end
|
||||
|
||||
if type(arg1)=="number" then arg1 = E:Scale(arg1) end
|
||||
if type(arg2)=="number" then arg2 = E:Scale(arg2) end
|
||||
if type(arg3)=="number" then arg3 = E:Scale(arg3) end
|
||||
if type(arg4)=="number" then arg4 = E:Scale(arg4) end
|
||||
if type(arg5)=="number" then arg5 = E:Scale(arg5) end
|
||||
|
||||
obj:SetPoint(arg1, arg2, arg3, arg4, arg5)
|
||||
end
|
||||
|
||||
function E:SetOutside(obj, anchor, xOffset, yOffset, anchor2)
|
||||
xOffset = xOffset or E.Border
|
||||
yOffset = yOffset or E.Border
|
||||
anchor = anchor or obj:GetParent()
|
||||
|
||||
assert(anchor);
|
||||
if obj:GetPoint() then
|
||||
obj:ClearAllPoints()
|
||||
end
|
||||
|
||||
obj:SetPoint("TOPLEFT", anchor, "TOPLEFT", -xOffset, yOffset)
|
||||
obj:SetPoint("BOTTOMRIGHT", anchor2 or anchor, "BOTTOMRIGHT", xOffset, -yOffset)
|
||||
end
|
||||
|
||||
function E:SetInside(obj, anchor, xOffset, yOffset, anchor2)
|
||||
xOffset = xOffset or E.Border
|
||||
yOffset = yOffset or E.Border
|
||||
anchor = anchor or obj:GetParent()
|
||||
|
||||
assert(anchor);
|
||||
if obj:GetPoint() then
|
||||
obj:ClearAllPoints()
|
||||
end
|
||||
|
||||
obj:SetPoint("TOPLEFT", anchor, "TOPLEFT", xOffset, -yOffset)
|
||||
obj:SetPoint("BOTTOMRIGHT", anchor2 or anchor, "BOTTOMRIGHT", -xOffset, yOffset)
|
||||
end
|
||||
|
||||
function E:SetTemplate(f, t, glossTex, ignoreUpdates, forcePixelMode, isUnitFrameElement)
|
||||
GetTemplate(t, isUnitFrameElement)
|
||||
|
||||
if(t) then
|
||||
f.template = t;
|
||||
end
|
||||
|
||||
if(glossTex) then
|
||||
f.glossTex = glossTex;
|
||||
end
|
||||
|
||||
if(ignoreUpdates) then
|
||||
f.ignoreUpdates = ignoreUpdates;
|
||||
end
|
||||
|
||||
if(forcePixelMode) then
|
||||
f.forcePixelMode = forcePixelMode
|
||||
end
|
||||
|
||||
local bgFile = E.media.blankTex;
|
||||
if(glossTex) then
|
||||
bgFile = E.media.glossTex;
|
||||
end
|
||||
|
||||
if(isUnitFrameElement) then
|
||||
f.isUnitFrameElement = isUnitFrameElement
|
||||
end
|
||||
|
||||
if(t ~= "NoBackdrop") then
|
||||
if(E.private.general.pixelPerfect or f.forcePixelMode) then
|
||||
f:SetBackdrop({
|
||||
bgFile = bgFile,
|
||||
edgeFile = E["media"].blankTex,
|
||||
tile = false, tileSize = 0, edgeSize = E.mult,
|
||||
insets = {left = 0, right = 0, top = 0, bottom = 0}
|
||||
});
|
||||
else
|
||||
f:SetBackdrop({
|
||||
bgFile = bgFile,
|
||||
edgeFile = E["media"].blankTex,
|
||||
tile = false, tileSize = 0, edgeSize = E.mult,
|
||||
insets = {left = -E.mult, right = -E.mult, top = -E.mult, bottom = -E.mult}
|
||||
});
|
||||
end
|
||||
|
||||
if not f.oborder and not f.iborder and not E.private.general.pixelPerfect and not f.forcePixelMode then
|
||||
local border = CreateFrame("Frame", nil, f)
|
||||
E:SetInside(border, f, E.mult, E.mult)
|
||||
border:SetBackdrop({
|
||||
edgeFile = E["media"].blankTex,
|
||||
edgeSize = E.mult,
|
||||
insets = {left = E.mult, right = E.mult, top = E.mult, bottom = E.mult}
|
||||
});
|
||||
border:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
f.iborder = border
|
||||
|
||||
if f.oborder then return end
|
||||
border = CreateFrame("Frame", nil, f)
|
||||
E:SetOutside(border, f, E.mult, E.mult)
|
||||
border:SetFrameLevel(f:GetFrameLevel() + 1)
|
||||
border:SetBackdrop({
|
||||
edgeFile = E["media"].blankTex,
|
||||
edgeSize = E.mult,
|
||||
insets = {left = E.mult, right = E.mult, top = E.mult, bottom = E.mult}
|
||||
});
|
||||
border:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
f.oborder = border
|
||||
end
|
||||
else
|
||||
f:SetBackdrop(nil);
|
||||
end
|
||||
|
||||
f:SetBackdropColor(backdropr, backdropg, backdropb, backdropa)
|
||||
f:SetBackdropBorderColor(borderr, borderg, borderb)
|
||||
|
||||
if(not f.ignoreUpdates) then
|
||||
if f.isUnitFrameElement then
|
||||
E["unitFrameElements"][f] = true
|
||||
else
|
||||
E["frames"][f] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:CreateBackdrop(f, t, tex, ignoreUpdates, forcePixelMode, isUnitFrameElement)
|
||||
if not f then return end
|
||||
if(not t) then t = "Default"; end
|
||||
|
||||
local b = CreateFrame("Frame", nil, f);
|
||||
if(f.forcePixelMode or forcePixelMode) then
|
||||
E:SetOutside(b, nil, E.mult, E.mult);
|
||||
else
|
||||
E:SetOutside(b);
|
||||
end
|
||||
E:SetTemplate(b, t, tex, ignoreUpdates, forcePixelMode, isUnitFrameElement);
|
||||
|
||||
if(f:GetFrameLevel() - 1 >= 0) then
|
||||
b:SetFrameLevel(f:GetFrameLevel() - 1);
|
||||
else
|
||||
b:SetFrameLevel(0);
|
||||
end
|
||||
|
||||
f.backdrop = b;
|
||||
end
|
||||
|
||||
function E:CreateShadow(f)
|
||||
if f.shadow then return end
|
||||
|
||||
borderr, borderg, borderb = 0, 0, 0
|
||||
backdropr, backdropg, backdropb = 0, 0, 0
|
||||
|
||||
local shadow = CreateFrame("Frame", nil, f)
|
||||
shadow:SetFrameLevel(1)
|
||||
shadow:SetFrameStrata(f:GetFrameStrata())
|
||||
E:SetOutside(shadow, f, 3, 3)
|
||||
shadow:SetBackdrop({
|
||||
edgeFile = LSM:Fetch("border", "ElvUI GlowBorder"), edgeSize = E:Scale(3),
|
||||
insets = {left = E:Scale(5), right = E:Scale(5), top = E:Scale(5), bottom = E:Scale(5)}
|
||||
});
|
||||
shadow:SetBackdropColor(backdropr, backdropg, backdropb, 0)
|
||||
shadow:SetBackdropBorderColor(borderr, borderg, borderb, 0.9)
|
||||
f.shadow = shadow
|
||||
end
|
||||
|
||||
function E:Kill(object)
|
||||
if object.UnregisterAllEvents then
|
||||
object:UnregisterAllEvents()
|
||||
object:SetParent(E.HiddenFrame)
|
||||
else
|
||||
object.Show = object.Hide
|
||||
end
|
||||
|
||||
object:Hide()
|
||||
end
|
||||
|
||||
function E:StripTextures(object, kill)
|
||||
for _, region in ipairs({object:GetRegions()}) do
|
||||
if region and region:GetObjectType() == "Texture" then
|
||||
if kill and type(kill) == "boolean" then
|
||||
E:Kill(region)
|
||||
elseif region:GetDrawLayer() == kill then
|
||||
region:SetTexture(nil)
|
||||
elseif kill and type(kill) == "string" and region:GetTexture() ~= kill then
|
||||
region:SetTexture(nil)
|
||||
else
|
||||
region:SetTexture(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function E:FontTemplate(fs, font, fontSize, fontStyle)
|
||||
fs.font = font
|
||||
fs.fontSize = fontSize
|
||||
fs.fontStyle = fontStyle
|
||||
|
||||
font = font or LSM:Fetch("font", E.db["general"].font)
|
||||
fontSize = fontSize or E.db.general.fontSize
|
||||
|
||||
if fontStyle == "OUTLINE" and (E.db.general.font == "Homespun") then
|
||||
if (fontSize > 10 and not fs.fontSize) then
|
||||
fontStyle = "MONOCHROMEOUTLINE"
|
||||
fontSize = 10
|
||||
end
|
||||
end
|
||||
|
||||
fs:SetFont(font, fontSize, fontStyle)
|
||||
if fontStyle and (fontStyle ~= "NONE") then
|
||||
fs:SetShadowColor(0, 0, 0, 0.2)
|
||||
else
|
||||
fs:SetShadowColor(0, 0, 0, 1)
|
||||
end
|
||||
fs:SetShadowOffset((E.mult or 1), -(E.mult or 1))
|
||||
|
||||
E["texts"][fs] = true
|
||||
end
|
||||
|
||||
function E:StyleButton(button, noHover, noPushed, noChecked)
|
||||
if button.SetHighlightTexture and not button.hover and not noHover then
|
||||
local hover = button:CreateTexture();
|
||||
hover:SetTexture(1, 1, 1, 0.3)
|
||||
E:SetInside(hover)
|
||||
button.hover = hover
|
||||
button:SetHighlightTexture(hover)
|
||||
end
|
||||
|
||||
if button.SetPushedTexture and not button.pushed and not noPushed then
|
||||
local pushed = button:CreateTexture();
|
||||
pushed:SetTexture(0.9, 0.8, 0.1, 0.3)
|
||||
E:SetInside(pushed)
|
||||
button.pushed = pushed
|
||||
button:SetPushedTexture(pushed)
|
||||
end
|
||||
|
||||
if button.SetCheckedTexture and not button.checked and not noChecked then
|
||||
local checked = button:CreateTexture();
|
||||
checked:SetTexture(1, 1, 1)
|
||||
E:SetInside(checked)
|
||||
checked:SetAlpha(0.3)
|
||||
button.checked = checked
|
||||
button:SetCheckedTexture(checked)
|
||||
end
|
||||
|
||||
local cooldown = button:GetName() and _G[button:GetName().."Cooldown"]
|
||||
if cooldown then
|
||||
cooldown:ClearAllPoints()
|
||||
E:SetInside(cooldown)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
|
||||
local _G = getfenv();
|
||||
|
||||
local CreateFrame = CreateFrame;
|
||||
local DISABLE = DISABLE;
|
||||
local HIDE = HIDE;
|
||||
|
||||
E.TutorialList = {
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"],
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."],
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."],
|
||||
L["You can set your keybinds quickly by typing /kb."],
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."],
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."],
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."],
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."],
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."],
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."],
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"],
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."],
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."]
|
||||
}
|
||||
|
||||
function E:SetNextTutorial()
|
||||
self.db.currentTutorial = self.db.currentTutorial or 0
|
||||
self.db.currentTutorial = self.db.currentTutorial + 1
|
||||
|
||||
if self.db.currentTutorial > gent(E.TutorialList) then
|
||||
self.db.currentTutorial = 1
|
||||
end
|
||||
|
||||
ElvUITutorialWindow.desc:SetText(E.TutorialList[self.db.currentTutorial])
|
||||
end
|
||||
|
||||
function E:SetPrevTutorial()
|
||||
self.db.currentTutorial = self.db.currentTutorial or 0
|
||||
self.db.currentTutorial = self.db.currentTutorial - 1
|
||||
|
||||
if self.db.currentTutorial <= 0 then
|
||||
self.db.currentTutorial = gent(E.TutorialList)
|
||||
end
|
||||
|
||||
ElvUITutorialWindow.desc:SetText(E.TutorialList[self.db.currentTutorial])
|
||||
end
|
||||
|
||||
function E:SpawnTutorialFrame()
|
||||
local f = CreateFrame("Frame", "ElvUITutorialWindow", UIParent)
|
||||
f:SetFrameStrata("DIALOG")
|
||||
f:SetToplevel(true)
|
||||
f:SetClampedToScreen(true)
|
||||
f:SetWidth(360)
|
||||
f:SetHeight(110)
|
||||
E:SetTemplate(f, "Transparent")
|
||||
f:Hide()
|
||||
|
||||
local S = E:GetModule("Skins")
|
||||
|
||||
local header = CreateFrame("Button", nil, f)
|
||||
E:SetTemplate(header, "Default", true)
|
||||
header:SetWidth(120); header:SetHeight(25)
|
||||
header:SetPoint("CENTER", f, "TOP")
|
||||
header:SetFrameLevel(header:GetFrameLevel() + 2)
|
||||
|
||||
local title = header:CreateFontString("OVERLAY")
|
||||
title:FontTemplate()
|
||||
title:SetPoint("CENTER", header, "CENTER")
|
||||
title:SetText("ElvUI")
|
||||
|
||||
local desc = f:CreateFontString("ARTWORK")
|
||||
desc:SetFontObject("GameFontHighlight")
|
||||
desc:SetJustifyV("TOP")
|
||||
desc:SetJustifyH("LEFT")
|
||||
desc:SetPoint("TOPLEFT", 18, -32)
|
||||
desc:SetPoint("BOTTOMRIGHT", -18, 30)
|
||||
f.desc = desc
|
||||
|
||||
f.disableButton = CreateFrame("CheckButton", f:GetName().."DisableButton", f, "OptionsCheckButtonTemplate")
|
||||
_G[f.disableButton:GetName() .. "Text"]:SetText(DISABLE)
|
||||
f.disableButton:SetPoint("BOTTOMLEFT")
|
||||
S:HandleCheckBox(f.disableButton)
|
||||
f.disableButton:SetScript("OnShow", function(self) self:SetChecked(E.db.hideTutorial) end)
|
||||
|
||||
f.disableButton:SetScript("OnClick", function(self) E.db.hideTutorial = self:GetChecked() end)
|
||||
|
||||
f.hideButton = CreateFrame("Button", f:GetName().."HideButton", f, "OptionsButtonTemplate")
|
||||
f.hideButton:SetPoint("BOTTOMRIGHT", -5, 5)
|
||||
S:HandleButton(f.hideButton)
|
||||
_G[f.hideButton:GetName() .. "Text"]:SetText(HIDE)
|
||||
f.hideButton:SetScript("OnClick", function(self) E:StaticPopupSpecial_Hide(self:GetParent()) end)
|
||||
|
||||
f.nextButton = CreateFrame("Button", f:GetName().."NextButton", f, "OptionsButtonTemplate")
|
||||
f.nextButton:SetPoint("RIGHT", f.hideButton, "LEFT", -4, 0)
|
||||
f.nextButton:Width(20)
|
||||
S:HandleButton(f.nextButton)
|
||||
_G[f.nextButton:GetName() .. "Text"]:SetText(">")
|
||||
f.nextButton:SetScript("OnClick", function() E:SetNextTutorial() end)
|
||||
|
||||
f.prevButton = CreateFrame("Button", f:GetName().."PrevButton", f, "OptionsButtonTemplate")
|
||||
f.prevButton:SetPoint("RIGHT", f.nextButton, "LEFT", -4, 0)
|
||||
f.prevButton:Width(20)
|
||||
S:HandleButton(f.prevButton)
|
||||
_G[f.prevButton:GetName() .. "Text"]:SetText("<")
|
||||
f.prevButton:SetScript("OnClick", function() E:SetPrevTutorial() end)
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
function E:Tutorials(forceShow)
|
||||
if (not forceShow and self.db.hideTutorial) or (not forceShow and not self.private.install_complete) then return; end
|
||||
local f = ElvUITutorialWindow
|
||||
if not f then
|
||||
f = E:SpawnTutorialFrame()
|
||||
end
|
||||
|
||||
E:StaticPopupSpecial_Show(f)
|
||||
|
||||
self:SetNextTutorial()
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
--Cache global variables
|
||||
--Lua functions
|
||||
local _G = getfenv()
|
||||
local print, tostring, select = print, tostring, select
|
||||
local format = string.format
|
||||
--WoW API / Variables
|
||||
local GetMouseFocus = GetMouseFocus
|
||||
|
||||
--[[
|
||||
Command to grab frame information when mouseing over a frame
|
||||
|
||||
Frame Name
|
||||
Width
|
||||
Height
|
||||
Strata
|
||||
Level
|
||||
X Offset
|
||||
Y Offset
|
||||
Point
|
||||
]]
|
||||
|
||||
SLASH_FRAME1 = "/frame"
|
||||
SlashCmdList["FRAME"] = function(arg)
|
||||
if arg ~= "" then
|
||||
arg = _G[arg]
|
||||
else
|
||||
arg = GetMouseFocus()
|
||||
end
|
||||
if arg ~= nil then FRAME = arg end --Set the global variable FRAME to = whatever we are mousing over to simplify messing with frames that have no name.
|
||||
if arg ~= nil and arg:GetName() ~= nil then
|
||||
local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint()
|
||||
ChatFrame1:AddMessage("|cffCC0000----------------------------")
|
||||
ChatFrame1:AddMessage("Name: |cffFFD100"..arg:GetName())
|
||||
if arg:GetParent() and arg:GetParent():GetName() then
|
||||
ChatFrame1:AddMessage("Parent: |cffFFD100"..arg:GetParent():GetName())
|
||||
end
|
||||
|
||||
ChatFrame1:AddMessage("Width: |cffFFD100"..format("%.2f",arg:GetWidth()))
|
||||
ChatFrame1:AddMessage("Height: |cffFFD100"..format("%.2f",arg:GetHeight()))
|
||||
ChatFrame1:AddMessage("Strata: |cffFFD100"..arg:GetFrameStrata())
|
||||
ChatFrame1:AddMessage("Level: |cffFFD100"..arg:GetFrameLevel())
|
||||
|
||||
if xOfs then
|
||||
ChatFrame1:AddMessage("X: |cffFFD100"..format("%.2f",xOfs))
|
||||
end
|
||||
if yOfs then
|
||||
ChatFrame1:AddMessage("Y: |cffFFD100"..format("%.2f",yOfs))
|
||||
end
|
||||
if relativeTo and relativeTo:GetName() then
|
||||
ChatFrame1:AddMessage("Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint)
|
||||
end
|
||||
ChatFrame1:AddMessage("|cffCC0000----------------------------|r")
|
||||
elseif arg == nil then
|
||||
ChatFrame1:AddMessage("Invalid frame name")
|
||||
else
|
||||
ChatFrame1:AddMessage("Could not find frame info")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="ReloadUI.lua"/>
|
||||
<Script file="Frame.lua"/>
|
||||
<Script file="Test.lua"/>
|
||||
<Script file="Table.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,7 @@
|
||||
--[[
|
||||
Shortcut to ReloadUI
|
||||
]]
|
||||
|
||||
SLASH_RELOADUI1 = "/rl"
|
||||
SLASH_RELOADUI2 = "/reloadui"
|
||||
SlashCmdList.RELOADUI = ReloadUI
|
||||
@@ -0,0 +1,22 @@
|
||||
--Cache global variables
|
||||
local setmetatable, getmetatable = setmetatable, getmetatable
|
||||
local pairs, type = pairs, type
|
||||
local table = table
|
||||
|
||||
function table.copy(t, deep, seen)
|
||||
seen = seen or {}
|
||||
if t == nil then return nil end
|
||||
if seen[t] then return seen[t] end
|
||||
|
||||
local nt = {}
|
||||
for k, v in pairs(t) do
|
||||
if deep and type(v) == "table" then
|
||||
nt[k] = table.copy(v, deep, seen)
|
||||
else
|
||||
nt[k] = v
|
||||
end
|
||||
end
|
||||
setmetatable(nt, table.copy(getmetatable(t), deep, seen))
|
||||
seen[t] = nt
|
||||
return nt
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
--[[
|
||||
Going to leave this as my bullshit lua file.
|
||||
|
||||
So I can test stuff.
|
||||
]]
|
||||
@@ -0,0 +1,18 @@
|
||||
## Interface: 11200
|
||||
## Author: Elv, Bunny
|
||||
## Version: 0.01
|
||||
## Title: |cffA11313E|r|cffC4C4C4lvUI|r
|
||||
## Notes: User Interface replacement AddOn for World of Warcraft.
|
||||
## SavedVariables: ElvDB, ElvPrivateDB
|
||||
## SavedVariablesPerCharacter: ElvCharacterDB
|
||||
## OptionalDeps: SharedMedia
|
||||
|
||||
Developer\Load_Developer.xml
|
||||
Libraries\Load_Libraries.xml
|
||||
Locales\Load_Locales.xml
|
||||
Media\Load_Media.xml
|
||||
Init.lua
|
||||
Settings\Load_Config.xml
|
||||
Core\Load_Core.xml
|
||||
Layout\Load_Layout.xml
|
||||
Modules\Load_Modules.xml
|
||||
@@ -0,0 +1,156 @@
|
||||
--Cache global variables
|
||||
_G = getfenv(0)
|
||||
local pairs, unpack = pairs, unpack
|
||||
|
||||
BINDING_HEADER_ELVUI = GetAddOnMetadata("ElvUI", "Title")
|
||||
|
||||
ElvUI = {}
|
||||
|
||||
local AddOnName, Engine = "ElvUI", ElvUI
|
||||
local AddOn = LibStub("AceAddon-3.0"):NewAddon(AddOnName, "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "AceHook-3.0")
|
||||
AddOn.callbacks = AddOn.callbacks or
|
||||
LibStub("CallbackHandler-1.0"):New(AddOn)
|
||||
AddOn.DF = {} AddOn.DF["profile"] = {} AddOn.DF["global"] = {} AddOn.privateVars = {} AddOn.privateVars["profile"] = {} -- Defaults
|
||||
AddOn.Options = {
|
||||
type = "group",
|
||||
name = AddOnName,
|
||||
args = {},
|
||||
}
|
||||
|
||||
local Locale = LibStub("AceLocale-3.0"):GetLocale(AddOnName, false)
|
||||
Engine[1] = AddOn
|
||||
Engine[2] = Locale
|
||||
Engine[3] = AddOn.privateVars["profile"]
|
||||
Engine[4] = AddOn.DF["profile"]
|
||||
Engine[5] = AddOn.DF["global"]
|
||||
|
||||
_G[AddOnName] = Engine
|
||||
local tcopy = table.copy
|
||||
function AddOn:OnInitialize()
|
||||
if not ElvCharacterDB then
|
||||
ElvCharacterDB = {}
|
||||
end
|
||||
|
||||
self.db = tcopy(self.DF.profile, true)
|
||||
self.global = tcopy(self.DF.global, true)
|
||||
if ElvDB then
|
||||
if ElvDB.global then
|
||||
self:CopyTable(self.global, ElvDB.global)
|
||||
end
|
||||
|
||||
local profileKey
|
||||
if ElvDB.profileKeys then
|
||||
profileKey = ElvDB.profileKeys[self.myname.." - "..self.myrealm]
|
||||
end
|
||||
|
||||
if profileKey and ElvDB.profiles and ElvDB.profiles[profileKey] then
|
||||
self:CopyTable(self.db, ElvDB.profiles[profileKey])
|
||||
end
|
||||
end
|
||||
|
||||
self.private = tcopy(self.privateVars.profile, true)
|
||||
if ElvPrivateDB then
|
||||
local profileKey
|
||||
if ElvPrivateDB.profileKeys then
|
||||
profileKey = ElvPrivateDB.profileKeys[self.myname.." - "..self.myrealm]
|
||||
end
|
||||
|
||||
if profileKey and ElvPrivateDB.profiles and ElvPrivateDB.profiles[profileKey] then
|
||||
self:CopyTable(self.private, ElvPrivateDB.profiles[profileKey])
|
||||
end
|
||||
end
|
||||
|
||||
if self.private.general.pixelPerfect then
|
||||
self.Border = self.mult
|
||||
self.Spacing = 0
|
||||
self.PixelMode = true
|
||||
end
|
||||
|
||||
self:UIScale()
|
||||
self:UpdateMedia()
|
||||
|
||||
self:RegisterEvent("PLAYER_LOGIN", "Initialize")
|
||||
--self:Contruct_StaticPopups()
|
||||
self:InitializeInitialModules()
|
||||
|
||||
if IsAddOnLoaded("Tukui") then
|
||||
self:StaticPopup_Show("TUKUI_ELVUI_INCOMPATIBLE")
|
||||
end
|
||||
|
||||
local GameMenuButton = CreateFrame("Button", nil, GameMenuFrame, "GameMenuButtonTemplate")
|
||||
GameMenuButton:SetWidth(GameMenuButtonLogout:GetWidth())
|
||||
GameMenuButton:SetHeight(GameMenuButtonLogout:GetHeight())
|
||||
|
||||
GameMenuButton:SetText(AddOnName)
|
||||
GameMenuButton:SetScript("OnClick", function()
|
||||
AddOn:ToggleConfig()
|
||||
HideUIPanel(GameMenuFrame)
|
||||
end)
|
||||
GameMenuFrame[AddOnName] = GameMenuButton
|
||||
|
||||
HookScript(GameMenuFrame, "OnShow", function()
|
||||
if not GameMenuFrame.isElvUI then
|
||||
GameMenuFrame:SetHeight(GameMenuFrame:GetHeight() + GameMenuButtonLogout:GetHeight() + 1)
|
||||
GameMenuFrame.isElvUI = true
|
||||
end
|
||||
local _, relTo = GameMenuButtonLogout:GetPoint()
|
||||
if relTo ~= GameMenuFrame[AddOnName] then
|
||||
GameMenuFrame[AddOnName]:ClearAllPoints()
|
||||
GameMenuFrame[AddOnName]:SetPoint("TOPLEFT", relTo, "BOTTOMLEFT", 0, -1)
|
||||
GameMenuButtonLogout:ClearAllPoints()
|
||||
GameMenuButtonLogout:SetPoint("TOPLEFT", GameMenuFrame[AddOnName], "BOTTOMLEFT", 0, -16)
|
||||
end
|
||||
end)
|
||||
local S = AddOn:GetModule("Skins")
|
||||
S:HandleButton(GameMenuButton)
|
||||
end
|
||||
|
||||
function AddOn:ResetProfile()
|
||||
local profileKey
|
||||
if ElvPrivateDB.profileKeys then
|
||||
profileKey = ElvPrivateDB.profileKeys[self.myname.." - "..self.myrealm]
|
||||
end
|
||||
|
||||
if profileKey and ElvPrivateDB.profiles and ElvPrivateDB.profiles[profileKey] then
|
||||
ElvPrivateDB.profiles[profileKey] = nil
|
||||
end
|
||||
|
||||
ElvCharacterDB = nil
|
||||
ReloadUI()
|
||||
end
|
||||
|
||||
function AddOn:OnProfileReset()
|
||||
self:StaticPopup_Show("RESET_PROFILE_PROMPT")
|
||||
end
|
||||
|
||||
function AddOn:ToggleConfig()
|
||||
if not IsAddOnLoaded("ElvUI_Config") then
|
||||
local _, _, _, _, _, reason = GetAddOnInfo("ElvUI_Config")
|
||||
if reason ~= "MISSING" and reason ~= "DISABLED" then
|
||||
LoadAddOn("ElvUI_Config")
|
||||
if GetAddOnMetadata("ElvUI_Config", "Version") ~= "1.01" then
|
||||
self:StaticPopup_Show("CLIENT_UPDATE_REQUEST")
|
||||
end
|
||||
else
|
||||
self:Print("|cffff0000Error -- Addon 'ElvUI_Config' not found or is disabled.|r")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local ACD = LibStub("AceConfigDialog-3.0")
|
||||
|
||||
local mode = "Close"
|
||||
if not ACD.OpenFrames[AddOnName] then
|
||||
mode = "Open"
|
||||
end
|
||||
|
||||
if mode == "Open" then
|
||||
PlaySound("igMainMenuOpen")
|
||||
else
|
||||
PlaySound("igMainMenuClose")
|
||||
end
|
||||
|
||||
ACD[mode](ACD, AddOnName)
|
||||
|
||||
GameTooltip:Hide() --Just in case you're mouseovered something and it closes.
|
||||
end
|
||||
@@ -0,0 +1,415 @@
|
||||
local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local LO = E:NewModule("Layout", "AceEvent-3.0");
|
||||
|
||||
--Cache global variables
|
||||
--Lua functions
|
||||
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local UIFrameFadeIn, UIFrameFadeOut = UIFrameFadeIn, UIFrameFadeOut
|
||||
|
||||
local PANEL_HEIGHT = 22
|
||||
local SIDE_BUTTON_WIDTH = 16
|
||||
|
||||
E.Layout = LO
|
||||
|
||||
local function Panel_OnShow(self)
|
||||
self:SetFrameLevel(0)
|
||||
self:SetFrameStrata("BACKGROUND")
|
||||
end
|
||||
|
||||
function LO:Initialize()
|
||||
self:CreateChatPanels()
|
||||
self:CreateMinimapPanels()
|
||||
|
||||
self:SetDataPanelStyle()
|
||||
|
||||
self.BottomPanel = CreateFrame("Frame", "ElvUI_BottomPanel", E.UIParent)
|
||||
E:SetTemplate(self.BottomPanel, "Transparent")
|
||||
self.BottomPanel:SetPoint("BOTTOMLEFT", E.UIParent, "BOTTOMLEFT", -1, -1)
|
||||
self.BottomPanel:SetPoint("BOTTOMRIGHT", E.UIParent, "BOTTOMRIGHT", 1, -1)
|
||||
self.BottomPanel:SetHeight(PANEL_HEIGHT)
|
||||
self.BottomPanel:SetScript("OnShow", function() Panel_OnShow(this) end)
|
||||
Panel_OnShow(self.BottomPanel)
|
||||
self:BottomPanelVisibility()
|
||||
|
||||
self.TopPanel = CreateFrame("Frame", "ElvUI_TopPanel", E.UIParent)
|
||||
E:SetTemplate(self.TopPanel, "Transparent")
|
||||
self.TopPanel:SetPoint("TOPLEFT", E.UIParent, "TOPLEFT", -1, 1)
|
||||
self.TopPanel:SetPoint("TOPRIGHT", E.UIParent, "TOPRIGHT", 1, 1)
|
||||
self.TopPanel:SetHeight(PANEL_HEIGHT)
|
||||
self.TopPanel:SetScript("OnShow", function() Panel_OnShow(this) end)
|
||||
Panel_OnShow(self.TopPanel)
|
||||
self:TopPanelVisibility()
|
||||
end
|
||||
|
||||
function LO:BottomPanelVisibility()
|
||||
if(E.db.general.bottomPanel) then
|
||||
self.BottomPanel:Show()
|
||||
else
|
||||
self.BottomPanel:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function LO:TopPanelVisibility()
|
||||
if E.db.general.topPanel then
|
||||
self.TopPanel:Show()
|
||||
else
|
||||
self.TopPanel:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function ChatPanelLeft_OnFade()
|
||||
LeftChatPanel:Hide()
|
||||
end
|
||||
|
||||
local function ChatPanelRight_OnFade()
|
||||
RightChatPanel:Hide()
|
||||
end
|
||||
|
||||
local function ChatButton_OnEnter()
|
||||
if E.db[this.parent:GetName().."Faded"] then
|
||||
this.parent:Show()
|
||||
UIFrameFadeIn(this.parent, 0.2, this.parent:GetAlpha(), 1)
|
||||
UIFrameFadeIn(this, 0.2, this:GetAlpha(), 1)
|
||||
end
|
||||
|
||||
if this == LeftChatToggleButton then
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOPLEFT", 0, (E.PixelMode and 1 or 3))
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:AddDoubleLine(L["Left Click:"], L["Toggle Chat Frame"], 1, 1, 1)
|
||||
else
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOPRIGHT", 0, (E.PixelMode and 1 or 3))
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:AddDoubleLine(L["Left Click:"], L["Toggle Chat Frame"], 1, 1, 1)
|
||||
end
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
local function ChatButton_OnLeave()
|
||||
if E.db[this.parent:GetName().."Faded"] then
|
||||
UIFrameFadeOut(this.parent, 0.2, this.parent:GetAlpha(), 0)
|
||||
UIFrameFadeOut(this, 0.2, this:GetAlpha(), 0)
|
||||
this.parent.fadeInfo.finishedFunc = this.parent.fadeFunc
|
||||
end
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local function ChatButton_OnClick()
|
||||
GameTooltip:Hide()
|
||||
if E.db[this.parent:GetName().."Faded"] then
|
||||
E.db[this.parent:GetName().."Faded"] = nil
|
||||
UIFrameFadeIn(this.parent, 0.2, this.parent:GetAlpha(), 1)
|
||||
UIFrameFadeIn(this, 0.2, this:GetAlpha(), 1)
|
||||
else
|
||||
E.db[this.parent:GetName().."Faded"] = true
|
||||
UIFrameFadeOut(this.parent, 0.2, this.parent:GetAlpha(), 0)
|
||||
UIFrameFadeOut(this, 0.2, this:GetAlpha(), 0)
|
||||
this.parent.fadeInfo.finishedFunc = this.parent.fadeFunc
|
||||
end
|
||||
end
|
||||
|
||||
function HideLeftChat()
|
||||
ChatButton_OnClick(LeftChatToggleButton)
|
||||
end
|
||||
|
||||
function HideRightChat()
|
||||
ChatButton_OnClick(RightChatToggleButton)
|
||||
end
|
||||
|
||||
function HideBothChat()
|
||||
ChatButton_OnClick(LeftChatToggleButton)
|
||||
ChatButton_OnClick(RightChatToggleButton)
|
||||
end
|
||||
|
||||
function LO:ToggleChatTabPanels(rightOverride, leftOverride)
|
||||
if leftOverride or not E.db.chat.panelTabBackdrop then
|
||||
LeftChatTab:Hide()
|
||||
else
|
||||
LeftChatTab:Show()
|
||||
end
|
||||
|
||||
if rightOverride or not E.db.chat.panelTabBackdrop then
|
||||
RightChatTab:Hide()
|
||||
else
|
||||
RightChatTab:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function LO:SetChatTabStyle()
|
||||
if E.db.chat.panelTabTransparency then
|
||||
E:SetTemplate(LeftChatTab, "Transparent")
|
||||
E:SetTemplate(RightChatTab, "Transparent")
|
||||
else
|
||||
E:SetTemplate(LeftChatTab, "Default", true)
|
||||
E:SetTemplate(RightChatTab, "Default", true)
|
||||
end
|
||||
end
|
||||
|
||||
function LO:SetDataPanelStyle()
|
||||
if E.db.datatexts.panelTransparency then
|
||||
if not E.db.datatexts.panelBackdrop then
|
||||
E:SetTemplate(LeftChatDataPanel, "NoBackdrop")
|
||||
E:SetTemplate(LeftChatToggleButton, "NoBackdrop")
|
||||
E:SetTemplate(RightChatDataPanel, "NoBackdrop")
|
||||
E:SetTemplate(RightChatToggleButton, "NoBackdrop")
|
||||
else
|
||||
E:SetTemplate(LeftChatDataPanel, "Transparent")
|
||||
E:SetTemplate(LeftChatToggleButton, "Transparent")
|
||||
E:SetTemplate(RightChatDataPanel, "Transparent")
|
||||
E:SetTemplate(RightChatToggleButton, "Transparent")
|
||||
end
|
||||
|
||||
E:SetTemplate(LeftMiniPanel, "Transparent")
|
||||
E:SetTemplate(RightMiniPanel, "Transparent")
|
||||
else
|
||||
if not E.db.datatexts.panelBackdrop then
|
||||
E:SetTemplate(LeftChatDataPanel, "NoBackdrop")
|
||||
E:SetTemplate(LeftChatToggleButton, "NoBackdrop")
|
||||
E:SetTemplate(RightChatDataPanel, "NoBackdrop")
|
||||
E:SetTemplate(RightChatToggleButton, "NoBackdrop")
|
||||
else
|
||||
E:SetTemplate(LeftChatDataPanel, "Default", true)
|
||||
E:SetTemplate(LeftChatToggleButton, "Default", true)
|
||||
E:SetTemplate(RightChatDataPanel, "Default", true)
|
||||
E:SetTemplate(RightChatToggleButton, "Default", true)
|
||||
end
|
||||
|
||||
E:SetTemplate(RightMiniPanel, "Default", true)
|
||||
E:SetTemplate(LeftMiniPanel, "Default", true)
|
||||
end
|
||||
end
|
||||
|
||||
function LO:ToggleChatPanels()
|
||||
LeftChatDataPanel:ClearAllPoints()
|
||||
RightChatDataPanel:ClearAllPoints()
|
||||
local SPACING = E.Border*3 - E.Spacing
|
||||
|
||||
if E.db.datatexts.leftChatPanel then
|
||||
LeftChatDataPanel:Show()
|
||||
LeftChatToggleButton:Show()
|
||||
else
|
||||
LeftChatDataPanel:Hide()
|
||||
LeftChatToggleButton:Hide()
|
||||
end
|
||||
|
||||
if E.db.datatexts.rightChatPanel then
|
||||
RightChatDataPanel:Show()
|
||||
RightChatToggleButton:Show()
|
||||
else
|
||||
RightChatDataPanel:Hide()
|
||||
RightChatToggleButton:Hide()
|
||||
end
|
||||
|
||||
local panelBackdrop = E.db.chat.panelBackdrop
|
||||
if(panelBackdrop == "SHOWBOTH") then
|
||||
LeftChatPanel.backdrop:Show()
|
||||
RightChatPanel.backdrop:Show()
|
||||
LeftChatDataPanel:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SPACING + SIDE_BUTTON_WIDTH, SPACING)
|
||||
RightChatDataPanel:SetPoint("BOTTOMLEFT", RightChatPanel, "BOTTOMLEFT", SPACING, SPACING)
|
||||
LeftChatToggleButton:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SPACING, SPACING)
|
||||
RightChatToggleButton:SetPoint("BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT", -SPACING, SPACING)
|
||||
LO:ToggleChatTabPanels()
|
||||
elseif(panelBackdrop == "HIDEBOTH") then
|
||||
LeftChatPanel.backdrop:Hide()
|
||||
RightChatPanel.backdrop:Hide()
|
||||
LeftChatDataPanel:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SIDE_BUTTON_WIDTH, 0)
|
||||
RightChatDataPanel:SetPoint("BOTTOMLEFT", RightChatPanel, "BOTTOMLEFT")
|
||||
LeftChatToggleButton:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT")
|
||||
RightChatToggleButton:SetPoint("BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT")
|
||||
LO:ToggleChatTabPanels(true, true)
|
||||
elseif(panelBackdrop == "LEFT") then
|
||||
LeftChatPanel.backdrop:Show()
|
||||
RightChatPanel.backdrop:Hide()
|
||||
LeftChatDataPanel:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SPACING + SIDE_BUTTON_WIDTH, SPACING)
|
||||
RightChatDataPanel:SetPoint("BOTTOMLEFT", RightChatPanel, "BOTTOMLEFT")
|
||||
LeftChatToggleButton:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SPACING, SPACING)
|
||||
RightChatToggleButton:SetPoint("BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT")
|
||||
LO:ToggleChatTabPanels(true)
|
||||
else
|
||||
LeftChatPanel.backdrop:Hide()
|
||||
RightChatPanel.backdrop:Show()
|
||||
LeftChatDataPanel:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", SIDE_BUTTON_WIDTH, 0)
|
||||
RightChatDataPanel:SetPoint("BOTTOMLEFT", RightChatPanel, "BOTTOMLEFT", SPACING, SPACING)
|
||||
LeftChatToggleButton:SetPoint("BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT")
|
||||
RightChatToggleButton:SetPoint("BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT", -SPACING, SPACING)
|
||||
LO:ToggleChatTabPanels(nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
function LO:CreateChatPanels()
|
||||
local SPACING = E.Border*3 - E.Spacing
|
||||
--Left Chat
|
||||
local lchat = CreateFrame("Frame", "LeftChatPanel", E.UIParent)
|
||||
lchat:SetFrameStrata("BACKGROUND")
|
||||
lchat:SetWidth(E.db.chat.panelWidth)
|
||||
lchat:SetHeight(E.db.chat.panelHeight)
|
||||
lchat:SetPoint("BOTTOMLEFT", E.UIParent, 4, 4)
|
||||
lchat:SetFrameLevel(lchat:GetFrameLevel() + 2)
|
||||
E:CreateBackdrop(lchat, "Transparent")
|
||||
lchat.backdrop:SetAllPoints()
|
||||
E:CreateMover(lchat, "LeftChatMover", L["Left Chat"])
|
||||
|
||||
--Background Texture
|
||||
lchat.tex = lchat:CreateTexture(nil, "OVERLAY")
|
||||
E:SetInside(lchat.tex)
|
||||
lchat.tex:SetTexture(E.db.chat.panelBackdropNameLeft)
|
||||
lchat.tex:SetAlpha(E.db.general.backdropfadecolor.a - 0.7 > 0 and E.db.general.backdropfadecolor.a - 0.7 or 0.5)
|
||||
|
||||
--Left Chat Tab
|
||||
local lchattab = CreateFrame("Frame", "LeftChatTab", LeftChatPanel)
|
||||
lchattab:SetPoint("TOPLEFT", lchat, "TOPLEFT", SPACING, -SPACING)
|
||||
lchattab:SetPoint("BOTTOMRIGHT", lchat, "TOPRIGHT", -SPACING, -(SPACING + PANEL_HEIGHT))
|
||||
E:SetTemplate(lchattab, E.db.chat.panelTabTransparency == true and "Transparent" or "Default", true)
|
||||
|
||||
--Left Chat Data Panel
|
||||
local lchatdp = CreateFrame("Frame", "LeftChatDataPanel", LeftChatPanel)
|
||||
lchatdp:SetWidth(E.db.chat.panelWidth -((SPACING*2) + SIDE_BUTTON_WIDTH))
|
||||
lchatdp:SetHeight(PANEL_HEIGHT)
|
||||
lchatdp:SetPoint("BOTTOMLEFT", lchat, "BOTTOMLEFT", SPACING + SIDE_BUTTON_WIDTH, SPACING)
|
||||
E:SetTemplate(lchatdp, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
E:GetModule("DataTexts"):RegisterPanel(lchatdp, 3, "ANCHOR_TOPLEFT", -16, (E.PixelMode and 1 or 3))
|
||||
|
||||
--Left Chat Toggle Button
|
||||
local lchattb = CreateFrame("Button", "LeftChatToggleButton", E.UIParent)
|
||||
lchattb.parent = LeftChatPanel
|
||||
LeftChatPanel.fadeFunc = ChatPanelLeft_OnFade
|
||||
lchattb:SetPoint("TOPRIGHT", lchatdp, "TOPLEFT", E.Border - E.Spacing*3, 0)
|
||||
lchattb:SetPoint("BOTTOMLEFT", lchat, "BOTTOMLEFT", SPACING, SPACING)
|
||||
E:SetTemplate(lchattb, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
lchattb:SetScript("OnEnter", ChatButton_OnEnter)
|
||||
lchattb:SetScript("OnLeave", ChatButton_OnLeave)
|
||||
lchattb:SetScript("OnClick", ChatButton_OnClick)
|
||||
lchattb.text = lchattb:CreateFontString(nil, "OVERLAY")
|
||||
E:FontTemplate(lchattb.text)
|
||||
lchattb.text:SetPoint("CENTER", lchattb)
|
||||
lchattb.text:SetJustifyH("CENTER")
|
||||
lchattb.text:SetText("<")
|
||||
|
||||
--Right Chat
|
||||
local rchat = CreateFrame("Frame", "RightChatPanel", E.UIParent)
|
||||
rchat:SetFrameStrata("BACKGROUND")
|
||||
rchat:SetWidth(E.db.chat.separateSizes and E.db.chat.panelWidthRight or E.db.chat.panelWidth)
|
||||
rchat:SetHeight(E.db.chat.separateSizes and E.db.chat.panelHeightRight or E.db.chat.panelHeight)
|
||||
rchat:SetPoint("BOTTOMRIGHT", E.UIParent, -4, 4)
|
||||
rchat:SetFrameLevel(lchat:GetFrameLevel() + 2)
|
||||
E:CreateBackdrop(rchat, "Transparent")
|
||||
rchat.backdrop:SetAllPoints()
|
||||
E:CreateMover(rchat, "RightChatMover", L["Right Chat"])
|
||||
|
||||
--Background Texture
|
||||
rchat.tex = rchat:CreateTexture(nil, "OVERLAY")
|
||||
E:SetInside(rchat.tex)
|
||||
rchat.tex:SetTexture(E.db.chat.panelBackdropNameRight)
|
||||
rchat.tex:SetAlpha(E.db.general.backdropfadecolor.a - 0.7 > 0 and E.db.general.backdropfadecolor.a - 0.7 or 0.5)
|
||||
|
||||
--Right Chat Tab
|
||||
local rchattab = CreateFrame("Frame", "RightChatTab", RightChatPanel)
|
||||
rchattab:SetPoint("TOPRIGHT", rchat, "TOPRIGHT", -SPACING, -SPACING)
|
||||
rchattab:SetPoint("BOTTOMLEFT", rchat, "TOPLEFT", SPACING, -(SPACING + PANEL_HEIGHT))
|
||||
E:SetTemplate(rchattab, E.db.chat.panelTabTransparency == true and "Transparent" or "Default", true)
|
||||
|
||||
--Right Chat Data Panel
|
||||
local rchatdp = CreateFrame("Frame", "RightChatDataPanel", RightChatPanel)
|
||||
rchatdp:SetWidth((E.db.chat.separateSizes and E.db.chat.panelWidthRight or E.db.chat.panelWidth) -((SPACING*2) + SIDE_BUTTON_WIDTH))
|
||||
rchatdp:SetHeight(PANEL_HEIGHT)
|
||||
rchatdp:SetPoint("BOTTOMLEFT", rchat, "BOTTOMLEFT", SPACING, SPACING)
|
||||
E:SetTemplate(rchatdp, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
E:GetModule("DataTexts"):RegisterPanel(rchatdp, 3, "ANCHOR_TOPRIGHT", 16, (E.PixelMode and 1 or 3))
|
||||
|
||||
--Right Chat Toggle Button
|
||||
local rchattb = CreateFrame("Button", "RightChatToggleButton", E.UIParent)
|
||||
rchattb.parent = RightChatPanel
|
||||
RightChatPanel.fadeFunc = ChatPanelRight_OnFade
|
||||
rchattb:SetPoint("TOPLEFT", rchatdp, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
rchattb:SetPoint("BOTTOMRIGHT", rchat, "BOTTOMRIGHT", -SPACING, SPACING)
|
||||
E:SetTemplate(rchattb, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
rchattb:SetScript("OnEnter", ChatButton_OnEnter)
|
||||
rchattb:SetScript("OnLeave", ChatButton_OnLeave)
|
||||
rchattb:SetScript("OnClick", ChatButton_OnClick)
|
||||
rchattb.text = rchattb:CreateFontString(nil, "OVERLAY")
|
||||
E:FontTemplate(rchattb.text)
|
||||
rchattb.text:SetPoint("CENTER", rchattb)
|
||||
rchattb.text:SetJustifyH("CENTER")
|
||||
rchattb.text:SetText(">")
|
||||
|
||||
--Load Settings
|
||||
if E.db["LeftChatPanelFaded"] then
|
||||
LeftChatToggleButton:SetAlpha(0)
|
||||
LeftChatPanel:Hide()
|
||||
end
|
||||
|
||||
if E.db["RightChatPanelFaded"] then
|
||||
RightChatToggleButton:SetAlpha(0)
|
||||
RightChatPanel:Hide()
|
||||
end
|
||||
|
||||
self:ToggleChatPanels()
|
||||
end
|
||||
|
||||
function LO:CreateMinimapPanels()
|
||||
local lminipanel = CreateFrame("Frame", "LeftMiniPanel", Minimap.backdrop)
|
||||
lminipanel:SetWidth(E.db.general.minimap.size/2 + (E.PixelMode and 1 or 3))
|
||||
lminipanel:SetHeight(PANEL_HEIGHT)
|
||||
lminipanel:SetPoint("TOPLEFT", Minimap, "BOTTOMLEFT", -E.Border, (E.PixelMode and 0 or -3))
|
||||
E:SetTemplate(lminipanel, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
E:GetModule("DataTexts"):RegisterPanel(lminipanel, 1, "ANCHOR_BOTTOMLEFT", lminipanel:GetWidth() * 2, -(E.PixelMode and 1 or 3))
|
||||
|
||||
local rminipanel = CreateFrame("Frame", "RightMiniPanel", Minimap.backdrop)
|
||||
rminipanel:SetWidth(E.db.general.minimap.size/2 + (E.PixelMode and 1 or 3))
|
||||
rminipanel:SetHeight(PANEL_HEIGHT)
|
||||
rminipanel:SetPoint("TOPRIGHT", Minimap, "BOTTOMRIGHT", E.Border, (E.PixelMode and 0 or -3))
|
||||
E:SetTemplate(rminipanel, E.db.datatexts.panelTransparency and "Transparent" or "Default", true)
|
||||
E:GetModule("DataTexts"):RegisterPanel(rminipanel, 1, "ANCHOR_BOTTOM", 0, -(E.PixelMode and 1 or 3))
|
||||
|
||||
if E.db.datatexts.minimapPanels then
|
||||
LeftMiniPanel:Show()
|
||||
RightMiniPanel:Show()
|
||||
else
|
||||
LeftMiniPanel:Hide()
|
||||
RightMiniPanel:Hide()
|
||||
end
|
||||
|
||||
local f = CreateFrame("Frame", "BottomMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("BOTTOM", Minimap, "BOTTOM")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOM", 0, -10)
|
||||
|
||||
f = CreateFrame("Frame", "TopMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("TOP", Minimap, "TOP")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOM", 0, -10)
|
||||
|
||||
f = CreateFrame("Frame", "TopLeftMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("TOPLEFT", Minimap, "TOPLEFT")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOMLEFT", 0, -10)
|
||||
|
||||
f = CreateFrame("Frame", "TopRightMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("TOPRIGHT", Minimap, "TOPRIGHT")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOMRIGHT", 0, -10)
|
||||
|
||||
f = CreateFrame("Frame", "BottomLeftMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("BOTTOMLEFT", Minimap, "BOTTOMLEFT")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOMLEFT", 0, -10)
|
||||
|
||||
f = CreateFrame("Frame", "BottomRightMiniPanel", Minimap.backdrop)
|
||||
f:SetPoint("BOTTOMRIGHT", Minimap, "BOTTOMRIGHT")
|
||||
f:SetWidth(75)
|
||||
f:SetHeight(20)
|
||||
E:GetModule("DataTexts"):RegisterPanel(f, 1, "ANCHOR_BOTTOMRIGHT", 0, -10)
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
LO:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(LO:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Layout.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,674 @@
|
||||
--- **AceAddon-3.0** provides a template for creating addon objects.
|
||||
-- It'll provide you with a set of callback functions that allow you to simplify the loading
|
||||
-- process of your addon.\\
|
||||
-- Callbacks provided are:\\
|
||||
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
|
||||
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
|
||||
-- * **OnDisable**, which is only called when your addon is manually being disabled.
|
||||
-- @usage
|
||||
-- -- A small (but complete) addon, that doesn't do anything,
|
||||
-- -- but shows usage of the callbacks.
|
||||
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
|
||||
--
|
||||
-- function MyAddon:OnInitialize()
|
||||
-- -- do init tasks here, like loading the Saved Variables,
|
||||
-- -- or setting up slash commands.
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- -- Do more initialization here, that really enables the use of your addon.
|
||||
-- -- Register Events, Hook functions, Create Frames, Get information from
|
||||
-- -- the game that wasn't available in OnInitialize
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:OnDisable()
|
||||
-- -- Unhook, Unregister Events, Hide frames that you created.
|
||||
-- -- You would probably only use an OnDisable if you want to
|
||||
-- -- build a "standby" mode, or be able to toggle modules on/off.
|
||||
-- end
|
||||
-- @class file
|
||||
-- @name AceAddon-3.0.lua
|
||||
-- @release $Id: AceAddon-3.0.lua 1084 2013-04-27 20:14:11Z nevcairiel $
|
||||
|
||||
local MAJOR, MINOR = "AceAddon-3.0", 12
|
||||
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceAddon then return end -- No Upgrade needed.
|
||||
|
||||
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
|
||||
AceAddon.addons = AceAddon.addons or {} -- addons in general
|
||||
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
|
||||
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
|
||||
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
|
||||
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
|
||||
local getn, tinsert, tconcat, tremove = table.getn, table.insert, table.concat, table.remove
|
||||
local fmt, tostring = string.format, tostring
|
||||
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
|
||||
local loadstring, assert, error = loadstring, assert, error
|
||||
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
|
||||
|
||||
--[[
|
||||
xpcall safecall implementation
|
||||
]]
|
||||
local xpcall = xpcall
|
||||
|
||||
local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
local xpcall, eh = arg1, arg2
|
||||
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, eh)
|
||||
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 Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
|
||||
|
||||
-- used in the addon metatable
|
||||
local function addontostring( self ) return self.name end
|
||||
|
||||
-- Check if the addon is queued for initialization
|
||||
local function queuedForInitialization(addon)
|
||||
for i = 1, getn(AceAddon.initializequeue) do
|
||||
if AceAddon.initializequeue[i] == addon then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Create a new AceAddon-3.0 addon.
|
||||
-- Any libraries you specified will be embeded, and the addon will be scheduled for
|
||||
-- its OnInitialize and OnEnable callbacks.
|
||||
-- The final addon object, with all libraries embeded, will be returned.
|
||||
-- @paramsig [object ,]name[, lib, ...]
|
||||
-- @param object Table to use as a base for the addon (optional)
|
||||
-- @param name Name of the addon object to create
|
||||
-- @param lib List of libraries to embed into the addon
|
||||
-- @usage
|
||||
-- -- Create a simple addon object
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
|
||||
--
|
||||
-- -- Create a Addon object based on the table of a frame
|
||||
-- local MyFrame = CreateFrame("Frame")
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
|
||||
function AceAddon:NewAddon(objectorname, ...)
|
||||
local object,name
|
||||
local i=1
|
||||
if type(objectorname)=="table" then
|
||||
object=objectorname
|
||||
name=unpack(arg)
|
||||
i=2
|
||||
else
|
||||
name=objectorname
|
||||
end
|
||||
|
||||
if type(name)~="string" then
|
||||
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
|
||||
end
|
||||
if self.addons[name] then
|
||||
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
|
||||
end
|
||||
|
||||
object = object or {}
|
||||
object.name = name
|
||||
|
||||
local addonmeta = {}
|
||||
local oldmeta = getmetatable(object)
|
||||
if oldmeta then
|
||||
for k, v in pairs(oldmeta) do addonmeta[k] = v end
|
||||
end
|
||||
addonmeta.__tostring = addontostring
|
||||
|
||||
setmetatable( object, addonmeta )
|
||||
self.addons[name] = object
|
||||
object.modules = {}
|
||||
object.orderedModules = {}
|
||||
object.defaultModuleLibraries = {}
|
||||
Embed( object ) -- embed NewModule, GetModule methods
|
||||
self:EmbedLibraries(object, unpack(arg))
|
||||
|
||||
-- add to queue of addons to be initialized upon ADDON_LOADED
|
||||
tinsert(self.initializequeue, object)
|
||||
return object
|
||||
end
|
||||
|
||||
|
||||
--- 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).
|
||||
-- @param name unique name of the addon object
|
||||
-- @param silent if true, the addon is optional, silently return nil if its not found
|
||||
-- @usage
|
||||
-- -- Get the Addon
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
function AceAddon:GetAddon(name, silent)
|
||||
if not silent and not self.addons[name] then
|
||||
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
|
||||
end
|
||||
return self.addons[name]
|
||||
end
|
||||
|
||||
-- - Embed a list of libraries into the specified addon.
|
||||
-- This function will try to embed all of the listed libraries into the addon
|
||||
-- and error if a single one fails.
|
||||
--
|
||||
-- **Note:** This function is for internal use by :NewAddon/:NewModule
|
||||
-- @paramsig addon, [lib, ...]
|
||||
-- @param addon addon object to embed the libs in
|
||||
-- @param lib List of libraries to embed into the addon
|
||||
function AceAddon:EmbedLibraries(addon, ...)
|
||||
for i=1, getn(arg) do
|
||||
local libname = arg[i]
|
||||
self:EmbedLibrary(addon, libname, false, 4)
|
||||
end
|
||||
end
|
||||
|
||||
-- - Embed a library into the addon object.
|
||||
-- This function will check if the specified library is registered with LibStub
|
||||
-- and if it has a :Embed function to call. It'll error if any of those conditions
|
||||
-- fails.
|
||||
--
|
||||
-- **Note:** This function is for internal use by :EmbedLibraries
|
||||
-- @paramsig addon, libname[, silent[, offset]]
|
||||
-- @param addon addon object to embed the library in
|
||||
-- @param libname name of the library to embed
|
||||
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
|
||||
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
|
||||
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
|
||||
local lib = LibStub:GetLibrary(libname, true)
|
||||
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)
|
||||
elseif lib and type(lib.Embed) == "function" then
|
||||
lib:Embed(addon)
|
||||
tinsert(self.embeds[addon], libname)
|
||||
return true
|
||||
elseif lib then
|
||||
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
|
||||
end
|
||||
end
|
||||
|
||||
--- Return the specified module from an addon object.
|
||||
-- Throws an error if the addon object cannot be found (except if silent is set)
|
||||
-- @name //addon//:GetModule
|
||||
-- @paramsig name[, silent]
|
||||
-- @param name unique name of the module
|
||||
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
|
||||
-- @usage
|
||||
-- -- Get the Addon
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- -- Get the Module
|
||||
-- MyModule = MyAddon:GetModule("MyModule")
|
||||
function GetModule(self, name, silent)
|
||||
if not self.modules[name] and not silent then
|
||||
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
|
||||
end
|
||||
return self.modules[name]
|
||||
end
|
||||
|
||||
local function IsModuleTrue(self) return true end
|
||||
|
||||
--- Create a new module for the addon.
|
||||
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
|
||||
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
|
||||
-- an addon object.
|
||||
-- @name //addon//:NewModule
|
||||
-- @paramsig name[, prototype|lib[, lib, ...]]
|
||||
-- @param name unique name of the module
|
||||
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
|
||||
-- @param lib List of libraries to embed into the addon
|
||||
-- @usage
|
||||
-- -- Create a module with some embeded libraries
|
||||
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
|
||||
--
|
||||
-- -- Create a module with a prototype
|
||||
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
|
||||
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
|
||||
function NewModule(self, name, prototype, ...)
|
||||
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(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 self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
|
||||
|
||||
-- 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.
|
||||
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
|
||||
|
||||
module.IsModule = IsModuleTrue
|
||||
module:SetEnabledState(self.defaultModuleState)
|
||||
module.moduleName = name
|
||||
|
||||
if type(prototype) == "string" then
|
||||
AceAddon:EmbedLibraries(module, prototype, unpack(arg))
|
||||
else
|
||||
AceAddon:EmbedLibraries(module, unpack(arg))
|
||||
end
|
||||
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
|
||||
|
||||
if not prototype or type(prototype) == "string" then
|
||||
prototype = self.defaultModulePrototype or nil
|
||||
end
|
||||
|
||||
if type(prototype) == "table" then
|
||||
local mt = getmetatable(module)
|
||||
mt.__index = prototype
|
||||
setmetatable(module, mt) -- More of a Base class type feel.
|
||||
end
|
||||
|
||||
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
|
||||
self.modules[name] = module
|
||||
tinsert(self.orderedModules, module)
|
||||
|
||||
return module
|
||||
end
|
||||
|
||||
--- Returns the real name of the addon or module, without any prefix.
|
||||
-- @name //addon//:GetName
|
||||
-- @paramsig
|
||||
-- @usage
|
||||
-- print(MyAddon:GetName())
|
||||
-- -- prints "MyAddon"
|
||||
function GetName(self)
|
||||
return self.moduleName or self.name
|
||||
end
|
||||
|
||||
--- Enables the Addon, if possible, return true or false depending on success.
|
||||
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
|
||||
-- and enabling all modules of the addon (unless explicitly disabled).\\
|
||||
-- :Enable() also sets the internal `enableState` variable to true
|
||||
-- @name //addon//:Enable
|
||||
-- @paramsig
|
||||
-- @usage
|
||||
-- -- Enable MyModule
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyModule = MyAddon:GetModule("MyModule")
|
||||
-- MyModule:Enable()
|
||||
function Enable(self)
|
||||
self:SetEnabledState(true)
|
||||
|
||||
-- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still
|
||||
-- it'll be enabled after the init process
|
||||
if not queuedForInitialization(self) then
|
||||
return AceAddon:EnableAddon(self)
|
||||
end
|
||||
end
|
||||
|
||||
--- Disables the Addon, if possible, return true or false depending on success.
|
||||
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
|
||||
-- and disabling all modules of the addon.\\
|
||||
-- :Disable() also sets the internal `enableState` variable to false
|
||||
-- @name //addon//:Disable
|
||||
-- @paramsig
|
||||
-- @usage
|
||||
-- -- Disable MyAddon
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyAddon:Disable()
|
||||
function Disable(self)
|
||||
self:SetEnabledState(false)
|
||||
return AceAddon:DisableAddon(self)
|
||||
end
|
||||
|
||||
--- Enables the Module, if possible, return true or false depending on success.
|
||||
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
|
||||
-- @name //addon//:EnableModule
|
||||
-- @paramsig name
|
||||
-- @usage
|
||||
-- -- Enable MyModule using :GetModule
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyModule = MyAddon:GetModule("MyModule")
|
||||
-- MyModule:Enable()
|
||||
--
|
||||
-- -- Enable MyModule using the short-hand
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyAddon:EnableModule("MyModule")
|
||||
function EnableModule(self, name)
|
||||
local module = self:GetModule( name )
|
||||
return module:Enable()
|
||||
end
|
||||
|
||||
--- Disables the Module, if possible, return true or false depending on success.
|
||||
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
|
||||
-- @name //addon//:DisableModule
|
||||
-- @paramsig name
|
||||
-- @usage
|
||||
-- -- Disable MyModule using :GetModule
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyModule = MyAddon:GetModule("MyModule")
|
||||
-- MyModule:Disable()
|
||||
--
|
||||
-- -- Disable MyModule using the short-hand
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
|
||||
-- MyAddon:DisableModule("MyModule")
|
||||
function DisableModule(self, name)
|
||||
local module = self:GetModule( name )
|
||||
return module:Disable()
|
||||
end
|
||||
|
||||
--- Set the default libraries to be mixed into all modules created by this object.
|
||||
-- Note that you can only change the default module libraries before any module is created.
|
||||
-- @name //addon//:SetDefaultModuleLibraries
|
||||
-- @paramsig lib[, lib, ...]
|
||||
-- @param lib List of libraries to embed into the addon
|
||||
-- @usage
|
||||
-- -- Create the addon object
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
|
||||
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
|
||||
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
|
||||
-- -- Create a module
|
||||
-- MyModule = MyAddon:NewModule("MyModule")
|
||||
function SetDefaultModuleLibraries(self, ...)
|
||||
if next(self.modules) then
|
||||
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
|
||||
end
|
||||
self.defaultModuleLibraries = {unpack(arg)}
|
||||
end
|
||||
|
||||
--- Set the default state in which new modules are being created.
|
||||
-- Note that you can only change the default state before any module is created.
|
||||
-- @name //addon//:SetDefaultModuleState
|
||||
-- @paramsig state
|
||||
-- @param state Default state for new modules, true for enabled, false for disabled
|
||||
-- @usage
|
||||
-- -- Create the addon object
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
|
||||
-- -- Set the default state to "disabled"
|
||||
-- MyAddon:SetDefaultModuleState(false)
|
||||
-- -- Create a module and explicilty enable it
|
||||
-- MyModule = MyAddon:NewModule("MyModule")
|
||||
-- MyModule:Enable()
|
||||
function SetDefaultModuleState(self, state)
|
||||
if next(self.modules) then
|
||||
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
|
||||
end
|
||||
self.defaultModuleState = state
|
||||
end
|
||||
|
||||
--- Set the default prototype to use for new modules on creation.
|
||||
-- Note that you can only change the default prototype before any module is created.
|
||||
-- @name //addon//:SetDefaultModulePrototype
|
||||
-- @paramsig prototype
|
||||
-- @param prototype Default prototype for the new modules (table)
|
||||
-- @usage
|
||||
-- -- Define a prototype
|
||||
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
|
||||
-- -- Set the default prototype
|
||||
-- MyAddon:SetDefaultModulePrototype(prototype)
|
||||
-- -- Create a module and explicitly Enable it
|
||||
-- MyModule = MyAddon:NewModule("MyModule")
|
||||
-- MyModule:Enable()
|
||||
-- -- should print "OnEnable called!" now
|
||||
-- @see NewModule
|
||||
function SetDefaultModulePrototype(self, prototype)
|
||||
if next(self.modules) then
|
||||
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
|
||||
end
|
||||
if type(prototype) ~= "table" then
|
||||
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
|
||||
end
|
||||
self.defaultModulePrototype = prototype
|
||||
end
|
||||
|
||||
--- Set the state of an addon or module
|
||||
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
|
||||
-- @name //addon//:SetEnabledState
|
||||
-- @paramsig state
|
||||
-- @param state the state of an addon or module (enabled=true, disabled=false)
|
||||
function SetEnabledState(self, state)
|
||||
self.enabledState = state
|
||||
end
|
||||
|
||||
|
||||
--- Return an iterator of all modules associated to the addon.
|
||||
-- @name //addon//:IterateModules
|
||||
-- @paramsig
|
||||
-- @usage
|
||||
-- -- Enable all modules
|
||||
-- for name, module in MyAddon:IterateModules() do
|
||||
-- module:Enable()
|
||||
-- end
|
||||
local function IterateModules(self) return pairs(self.modules) end
|
||||
|
||||
-- Returns an iterator of all embeds in the addon
|
||||
-- @name //addon//:IterateEmbeds
|
||||
-- @paramsig
|
||||
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
|
||||
|
||||
--- Query the enabledState of an addon.
|
||||
-- @name //addon//:IsEnabled
|
||||
-- @paramsig
|
||||
-- @usage
|
||||
-- if MyAddon:IsEnabled() then
|
||||
-- MyAddon:Disable()
|
||||
-- end
|
||||
local function IsEnabled(self) return self.enabledState end
|
||||
local mixins = {
|
||||
NewModule = NewModule,
|
||||
GetModule = GetModule,
|
||||
Enable = Enable,
|
||||
Disable = Disable,
|
||||
EnableModule = EnableModule,
|
||||
DisableModule = DisableModule,
|
||||
IsEnabled = IsEnabled,
|
||||
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
|
||||
SetDefaultModuleState = SetDefaultModuleState,
|
||||
SetDefaultModulePrototype = SetDefaultModulePrototype,
|
||||
SetEnabledState = SetEnabledState,
|
||||
IterateModules = IterateModules,
|
||||
IterateEmbeds = IterateEmbeds,
|
||||
GetName = GetName,
|
||||
}
|
||||
local function IsModule(self) return false end
|
||||
local pmixins = {
|
||||
defaultModuleState = true,
|
||||
enabledState = true,
|
||||
IsModule = IsModule,
|
||||
}
|
||||
-- Embed( target )
|
||||
-- target (object) - target object to embed aceaddon in
|
||||
--
|
||||
-- this is a local function specifically since it's meant to be only called internally
|
||||
function Embed(target, skipPMixins)
|
||||
for k, v in pairs(mixins) do
|
||||
target[k] = v
|
||||
end
|
||||
if not skipPMixins then
|
||||
for k, v in pairs(pmixins) do
|
||||
target[k] = target[k] or v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- - Initialize the addon after creation.
|
||||
-- This function is only used internally during the ADDON_LOADED event
|
||||
-- It will call the **OnInitialize** function on the addon object (if present),
|
||||
-- and the **OnEmbedInitialize** function on all embeded libraries.
|
||||
--
|
||||
-- **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
|
||||
function AceAddon:InitializeAddon(addon)
|
||||
safecall(addon.OnInitialize, addon)
|
||||
|
||||
local embeds = self.embeds[addon]
|
||||
for i = 1, getn(embeds) do
|
||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||
--if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
|
||||
end
|
||||
|
||||
-- we don't call InitializeAddon on modules specifically, this is handled
|
||||
-- from the event handler and only done _once_
|
||||
end
|
||||
|
||||
-- - Enable the addon after creation.
|
||||
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
|
||||
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
|
||||
-- It will call the **OnEnable** function on the addon object (if present),
|
||||
-- and the **OnEmbedEnable** function on all embeded libraries.\\
|
||||
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
|
||||
--
|
||||
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
|
||||
-- Use :Enable on the addon itself instead.
|
||||
-- @param addon addon object to enable
|
||||
function AceAddon:EnableAddon(addon)
|
||||
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
|
||||
if self.statuses[addon.name] or not addon.enabledState then return false end
|
||||
|
||||
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
|
||||
self.statuses[addon.name] = true
|
||||
|
||||
safecall(addon.OnEnable, addon)
|
||||
|
||||
-- make sure we're still enabled before continueing
|
||||
if self.statuses[addon.name] then
|
||||
local embeds = self.embeds[addon]
|
||||
for i = 1, getn(embeds) do
|
||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
|
||||
end
|
||||
|
||||
-- enable possible modules.
|
||||
local modules = addon.orderedModules
|
||||
for i = 1, getn(modules) do
|
||||
self:EnableAddon(modules[i])
|
||||
end
|
||||
end
|
||||
return self.statuses[addon.name] -- return true if we're disabled
|
||||
end
|
||||
|
||||
-- - Disable the addon
|
||||
-- Note: This function is only used internally.
|
||||
-- It will call the **OnDisable** function on the addon object (if present),
|
||||
-- and the **OnEmbedDisable** function on all embeded libraries.\\
|
||||
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
|
||||
--
|
||||
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
|
||||
-- Use :Disable on the addon itself instead.
|
||||
-- @param addon addon object to enable
|
||||
function AceAddon:DisableAddon(addon)
|
||||
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
|
||||
if not self.statuses[addon.name] then return false end
|
||||
|
||||
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
|
||||
self.statuses[addon.name] = false
|
||||
|
||||
safecall( addon.OnDisable, addon )
|
||||
|
||||
-- make sure we're still disabling...
|
||||
if not self.statuses[addon.name] then
|
||||
local embeds = self.embeds[addon]
|
||||
for i = 1, getn(embeds) do
|
||||
local lib = LibStub:GetLibrary(embeds[i], true)
|
||||
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
|
||||
end
|
||||
-- disable possible modules.
|
||||
local modules = addon.orderedModules
|
||||
for i = 1, getn(modules) do
|
||||
self:DisableAddon(modules[i])
|
||||
end
|
||||
end
|
||||
|
||||
return not self.statuses[addon.name] -- return true if we're disabled
|
||||
end
|
||||
|
||||
--- Get an iterator over all registered addons.
|
||||
-- @usage
|
||||
-- -- Print a list of all installed AceAddon's
|
||||
-- for name, addon in AceAddon:IterateAddons() do
|
||||
-- print("Addon: " .. name)
|
||||
-- end
|
||||
function AceAddon:IterateAddons() return pairs(self.addons) end
|
||||
|
||||
--- Get an iterator over the internal status registry.
|
||||
-- @usage
|
||||
-- -- Print a list of all enabled addons
|
||||
-- for name, status in AceAddon:IterateAddonStatus() do
|
||||
-- if status then
|
||||
-- print("EnabledAddon: " .. name)
|
||||
-- end
|
||||
-- end
|
||||
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
|
||||
|
||||
-- Following Iterators are deprecated, and their addon specific versions should be used
|
||||
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
|
||||
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
|
||||
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
|
||||
|
||||
local IsLoggedIn
|
||||
-- Event Handling
|
||||
local function onEvent()
|
||||
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
|
||||
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
|
||||
while(getn(AceAddon.initializequeue) > 0) do
|
||||
local addon = tremove(AceAddon.initializequeue, 1)
|
||||
-- this might be an issue with recursion - TODO: validate
|
||||
if event == "ADDON_LOADED" then addon.baseName = arg1 end
|
||||
AceAddon:InitializeAddon(addon)
|
||||
tinsert(AceAddon.enablequeue, addon)
|
||||
end
|
||||
|
||||
if event == "PLAYER_LOGIN" then
|
||||
IsLoggedIn = true
|
||||
end
|
||||
|
||||
if IsLoggedIn then
|
||||
while(getn(AceAddon.enablequeue) > 0) do
|
||||
local addon = tremove(AceAddon.enablequeue, 1)
|
||||
AceAddon:EnableAddon(addon)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AceAddon.frame:RegisterEvent("ADDON_LOADED")
|
||||
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
|
||||
AceAddon.frame:SetScript("OnEvent", onEvent)
|
||||
|
||||
-- upgrade embeded
|
||||
for name, addon in pairs(AceAddon.addons) do
|
||||
Embed(addon, true)
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceAddon-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,306 @@
|
||||
--- **AceComm-3.0** allows you to send messages of unlimited length over the addon comm channels.
|
||||
-- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
|
||||
-- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
|
||||
--
|
||||
-- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
|
||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||
-- and can be accessed directly, without having to explicitly call AceComm itself.\\
|
||||
-- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceComm.
|
||||
-- @class file
|
||||
-- @name AceComm-3.0
|
||||
-- @release $Id: AceComm-3.0.lua 1107 2014-02-19 16:40:32Z nevcairiel $
|
||||
|
||||
--[[ AceComm-3.0
|
||||
|
||||
TODO: Time out old data rotting around from dead senders? Not a HUGE deal since the number of possible sender names is somewhat limited.
|
||||
|
||||
]]
|
||||
|
||||
local MAJOR, MINOR = "AceComm-3.0", 9
|
||||
|
||||
local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceComm then return end
|
||||
|
||||
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||
local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
|
||||
|
||||
-- Lua APIs
|
||||
local type, next, pairs, tostring = type, next, pairs, tostring
|
||||
local strlen, strsub, strfind = string.len, string.sub, string.find
|
||||
local tinsert, tconcat, tgetn, tremove = table.insert, table.concat, table.getn, table.remove
|
||||
local error, assert = error, assert
|
||||
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: LibStub, DEFAULT_CHAT_FRAME, geterrorhandler, RegisterAddonMessagePrefix
|
||||
|
||||
AceComm.embeds = AceComm.embeds or {}
|
||||
|
||||
-- for my sanity and yours, let's give the message type bytes some names
|
||||
local MSG_MULTI_FIRST = "\001"
|
||||
local MSG_MULTI_NEXT = "\002"
|
||||
local MSG_MULTI_LAST = "\003"
|
||||
local MSG_ESCAPE = "\004"
|
||||
|
||||
-- remove old structures (pre WoW 4.0)
|
||||
AceComm.multipart_origprefixes = nil
|
||||
AceComm.multipart_reassemblers = nil
|
||||
|
||||
-- the multipart message spool: indexed by a combination of sender+distribution+
|
||||
AceComm.multipart_spool = AceComm.multipart_spool or {}
|
||||
|
||||
--- Register for Addon Traffic on a specified prefix
|
||||
-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
|
||||
-- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
|
||||
function AceComm:RegisterComm(prefix, method)
|
||||
if method == nil then
|
||||
method = "OnCommReceived"
|
||||
end
|
||||
|
||||
if strlen(prefix) > 16 then -- TODO: 15?
|
||||
error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
|
||||
end
|
||||
|
||||
return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
|
||||
end
|
||||
|
||||
local warnedPrefix=false
|
||||
|
||||
--- Send a message over the Addon Channel
|
||||
-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
|
||||
-- @param text Data to send, nils (\000) not allowed. Any length.
|
||||
-- @param distribution Addon channel, e.g. "RAID", "GUILD", etc; see SendAddonMessage API
|
||||
-- @param target Destination for some distributions; see SendAddonMessage API
|
||||
-- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL".
|
||||
-- @param callbackFn OPTIONAL: callback function to be called as each chunk is sent. receives 3 args: the user supplied arg (see next), the number of bytes sent so far, and the number of bytes total to send.
|
||||
-- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified.
|
||||
function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callbackFn, callbackArg)
|
||||
prio = prio or "NORMAL" -- pasta's reference implementation had different prio for singlepart and multipart, but that's a very bad idea since that can easily lead to out-of-sequence delivery!
|
||||
if not( type(prefix)=="string" and
|
||||
type(text)=="string" and
|
||||
type(distribution)=="string" and
|
||||
(target==nil or type(target)=="string") and
|
||||
(prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
|
||||
) then
|
||||
error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
|
||||
end
|
||||
|
||||
local textlen = strlen(text)
|
||||
-- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
|
||||
-- Ace3v: substract the prefix length
|
||||
local maxtextlen = 254 - strlen(prefix)
|
||||
local queueName = prefix..distribution..(target or "")
|
||||
|
||||
local ctlCallback = nil
|
||||
if callbackFn then
|
||||
ctlCallback = function(sent)
|
||||
return callbackFn(callbackArg, sent, textlen)
|
||||
end
|
||||
end
|
||||
|
||||
local forceMultipart
|
||||
if strfind(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
|
||||
-- we need to escape the first character with a \004
|
||||
if textlen+1 > maxtextlen then -- would we go over the size limit?
|
||||
forceMultipart = true -- just make it multipart, no escape problems then
|
||||
else
|
||||
text = "\004" .. text
|
||||
end
|
||||
end
|
||||
|
||||
if not forceMultipart and textlen <= maxtextlen then
|
||||
-- fits all in one message
|
||||
CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
|
||||
else
|
||||
maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
|
||||
|
||||
-- first part
|
||||
local chunk = strsub(text, 1, maxtextlen)
|
||||
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
|
||||
|
||||
-- continuation
|
||||
local pos = 1+maxtextlen
|
||||
|
||||
while pos+maxtextlen <= textlen do
|
||||
chunk = strsub(text, pos, pos+maxtextlen-1)
|
||||
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
|
||||
pos = pos + maxtextlen
|
||||
end
|
||||
|
||||
-- final part
|
||||
chunk = strsub(text, pos)
|
||||
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------
|
||||
-- Message receiving
|
||||
----------------------------------------
|
||||
|
||||
do
|
||||
local compost = setmetatable({}, {__mode = "k"})
|
||||
local function new()
|
||||
local t = next(compost)
|
||||
if t then
|
||||
compost[t]=nil
|
||||
for i=tgetn(t),3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
|
||||
tremove(t) -- Ace3v: t[i] = nil wont affect the tgetn return value
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
return {}
|
||||
end
|
||||
|
||||
local function lostdatawarning(prefix,sender,where)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
|
||||
end
|
||||
|
||||
function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
|
||||
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
|
||||
local spool = AceComm.multipart_spool
|
||||
|
||||
--[[
|
||||
if spool[key] then
|
||||
lostdatawarning(prefix,sender,"First")
|
||||
-- continue and overwrite
|
||||
end
|
||||
--]]
|
||||
|
||||
spool[key] = message -- plain string for now
|
||||
end
|
||||
|
||||
function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender)
|
||||
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
|
||||
local spool = AceComm.multipart_spool
|
||||
local olddata = spool[key]
|
||||
|
||||
if not olddata then
|
||||
--lostdatawarning(prefix,sender,"Next")
|
||||
return
|
||||
end
|
||||
|
||||
if type(olddata)~="table" then
|
||||
-- ... but what we have is not a table. So make it one. (Pull a composted one if available)
|
||||
local t = new()
|
||||
t[1] = olddata -- add old data as first string
|
||||
t[2] = message -- and new message as second string
|
||||
spool[key] = t -- and put the table in the spool instead of the old string
|
||||
else
|
||||
tinsert(olddata, message)
|
||||
end
|
||||
end
|
||||
|
||||
function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender)
|
||||
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
|
||||
local spool = AceComm.multipart_spool
|
||||
local olddata = spool[key]
|
||||
|
||||
if not olddata then
|
||||
--lostdatawarning(prefix,sender,"End")
|
||||
return
|
||||
end
|
||||
|
||||
spool[key] = nil
|
||||
|
||||
if type(olddata) == "table" then
|
||||
-- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
|
||||
tinsert(olddata, message)
|
||||
AceComm.callbacks:Fire(prefix, 3, tconcat(olddata, ""), distribution, sender)
|
||||
compost[olddata] = true
|
||||
else
|
||||
-- if we've only received a "first", the spooled data will still only be a string
|
||||
AceComm.callbacks:Fire(prefix, 3, olddata..message, distribution, sender)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------
|
||||
-- Embed CallbackHandler
|
||||
----------------------------------------
|
||||
|
||||
if not AceComm.callbacks then
|
||||
AceComm.callbacks = CallbackHandler:New(AceComm,
|
||||
"_RegisterComm",
|
||||
"UnregisterComm",
|
||||
"UnregisterAllComm")
|
||||
end
|
||||
|
||||
AceComm.callbacks.OnUsed = nil
|
||||
AceComm.callbacks.OnUnused = nil
|
||||
|
||||
-- Ace3v: in vanilla, global vars:
|
||||
-- event -> event type
|
||||
-- arg1 -> prefix
|
||||
-- arg2 -> message
|
||||
-- arg3 -> channel
|
||||
-- arg4 -> sender
|
||||
local function OnEvent()
|
||||
local prefix, message, distribution, sender = arg1, arg2, arg3, arg4
|
||||
if event == "CHAT_MSG_ADDON" then
|
||||
local _, _, control, rest = strfind(message, "^([\001-\009])(.*)")
|
||||
if control then
|
||||
if control==MSG_MULTI_FIRST then
|
||||
AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
|
||||
elseif control==MSG_MULTI_NEXT then
|
||||
AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
|
||||
elseif control==MSG_MULTI_LAST then
|
||||
AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
|
||||
elseif control==MSG_ESCAPE then
|
||||
AceComm.callbacks:Fire(prefix, 3, rest, distribution, sender)
|
||||
else
|
||||
-- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
|
||||
end
|
||||
else
|
||||
-- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
|
||||
AceComm.callbacks:Fire(prefix, 3, message, distribution, sender)
|
||||
end
|
||||
else
|
||||
assert(false, "Received "..tostring(event).." event?!")
|
||||
end
|
||||
end
|
||||
|
||||
AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame")
|
||||
AceComm.frame:SetScript("OnEvent", OnEvent)
|
||||
AceComm.frame:UnregisterAllEvents()
|
||||
AceComm.frame:RegisterEvent("CHAT_MSG_ADDON")
|
||||
|
||||
|
||||
----------------------------------------
|
||||
-- Base library stuff
|
||||
----------------------------------------
|
||||
|
||||
local mixins = {
|
||||
"RegisterComm",
|
||||
"UnregisterComm",
|
||||
"UnregisterAllComm",
|
||||
"SendCommMessage",
|
||||
}
|
||||
|
||||
-- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:..
|
||||
-- @param target target object to embed AceComm-3.0 in
|
||||
function AceComm:Embed(target)
|
||||
for k, v in pairs(mixins) do
|
||||
target[v] = self[v]
|
||||
end
|
||||
self.embeds[target] = true
|
||||
return target
|
||||
end
|
||||
|
||||
function AceComm:OnEmbedDisable(target)
|
||||
target:UnregisterAllComm()
|
||||
end
|
||||
|
||||
-- Update embeds
|
||||
for target, v in pairs(AceComm.embeds) do
|
||||
AceComm:Embed(target)
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="ChatThrottleLib.lua"/>
|
||||
<Script file="AceComm-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,527 @@
|
||||
--
|
||||
-- ChatThrottleLib by Mikk
|
||||
--
|
||||
-- Manages AddOn chat output to keep player from getting kicked off.
|
||||
--
|
||||
-- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
|
||||
-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
|
||||
--
|
||||
-- Priorities get an equal share of available bandwidth when fully loaded.
|
||||
-- Communication channels are separated on extension+chattype+destination and
|
||||
-- get round-robinned. (Destination only matters for whispers and channels,
|
||||
-- obviously)
|
||||
--
|
||||
-- Will install hooks for SendChatMessage and SendAddonMessage to measure
|
||||
-- bandwidth bypassing the library and use less bandwidth itself.
|
||||
--
|
||||
--
|
||||
-- Fully embeddable library. Just copy this file into your addon directory,
|
||||
-- add it to the .toc, and it's done.
|
||||
--
|
||||
-- Can run as a standalone addon also, but, really, just embed it! :-)
|
||||
--
|
||||
-- LICENSE: ChatThrottleLib is released into the Public Domain
|
||||
--
|
||||
|
||||
local CTL_VERSION = 23
|
||||
|
||||
local AceCore = LibStub("AceCore-3.0")
|
||||
local _G = AceCore._G
|
||||
local hooksecurefunc = AceCore.hooksecurefunc
|
||||
local wipe = AceCore.wipe
|
||||
|
||||
if _G.ChatThrottleLib then
|
||||
if _G.ChatThrottleLib.version >= CTL_VERSION then
|
||||
-- There's already a newer (or same) version loaded. Buh-bye.
|
||||
return
|
||||
elseif not _G.ChatThrottleLib.securelyHooked then
|
||||
print("ChatThrottleLib: Warning: There's an ANCIENT ChatThrottleLib.lua (pre-wow 2.0, <v16) in an addon somewhere. Get the addon updated or copy in a newer ChatThrottleLib.lua (>=v16) in it!")
|
||||
-- ATTEMPT to unhook; this'll behave badly if someone else has hooked...
|
||||
-- ... and if someone has securehooked, they can kiss that goodbye too... >.<
|
||||
_G.SendChatMessage = _G.ChatThrottleLib.ORIG_SendChatMessage
|
||||
if _G.ChatThrottleLib.ORIG_SendAddonMessage then
|
||||
_G.SendAddonMessage = _G.ChatThrottleLib.ORIG_SendAddonMessage
|
||||
end
|
||||
end
|
||||
_G.ChatThrottleLib.ORIG_SendChatMessage = nil
|
||||
_G.ChatThrottleLib.ORIG_SendAddonMessage = nil
|
||||
end
|
||||
|
||||
if not _G.ChatThrottleLib then
|
||||
_G.ChatThrottleLib = {}
|
||||
end
|
||||
|
||||
ChatThrottleLib = _G.ChatThrottleLib -- in case some addon does "local ChatThrottleLib" above us and we're copypasted (AceComm-2, sigh)
|
||||
local ChatThrottleLib = _G.ChatThrottleLib
|
||||
|
||||
ChatThrottleLib.version = CTL_VERSION
|
||||
|
||||
|
||||
|
||||
------------------ TWEAKABLES -----------------
|
||||
|
||||
ChatThrottleLib.MAX_CPS = 800 -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 800.
|
||||
ChatThrottleLib.MSG_OVERHEAD = 40 -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
|
||||
|
||||
ChatThrottleLib.BURST = 4000 -- WoW's server buffer seems to be about 32KB. 8KB should be safe, but seen disconnects on _some_ servers. Using 4KB now.
|
||||
|
||||
ChatThrottleLib.MIN_FPS = 20 -- Reduce output CPS to half (and don't burst) if FPS drops below this value
|
||||
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local table_remove = table.remove
|
||||
local tinsert = table.insert
|
||||
local tostring = tostring
|
||||
local GetTime = GetTime
|
||||
local math_min = math.min
|
||||
local math_max = math.max
|
||||
local next = next
|
||||
local strlen = string.len
|
||||
local GetFramerate = GetFramerate
|
||||
local strlower = string.lower
|
||||
local unpack,type,pairs,wipe = unpack,type,pairs,wipe
|
||||
local UnitInRaid,UnitInParty = UnitInRaid,UnitInParty
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Double-linked ring implementation
|
||||
|
||||
local Ring = {}
|
||||
local RingMeta = { __index = Ring }
|
||||
|
||||
function Ring:New()
|
||||
local ret = {}
|
||||
setmetatable(ret, RingMeta)
|
||||
return ret
|
||||
end
|
||||
|
||||
function Ring:Add(obj) -- Append at the "far end" of the ring (aka just before the current position)
|
||||
if self.pos then
|
||||
obj.prev = self.pos.prev
|
||||
obj.prev.next = obj
|
||||
obj.next = self.pos
|
||||
obj.next.prev = obj
|
||||
else
|
||||
obj.next = obj
|
||||
obj.prev = obj
|
||||
self.pos = obj
|
||||
end
|
||||
end
|
||||
|
||||
function Ring:Remove(obj)
|
||||
obj.next.prev = obj.prev
|
||||
obj.prev.next = obj.next
|
||||
if self.pos == obj then
|
||||
self.pos = obj.next
|
||||
if self.pos == obj then
|
||||
self.pos = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Recycling bin for pipes
|
||||
-- A pipe is a plain integer-indexed queue of messages
|
||||
-- Pipes normally live in Rings of pipes (3 rings total, one per priority)
|
||||
|
||||
ChatThrottleLib.PipeBin = nil -- pre-v19, drastically different
|
||||
local PipeBin = setmetatable({}, {__mode="k"})
|
||||
|
||||
local function DelPipe(pipe)
|
||||
PipeBin[pipe] = true
|
||||
end
|
||||
|
||||
local function NewPipe()
|
||||
local pipe = next(PipeBin)
|
||||
if pipe then
|
||||
wipe(pipe)
|
||||
PipeBin[pipe] = nil
|
||||
return pipe
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Recycling bin for messages
|
||||
|
||||
ChatThrottleLib.MsgBin = nil -- pre-v19, drastically different
|
||||
local MsgBin = setmetatable({}, {__mode="k"})
|
||||
|
||||
local function DelMsg(msg)
|
||||
msg[1] = nil
|
||||
-- there's more parameters, but they're very repetetive so the string pool doesn't suffer really, and it's faster to just not delete them.
|
||||
MsgBin[msg] = true
|
||||
end
|
||||
|
||||
local function NewMsg()
|
||||
local msg = next(MsgBin)
|
||||
if msg then
|
||||
MsgBin[msg] = nil
|
||||
return msg
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- ChatThrottleLib:Init
|
||||
-- Initialize queues, set up frame for OnUpdate, etc
|
||||
|
||||
|
||||
function ChatThrottleLib:Init()
|
||||
|
||||
-- Set up queues
|
||||
if not self.Prio then
|
||||
self.Prio = {}
|
||||
self.Prio["ALERT"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
|
||||
self.Prio["NORMAL"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
|
||||
self.Prio["BULK"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
|
||||
end
|
||||
|
||||
-- v4: total send counters per priority
|
||||
for _, Prio in pairs(self.Prio) do
|
||||
Prio.nTotalSent = Prio.nTotalSent or 0
|
||||
end
|
||||
|
||||
if not self.avail then
|
||||
self.avail = 0 -- v5
|
||||
end
|
||||
if not self.nTotalSent then
|
||||
self.nTotalSent = 0 -- v5
|
||||
end
|
||||
|
||||
|
||||
-- Set up a frame to get OnUpdate events
|
||||
if not self.Frame then
|
||||
self.Frame = CreateFrame("Frame")
|
||||
self.Frame:Hide()
|
||||
end
|
||||
self.Frame:SetScript("OnUpdate", self.OnUpdate)
|
||||
self.Frame:SetScript("OnEvent", self.OnEvent) -- v11: Monitor P_E_W so we can throttle hard for a few seconds
|
||||
self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
self.OnUpdateDelay = 0
|
||||
self.LastAvailUpdate = GetTime()
|
||||
self.HardThrottlingBeginTime = GetTime() -- v11: Throttle hard for a few seconds after startup
|
||||
|
||||
-- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
|
||||
if not self.securelyHooked then
|
||||
-- Use secure hooks as of v16. Old regular hook support yanked out in v21.
|
||||
self.securelyHooked = true
|
||||
--SendChatMessage
|
||||
hooksecurefunc("SendChatMessage", function(text, chattype, language, destination)
|
||||
return ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination)
|
||||
end)
|
||||
--SendAddonMessage
|
||||
hooksecurefunc("SendAddonMessage", function(prefix, text, chattype, destination)
|
||||
return ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination)
|
||||
end)
|
||||
end
|
||||
self.nBypass = 0
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
|
||||
|
||||
local bMyTraffic = false
|
||||
|
||||
function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination)
|
||||
if bMyTraffic then
|
||||
return
|
||||
end
|
||||
local self = ChatThrottleLib
|
||||
local size = strlen(tostring(text or "")) + strlen(tostring(destination or "")) + self.MSG_OVERHEAD
|
||||
self.avail = self.avail - size
|
||||
self.nBypass = self.nBypass + size -- just a statistic
|
||||
end
|
||||
function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination)
|
||||
if bMyTraffic then
|
||||
return
|
||||
end
|
||||
local self = ChatThrottleLib
|
||||
local size = strlen(tostring(text or "")) + strlen(tostring(prefix or ""));
|
||||
size = size + strlen(tostring(destination or "")) + self.MSG_OVERHEAD
|
||||
self.avail = self.avail - size
|
||||
self.nBypass = self.nBypass + size -- just a statistic
|
||||
end
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- ChatThrottleLib:UpdateAvail
|
||||
-- Update self.avail with how much bandwidth is currently available
|
||||
|
||||
function ChatThrottleLib:UpdateAvail()
|
||||
local now = GetTime()
|
||||
local MAX_CPS = self.MAX_CPS;
|
||||
local newavail = MAX_CPS * (now - self.LastAvailUpdate)
|
||||
local avail = self.avail
|
||||
|
||||
if now - self.HardThrottlingBeginTime < 5 then
|
||||
-- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
|
||||
avail = math_min(avail + (newavail*0.1), MAX_CPS*0.5)
|
||||
self.bChoking = true
|
||||
elseif GetFramerate() < self.MIN_FPS then -- GetFrameRate call takes ~0.002 secs
|
||||
avail = math_min(MAX_CPS, avail + newavail*0.5)
|
||||
self.bChoking = true -- just a statistic
|
||||
else
|
||||
avail = math_min(self.BURST, avail + newavail)
|
||||
self.bChoking = false
|
||||
end
|
||||
|
||||
avail = math_max(avail, 0-(MAX_CPS*2)) -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
|
||||
|
||||
self.avail = avail
|
||||
self.LastAvailUpdate = now
|
||||
|
||||
return avail
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Despooling logic
|
||||
-- Reminder:
|
||||
-- - We have 3 Priorities, each containing a "Ring" construct ...
|
||||
-- - ... made up of N "Pipe"s (1 for each destination/pipename)
|
||||
-- - and each pipe contains messages
|
||||
|
||||
function ChatThrottleLib:Despool(Prio)
|
||||
local ring = Prio.Ring
|
||||
while ring.pos and Prio.avail > ring.pos[1].nSize do
|
||||
local msg = table_remove(ring.pos, 1)
|
||||
if not ring.pos[1] then -- did we remove last msg in this pipe?
|
||||
local pipe = Prio.Ring.pos
|
||||
Prio.Ring:Remove(pipe)
|
||||
Prio.ByName[pipe.name] = nil
|
||||
DelPipe(pipe)
|
||||
else
|
||||
Prio.Ring.pos = Prio.Ring.pos.next
|
||||
end
|
||||
local didSend=false
|
||||
local lowerDest = strlower(msg[3] or "")
|
||||
if lowerDest == "raid" and not UnitInRaid("player") then
|
||||
-- do nothing
|
||||
elseif lowerDest == "party" and not UnitInParty("player") then
|
||||
-- do nothing
|
||||
else
|
||||
Prio.avail = Prio.avail - msg.nSize
|
||||
bMyTraffic = true
|
||||
msg.f(unpack(msg, 1, msg.n))
|
||||
bMyTraffic = false
|
||||
Prio.nTotalSent = Prio.nTotalSent + msg.nSize
|
||||
DelMsg(msg)
|
||||
didSend = true
|
||||
end
|
||||
-- notify caller of delivery (even if we didn't send it)
|
||||
if msg.callbackFn then
|
||||
msg.callbackFn (msg.callbackArg, didSend)
|
||||
end
|
||||
-- USER CALLBACK MAY ERROR
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ChatThrottleLib.OnEvent()
|
||||
-- v11: We know that the rate limiter is touchy after login. Assume that it's touchy after zoning, too.
|
||||
local self = ChatThrottleLib
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
self.HardThrottlingBeginTime = GetTime() -- Throttle hard for a few seconds after zoning
|
||||
self.avail = 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ChatThrottleLib.OnUpdate()
|
||||
local self = ChatThrottleLib
|
||||
|
||||
self.OnUpdateDelay = self.OnUpdateDelay + arg1
|
||||
if self.OnUpdateDelay < 0.08 then
|
||||
return
|
||||
end
|
||||
self.OnUpdateDelay = 0
|
||||
|
||||
self:UpdateAvail()
|
||||
|
||||
if self.avail < 0 then
|
||||
return -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
|
||||
end
|
||||
|
||||
-- See how many of our priorities have queued messages (we only have 3, don't worry about the loop)
|
||||
local n = 0
|
||||
for prioname,Prio in pairs(self.Prio) do
|
||||
if Prio.Ring.pos or Prio.avail < 0 then
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Anything queued still?
|
||||
if n<1 then
|
||||
-- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
|
||||
for prioname, Prio in pairs(self.Prio) do
|
||||
self.avail = self.avail + Prio.avail
|
||||
Prio.avail = 0
|
||||
end
|
||||
self.bQueueing = false
|
||||
self.Frame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
|
||||
local avail = self.avail/n
|
||||
self.avail = 0
|
||||
|
||||
for prioname, Prio in pairs(self.Prio) do
|
||||
if Prio.Ring.pos or Prio.avail < 0 then
|
||||
Prio.avail = Prio.avail + avail
|
||||
if Prio.Ring.pos and Prio.avail > Prio.Ring.pos[1].nSize then
|
||||
self:Despool(Prio)
|
||||
-- Note: We might not get here if the user-supplied callback function errors out! Take care!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Spooling logic
|
||||
|
||||
function ChatThrottleLib:Enqueue(prioname, pipename, msg)
|
||||
local Prio = self.Prio[prioname]
|
||||
local pipe = Prio.ByName[pipename]
|
||||
if not pipe then
|
||||
self.Frame:Show()
|
||||
pipe = NewPipe()
|
||||
pipe.name = pipename
|
||||
Prio.ByName[pipename] = pipe
|
||||
Prio.Ring:Add(pipe)
|
||||
end
|
||||
|
||||
tinsert(pipe,msg)
|
||||
|
||||
self.bQueueing = true
|
||||
end
|
||||
|
||||
function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName, callbackFn, callbackArg)
|
||||
if not self or not prio or not prefix or not text or not self.Prio[prio] then
|
||||
error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix", "text"[, "chattype"[, "language"[, "destination"]]]', 2)
|
||||
end
|
||||
if callbackFn and type(callbackFn)~="function" then
|
||||
error('ChatThrottleLib:ChatMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
|
||||
end
|
||||
|
||||
local nSize = strlen(text)
|
||||
|
||||
if nSize>255 then
|
||||
error("ChatThrottleLib:SendChatMessage(): message length cannot exceed 255 bytes", 2)
|
||||
end
|
||||
|
||||
nSize = nSize + self.MSG_OVERHEAD
|
||||
|
||||
-- Check if there's room in the global available bandwidth gauge to send directly
|
||||
if not self.bQueueing and nSize < self:UpdateAvail() then
|
||||
self.avail = self.avail - nSize
|
||||
bMyTraffic = true
|
||||
_G.SendChatMessage(text, chattype, language, destination)
|
||||
bMyTraffic = false
|
||||
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
|
||||
if callbackFn then
|
||||
callbackFn (callbackArg, true)
|
||||
end
|
||||
-- USER CALLBACK MAY ERROR
|
||||
return
|
||||
end
|
||||
|
||||
-- Message needs to be queued
|
||||
local msg = NewMsg()
|
||||
msg.f = _G.SendChatMessage
|
||||
msg[1] = text
|
||||
msg[2] = chattype or "SAY"
|
||||
msg[3] = language
|
||||
msg[4] = destination
|
||||
msg.n = 4
|
||||
msg.nSize = nSize
|
||||
msg.callbackFn = callbackFn
|
||||
msg.callbackArg = callbackArg
|
||||
|
||||
self:Enqueue(prio, queueName or (prefix..(chattype or "SAY")..(destination or "")), msg)
|
||||
end
|
||||
|
||||
|
||||
function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
|
||||
if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
|
||||
error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
|
||||
end
|
||||
if callbackFn and type(callbackFn)~="function" then
|
||||
error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
|
||||
end
|
||||
|
||||
local nSize = strlen(text);
|
||||
|
||||
if RegisterAddonMessagePrefix then
|
||||
if nSize>255 then
|
||||
error("ChatThrottleLib:SendAddonMessage(): message length cannot exceed 255 bytes", 2)
|
||||
end
|
||||
else
|
||||
nSize = nSize + strlen(prefix) + 1
|
||||
if nSize>255 then
|
||||
error("ChatThrottleLib:SendAddonMessage(): prefix + message length cannot exceed 254 bytes", 2)
|
||||
end
|
||||
end
|
||||
|
||||
nSize = nSize + self.MSG_OVERHEAD;
|
||||
|
||||
-- Check if there's room in the global available bandwidth gauge to send directly
|
||||
if not self.bQueueing and nSize < self:UpdateAvail() then
|
||||
self.avail = self.avail - nSize
|
||||
bMyTraffic = true
|
||||
_G.SendAddonMessage(prefix, text, chattype, target)
|
||||
bMyTraffic = false
|
||||
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
|
||||
if callbackFn then
|
||||
callbackFn (callbackArg, true)
|
||||
end
|
||||
-- USER CALLBACK MAY ERROR
|
||||
return
|
||||
end
|
||||
|
||||
-- Message needs to be queued
|
||||
local msg = NewMsg()
|
||||
msg.f = _G.SendAddonMessage
|
||||
msg[1] = prefix
|
||||
msg[2] = text
|
||||
msg[3] = chattype
|
||||
msg[4] = target
|
||||
msg.n = (target~=nil) and 4 or 3;
|
||||
msg.nSize = nSize
|
||||
msg.callbackFn = callbackFn
|
||||
msg.callbackArg = callbackArg
|
||||
|
||||
self:Enqueue(prio, queueName or (prefix..chattype..(target or "")), msg)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Get the ball rolling!
|
||||
|
||||
ChatThrottleLib:Init()
|
||||
|
||||
--[[ WoWBench debugging snippet
|
||||
if(WOWB_VER) then
|
||||
local function SayTimer()
|
||||
print("SAY: "..GetTime().." "..arg1)
|
||||
end
|
||||
ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer)
|
||||
ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY")
|
||||
end
|
||||
]]
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
--- **AceConsole-3.0** provides registration facilities for slash commands.
|
||||
-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
|
||||
-- to your addons individual needs.
|
||||
--
|
||||
-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
|
||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||
-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
|
||||
-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceConsole.
|
||||
-- @class file
|
||||
-- @name AceConsole-3.0
|
||||
-- @release $Id: AceConsole-3.0.lua 1143 2016-07-11 08:52:03Z nevcairiel $
|
||||
local MAJOR,MINOR = "AceConsole-3.0", 7
|
||||
|
||||
local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceConsole then return end -- No upgrade needed
|
||||
|
||||
AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
|
||||
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
|
||||
|
||||
-- Lua APIs
|
||||
local tconcat, tostring, select = table.concat, tostring, select
|
||||
local type, pairs, error = type, pairs, error
|
||||
local format, strfind, strsub = string.format, string.find, string.sub
|
||||
local max = math.max
|
||||
|
||||
-- WoW APIs
|
||||
local _G = getfenv()
|
||||
|
||||
-- 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, SlashCmdList, hash_SlashCmdList
|
||||
|
||||
local tmp={}
|
||||
local function Print(self,frame,...)
|
||||
local n=0
|
||||
if self ~= AceConsole then
|
||||
n=n+1
|
||||
tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
|
||||
end
|
||||
for i=1, getn(arg) do
|
||||
n=n+1
|
||||
tmp[n] = tostring(arg[i])
|
||||
end
|
||||
frame:AddMessage( tconcat(tmp," ",1,n) )
|
||||
end
|
||||
|
||||
--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||
-- @paramsig [chatframe ,] ...
|
||||
-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
|
||||
-- @param ... List of any values to be printed
|
||||
function AceConsole:Print(...)
|
||||
local frame = arg
|
||||
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||
return Print(self, frame, arg[2])
|
||||
else
|
||||
return Print(self, DEFAULT_CHAT_FRAME, arg)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
|
||||
-- @paramsig [chatframe ,] "format"[, ...]
|
||||
-- @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 ... Arguments to the format string
|
||||
function AceConsole:Printf(...)
|
||||
local frame = arg
|
||||
if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
|
||||
return Print(self, frame, format(arg[2]))
|
||||
else
|
||||
return Print(self, DEFAULT_CHAT_FRAME, format(arg))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Register a simple chat command
|
||||
-- @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 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 )
|
||||
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
|
||||
|
||||
local name = "ACECONSOLE_"..string.upper(command)
|
||||
|
||||
if type( func ) == "string" then
|
||||
SlashCmdList[name] = function(input, editBox)
|
||||
self[func](self, input, editBox)
|
||||
end
|
||||
else
|
||||
SlashCmdList[name] = func
|
||||
end
|
||||
_G["SLASH_"..name.."1"] = "/"..string.lower(command)
|
||||
AceConsole.commands[command] = name
|
||||
-- non-persisting commands are registered for enabling disabling
|
||||
if not persist then
|
||||
if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
|
||||
AceConsole.weakcommands[self][command] = func
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Unregister a chatcommand
|
||||
-- @param command Chat command to be unregistered WITHOUT leading "/"
|
||||
function AceConsole:UnregisterChatCommand( command )
|
||||
local name = AceConsole.commands[command]
|
||||
if name then
|
||||
SlashCmdList[name] = nil
|
||||
_G["SLASH_" .. name .. "1"] = nil
|
||||
hash_SlashCmdList["/" .. command:upper()] = nil
|
||||
AceConsole.commands[command] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Get an iterator over all Chat Commands registered with AceConsole
|
||||
-- @return Iterator (pairs) over all commands
|
||||
function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
|
||||
|
||||
|
||||
local function nils(n, ...)
|
||||
if n>1 then
|
||||
return nil, nils(n-1, arg)
|
||||
elseif n==1 then
|
||||
return nil, arg
|
||||
else
|
||||
return arg
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Retreive one or more space-separated arguments from a string.
|
||||
-- Treats quoted strings and itemlinks as non-spaced.
|
||||
-- @param str The raw argument string
|
||||
-- @param numargs How many arguments to get (default 1)
|
||||
-- @param startpos Where in the string to start scanning (default 1)
|
||||
-- @return Returns arg1, arg2, ..., nextposition\\
|
||||
-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
|
||||
function AceConsole:GetArgs(str, numargs, startpos)
|
||||
numargs = numargs or 1
|
||||
startpos = max(startpos or 1, 1)
|
||||
|
||||
local pos=startpos
|
||||
|
||||
-- find start of new arg
|
||||
pos = strfind(str, "[^ ]", pos)
|
||||
if not pos then -- whoops, end of string
|
||||
return nils(numargs, 1e9)
|
||||
end
|
||||
|
||||
if numargs<1 then
|
||||
return pos
|
||||
end
|
||||
|
||||
-- quoted or space separated? find out which pattern to use
|
||||
local delim_or_pipe
|
||||
local ch = strsub(str, pos, pos)
|
||||
if ch=='"' then
|
||||
pos = pos + 1
|
||||
delim_or_pipe='([|"])'
|
||||
elseif ch=="'" then
|
||||
pos = pos + 1
|
||||
delim_or_pipe="([|'])"
|
||||
else
|
||||
delim_or_pipe="([| ])"
|
||||
end
|
||||
|
||||
startpos = pos
|
||||
|
||||
while true do
|
||||
-- find delimiter or hyperlink
|
||||
local ch,_
|
||||
pos,_,ch = strfind(str, delim_or_pipe, pos)
|
||||
|
||||
if not pos then break end
|
||||
|
||||
if ch=="|" then
|
||||
-- some kind of escape
|
||||
|
||||
if strsub(str,pos,pos+1)=="|H" then
|
||||
-- It's a |H....|hhyper link!|h
|
||||
pos=strfind(str, "|h", pos+2) -- first |h
|
||||
if not pos then break end
|
||||
|
||||
pos=strfind(str, "|h", pos+2) -- second |h
|
||||
if not pos then break end
|
||||
elseif strsub(str,pos, pos+1) == "|T" then
|
||||
-- It's a |T....|t texture
|
||||
pos=strfind(str, "|t", pos+2)
|
||||
if not pos then break end
|
||||
end
|
||||
|
||||
pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
|
||||
|
||||
else
|
||||
-- found delimiter, done with this arg
|
||||
return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
|
||||
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)
|
||||
return strsub(str, startpos), nils(numargs-1, 1e9)
|
||||
end
|
||||
|
||||
|
||||
--- embedding and embed handling
|
||||
|
||||
local mixins = {
|
||||
"Print",
|
||||
"Printf",
|
||||
"RegisterChatCommand",
|
||||
"UnregisterChatCommand",
|
||||
"GetArgs",
|
||||
}
|
||||
|
||||
-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
|
||||
-- @param target target object to embed AceBucket in
|
||||
function AceConsole:Embed( target )
|
||||
for k, v in pairs( mixins ) do
|
||||
target[v] = self[v]
|
||||
end
|
||||
self.embeds[target] = true
|
||||
return target
|
||||
end
|
||||
|
||||
function AceConsole:OnEmbedEnable( target )
|
||||
if AceConsole.weakcommands[target] then
|
||||
for command, func in pairs( AceConsole.weakcommands[target] ) do
|
||||
target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceConsole:OnEmbedDisable( target )
|
||||
if AceConsole.weakcommands[target] then
|
||||
for command, func in pairs( AceConsole.weakcommands[target] ) do
|
||||
target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for addon in pairs(AceConsole.embeds) do
|
||||
AceConsole:Embed(addon)
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceConsole-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,205 @@
|
||||
local ACECORE_MAJOR, ACECORE_MINOR = "AceCore-3.0", 1
|
||||
local AceCore, oldminor = LibStub:NewLibrary(ACECORE_MAJOR, ACECORE_MINOR)
|
||||
|
||||
if not AceCore then return end -- No upgrade needed
|
||||
|
||||
AceCore._G = AceCore._G or getfenv()
|
||||
local _G = AceCore._G
|
||||
local strsub, strgsub, strfind = string.sub, string.gsub, string.find
|
||||
local tremove, tconcat = table.remove, table.concat
|
||||
local tgetn, tsetn = table.getn, table.setn
|
||||
|
||||
local new, del
|
||||
do
|
||||
local list = setmetatable({}, {__mode = "k"})
|
||||
function new()
|
||||
local t = next(list)
|
||||
if not t then
|
||||
return {}
|
||||
end
|
||||
list[t] = nil
|
||||
return t
|
||||
end
|
||||
|
||||
function del(t)
|
||||
setmetatable(t, nil)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
tsetn(t,0)
|
||||
list[t] = true
|
||||
end
|
||||
|
||||
-- debug
|
||||
function AceCore.listcount()
|
||||
local count = 0
|
||||
for k in list do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
end -- AceCore.new, AceCore.del
|
||||
AceCore.new, AceCore.del = new, del
|
||||
|
||||
local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
AceCore.errorhandler = errorhandler
|
||||
|
||||
local function CreateSafeDispatcher(argCount)
|
||||
local code = [[
|
||||
local errorhandler = LibStub("AceCore-3.0").errorhandler
|
||||
local method, UP_ARGS
|
||||
local function call()
|
||||
local func, ARGS = method, UP_ARGS
|
||||
method, UP_ARGS = nil, NILS
|
||||
return func(ARGS)
|
||||
end
|
||||
return function(func, ARGS)
|
||||
method, UP_ARGS = func, ARGS
|
||||
return xpcall(call, errorhandler)
|
||||
end
|
||||
]]
|
||||
local c = 4*argCount-1
|
||||
local s = "b01,b02,b03,b04,b05,b06,b07,b08,b09,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20"
|
||||
code = strgsub(code, "UP_ARGS", string.sub(s,1,c))
|
||||
s = "a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20"
|
||||
code = strgsub(code, "ARGS", string.sub(s,1,c))
|
||||
s = "nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil"
|
||||
code = strgsub(code, "NILS", string.sub(s,1,c))
|
||||
return assert(loadstring(code, "safecall SafeDispatcher["..tostring(argCount).."]"))()
|
||||
end
|
||||
|
||||
local SafeDispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher
|
||||
if not tonumber(argCount) then dbg(debugstack()) end
|
||||
if argCount > 0 then
|
||||
dispatcher = CreateSafeDispatcher(argCount)
|
||||
else
|
||||
dispatcher = function(func) return xpcall(func,errorhandler) end
|
||||
end
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
|
||||
local function safecall(func,argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
-- 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
|
||||
return SafeDispatchers[argc](func,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
AceCore.safecall = safecall
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
return function(func,ARGS)
|
||||
return func(ARGS)
|
||||
end
|
||||
]]
|
||||
local s = "a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20"
|
||||
code = strgsub(code, "ARGS", string.sub(s,1,4*argCount-1))
|
||||
return assert(loadstring(code, "call Dispatcher["..tostring(argCount).."]"))()
|
||||
end
|
||||
|
||||
AceCore.Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher
|
||||
if argCount > 0 then
|
||||
dispatcher = CreateDispatcher(argCount)
|
||||
else
|
||||
dispatcher = function(func) return func() end
|
||||
end
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
|
||||
-- some string functions
|
||||
-- vanilla available string operations:
|
||||
-- sub, gfind, rep, gsub, char, dump, find, upper, len, format, byte, lower
|
||||
-- we will just replace every string.match with string.find in the code
|
||||
function AceCore.strtrim(s)
|
||||
return strgsub(s, "^%s*(.-)%s*$", "%1")
|
||||
end
|
||||
|
||||
local function strsplit(delim, s, n)
|
||||
if n and n < 2 then return s end
|
||||
beg = beg or 1
|
||||
local i,j = string.find(s,delim,beg)
|
||||
if not i then
|
||||
return s, nil
|
||||
end
|
||||
return string.sub(s,1,j-1), strsplit(delim, string.sub(s,j+1), n and n-1 or nil)
|
||||
end
|
||||
AceCore.strsplit = strsplit
|
||||
|
||||
-- Ace3v: fonctions copied from AceHook-2.1
|
||||
local protFuncs = {
|
||||
CameraOrSelectOrMoveStart = true, CameraOrSelectOrMoveStop = true,
|
||||
TurnOrActionStart = true, TurnOrActionStop = true,
|
||||
PitchUpStart = true, PitchUpStop = true,
|
||||
PitchDownStart = true, PitchDownStop = true,
|
||||
MoveBackwardStart = true, MoveBackwardStop = true,
|
||||
MoveForwardStart = true, MoveForwardStop = true,
|
||||
Jump = true, StrafeLeftStart = true,
|
||||
StrafeLeftStop = true, StrafeRightStart = true,
|
||||
StrafeRightStop = true, ToggleMouseMove = true,
|
||||
ToggleRun = true, TurnLeftStart = true,
|
||||
TurnLeftStop = true, TurnRightStart = true,
|
||||
TurnRightStop = true,
|
||||
}
|
||||
|
||||
local function issecurevariable(x)
|
||||
return protFuncs[x] and 1 or nil
|
||||
end
|
||||
AceCore.issecurevariable = issecurevariable
|
||||
|
||||
local function hooksecurefunc(arg1, arg2, arg3)
|
||||
if type(arg1) == "string" then
|
||||
arg1, arg2, arg3 = _G, arg1, arg2
|
||||
end
|
||||
local orig = arg1[arg2]
|
||||
if type(orig) ~= "function" then
|
||||
error("The function "..arg2.." does not exist", 2)
|
||||
end
|
||||
arg1[arg2] = function(...)
|
||||
local tmp = {orig(unpack(arg))}
|
||||
arg3(unpack(arg))
|
||||
return unpack(tmp)
|
||||
end
|
||||
end
|
||||
AceCore.hooksecurefunc = hooksecurefunc
|
||||
|
||||
-- pickfirstset() - picks the first non-nil value and returns it
|
||||
local function pickfirstset(argc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
if (argc <= 1) or (a1 ~= nil) then
|
||||
return a1
|
||||
else
|
||||
return pickfirstset(argc-1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
end
|
||||
end
|
||||
AceCore.pickfirstset = pickfirstset
|
||||
|
||||
local function countargs(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
if (a1 == nil) then return 0 end
|
||||
return 1 + countargs(a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
end
|
||||
AceCore.countargs = countargs
|
||||
|
||||
-- wipe preserves metatable
|
||||
function AceCore.wipe(t)
|
||||
for k,v in pairs(t) do t[k] = nil end
|
||||
tsetn(t,0)
|
||||
return t
|
||||
end
|
||||
|
||||
function AceCore.truncate(t,e)
|
||||
e = e or tgetn(t)
|
||||
for i=1,e do
|
||||
if t[i] == nil then
|
||||
tsetn(t,i-1)
|
||||
return
|
||||
end
|
||||
end
|
||||
tsetn(t,e)
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceCore-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,755 @@
|
||||
--- **AceDB-3.0** manages the SavedVariables of your addon.
|
||||
-- It offers profile management, smart defaults and namespaces for modules.\\
|
||||
-- Data can be saved in different data-types, depending on its intended usage.
|
||||
-- The most common data-type is the `profile` type, which allows the user to choose
|
||||
-- the active profile, and manage the profiles of all of his characters.\\
|
||||
-- The following data types are available:
|
||||
-- * **char** Character-specific data. Every character has its own database.
|
||||
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
|
||||
-- * **class** Class-specific data. All of the players characters of the same class share this database.
|
||||
-- * **race** Race-specific data. All of the players characters of the same race share this database.
|
||||
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
|
||||
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
|
||||
-- * **locale** Locale specific data, based on the locale of the players game client.
|
||||
-- * **global** Global Data. All characters on the same account share this database.
|
||||
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
|
||||
--
|
||||
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
|
||||
-- of the DBObjectLib listed here. \\
|
||||
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
|
||||
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
|
||||
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
|
||||
--
|
||||
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
|
||||
--
|
||||
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
|
||||
--
|
||||
-- @usage
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
|
||||
--
|
||||
-- -- declare defaults to be used in the DB
|
||||
-- local defaults = {
|
||||
-- profile = {
|
||||
-- setting = true,
|
||||
-- }
|
||||
-- }
|
||||
--
|
||||
-- function MyAddon:OnInitialize()
|
||||
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
|
||||
-- end
|
||||
-- @class file
|
||||
-- @name AceDB-3.0.lua
|
||||
-- @release $Id: AceDB-3.0.lua 1142 2016-07-11 08:36:19Z nevcairiel $
|
||||
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 26
|
||||
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
|
||||
|
||||
if not AceDB then return end -- No upgrade needed
|
||||
|
||||
local AceCore = LibStub("AceCore-3.0")
|
||||
local new, del = AceCore.new, AceCore.del
|
||||
|
||||
-- Lua APIs
|
||||
local type, pairs, next, error = type, pairs, next, error
|
||||
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
|
||||
|
||||
-- WoW APIs
|
||||
local _G = AceCore._G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: LibStub
|
||||
|
||||
AceDB.db_registry = AceDB.db_registry or {}
|
||||
AceDB.frame = AceDB.frame or CreateFrame("Frame")
|
||||
|
||||
local CallbackHandler
|
||||
local CallbackDummy = { Fire = function() end }
|
||||
|
||||
local DBObjectLib = {}
|
||||
|
||||
-- Ace3v: for all recursive functions we must declare the iterator as local again, this step is necessary in vanilla
|
||||
-- Example:
|
||||
-- for k,v in pairs(table) do
|
||||
-- local v = v
|
||||
-- ...
|
||||
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Utility Functions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
-- Simple shallow copy for copying defaults
|
||||
local function copyTable(src, dest)
|
||||
if type(dest) ~= "table" then dest = {} end
|
||||
if type(src) == "table" then
|
||||
for k,v in pairs(src) do
|
||||
local v = v
|
||||
if type(v) == "table" then
|
||||
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
|
||||
v = copyTable(v, dest[k])
|
||||
end
|
||||
dest[k] = v
|
||||
end
|
||||
end
|
||||
return dest
|
||||
end
|
||||
|
||||
-- Called to add defaults to a section of the database
|
||||
--
|
||||
-- When a ["*"] default section is indexed with a new key, a table is returned
|
||||
-- and set in the host table. These tables must be cleaned up by removeDefaults
|
||||
-- in order to ensure we don't write empty default tables.
|
||||
local function copyDefaults(dest, src)
|
||||
-- this happens if some value in the SV overwrites our default value with a non-table
|
||||
--if type(dest) ~= "table" then return end
|
||||
for k, v in pairs(src) do
|
||||
local v = v
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- This is a metatable used for table defaults
|
||||
local mt = {
|
||||
-- This handles the lookup and creation of new subtables
|
||||
__index = function(t,k)
|
||||
if k == nil then return nil end
|
||||
local tbl = {}
|
||||
copyDefaults(tbl, v)
|
||||
rawset(t, k, tbl)
|
||||
return tbl
|
||||
end,
|
||||
}
|
||||
setmetatable(dest, mt)
|
||||
-- handle already existing tables in the SV
|
||||
for dk, dv in pairs(dest) do
|
||||
if not rawget(src, dk) and type(dv) == "table" then
|
||||
copyDefaults(dv, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Values are not tables, so this is just a simple return
|
||||
local mt = {__index = function(t,k) return k~=nil and v or nil end}
|
||||
setmetatable(dest, mt)
|
||||
end
|
||||
elseif type(v) == "table" then
|
||||
if not rawget(dest, k) then rawset(dest, k, {}) end
|
||||
if type(dest[k]) == "table" then
|
||||
copyDefaults(dest[k], v)
|
||||
if src['**'] then
|
||||
copyDefaults(dest[k], src['**'])
|
||||
end
|
||||
end
|
||||
else
|
||||
if rawget(dest, k) == nil then
|
||||
rawset(dest, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called to remove all defaults in the default table from the database
|
||||
local function removeDefaults(db, defaults, blocker)
|
||||
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them
|
||||
setmetatable(db, nil)
|
||||
-- loop through the defaults and remove their content
|
||||
for k,v in pairs(defaults) do
|
||||
local v = v
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- Loop through all the actual k,v pairs and remove
|
||||
for key, value in pairs(db) do
|
||||
local value = value
|
||||
if type(value) == "table" then
|
||||
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
|
||||
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
|
||||
removeDefaults(value, v)
|
||||
-- if the table is empty afterwards, remove it
|
||||
if next(value) == nil then
|
||||
db[key] = nil
|
||||
end
|
||||
-- if it was specified, only strip ** content, but block values which were set in the key table
|
||||
elseif k == "**" then
|
||||
removeDefaults(value, v, defaults[key])
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif k == "*" then
|
||||
-- check for non-table default
|
||||
for key, value in pairs(db) do
|
||||
if defaults[key] == nil and v == value then
|
||||
db[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif type(v) == "table" and type(db[k]) == "table" then
|
||||
-- if a blocker was set, dive into it, to allow multi-level defaults
|
||||
removeDefaults(db[k], v, blocker and blocker[k])
|
||||
if next(db[k]) == nil then
|
||||
db[k] = nil
|
||||
end
|
||||
else
|
||||
-- check if the current value matches the default, and that its not blocked by another defaults table
|
||||
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
|
||||
db[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- This is called when a table section is first accessed, to set up the defaults
|
||||
local function initSection(db, section, svstore, key, defaults)
|
||||
local sv = rawget(db, "sv")
|
||||
|
||||
local tableCreated
|
||||
if not sv[svstore] then sv[svstore] = {} end
|
||||
if not sv[svstore][key] then
|
||||
sv[svstore][key] = {}
|
||||
tableCreated = true
|
||||
end
|
||||
|
||||
local tbl = sv[svstore][key]
|
||||
|
||||
if defaults then
|
||||
copyDefaults(tbl, defaults)
|
||||
end
|
||||
rawset(db, section, tbl)
|
||||
|
||||
return tableCreated, tbl
|
||||
end
|
||||
|
||||
-- Metatable to handle the dynamic creation of sections and copying of sections.
|
||||
local dbmt = {
|
||||
__index = function(t, section)
|
||||
local keys = rawget(t, "keys")
|
||||
local key = keys[section]
|
||||
if key then
|
||||
local defaultTbl = rawget(t, "defaults")
|
||||
local defaults = defaultTbl and defaultTbl[section]
|
||||
|
||||
if section == "profile" then
|
||||
if initSection(t, section, "profiles", key, defaults) then
|
||||
-- Callback: OnNewProfile, database, newProfileKey
|
||||
t.callbacks:Fire("OnNewProfile", 2, t, key)
|
||||
end
|
||||
elseif section == "profiles" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.profiles then sv.profiles = {} end
|
||||
rawset(t, "profiles", sv.profiles)
|
||||
elseif section == "global" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.global then sv.global = {} end
|
||||
if defaults then
|
||||
copyDefaults(sv.global, defaults)
|
||||
end
|
||||
rawset(t, section, sv.global)
|
||||
else
|
||||
initSection(t, section, section, key, defaults)
|
||||
end
|
||||
end
|
||||
|
||||
return rawget(t, section)
|
||||
end
|
||||
}
|
||||
|
||||
local function validateDefaults(defaults, keyTbl, offset)
|
||||
if not defaults then return end
|
||||
offset = offset or 0
|
||||
for k in pairs(defaults) do
|
||||
if not keyTbl[k] or k == "profiles" then
|
||||
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local preserve_keys = {
|
||||
["callbacks"] = true,
|
||||
["RegisterCallback"] = true,
|
||||
["UnregisterCallback"] = true,
|
||||
["UnregisterAllCallbacks"] = true,
|
||||
["children"] = true,
|
||||
}
|
||||
|
||||
local realmKey = GetRealmName()
|
||||
local charKey = UnitName("player") .. " - " .. realmKey
|
||||
local _, classKey = UnitClass("player")
|
||||
local _, raceKey = UnitRace("player")
|
||||
local _, factionKey = UnitFactionGroup("player")
|
||||
-- Ace3v: the faction key may error when in GM mode
|
||||
factionKey = factionKey or "Others"
|
||||
local localeKey = string.lower(GetLocale())
|
||||
|
||||
-- Actual database initialization function
|
||||
local function initdb(sv, defaults, defaultProfile, olddb, parent)
|
||||
-- Generate the database keys for each section
|
||||
|
||||
-- map "true" to our "Default" profile
|
||||
if defaultProfile == true then defaultProfile = "Default" end
|
||||
|
||||
local profileKey
|
||||
if not parent then
|
||||
-- Make a container for profile keys
|
||||
if not sv.profileKeys then sv.profileKeys = {} end
|
||||
|
||||
-- Try to get the profile selected from the char db
|
||||
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
|
||||
|
||||
-- save the selected profile for later
|
||||
sv.profileKeys[charKey] = profileKey
|
||||
else
|
||||
-- Use the profile of the parents DB
|
||||
profileKey = parent.keys.profile or defaultProfile or charKey
|
||||
|
||||
-- clear the profileKeys in the DB, namespaces don't need to store them
|
||||
sv.profileKeys = nil
|
||||
end
|
||||
|
||||
-- This table contains keys that enable the dynamic creation
|
||||
-- of each section of the table. The 'global' and 'profiles'
|
||||
-- have a key of true, since they are handled in a special case
|
||||
local keyTbl= {
|
||||
["char"] = charKey,
|
||||
["realm"] = realmKey,
|
||||
["class"] = classKey,
|
||||
["race"] = raceKey,
|
||||
["faction"] = factionKey,
|
||||
["factionrealm"] = factionKey .. " - " .. realmKey,
|
||||
["profile"] = profileKey,
|
||||
["locale"] = localeKey,
|
||||
["global"] = true,
|
||||
["profiles"] = true,
|
||||
}
|
||||
|
||||
validateDefaults(defaults, keyTbl, 1)
|
||||
|
||||
-- This allows us to use this function to reset an entire database
|
||||
-- Clear out the old database
|
||||
if olddb then
|
||||
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
|
||||
end
|
||||
|
||||
-- Give this database the metatable so it initializes dynamically
|
||||
local db = setmetatable(olddb or {}, dbmt)
|
||||
|
||||
if not rawget(db, "callbacks") then
|
||||
-- try to load CallbackHandler-1.0 if it loaded after our library
|
||||
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
|
||||
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
|
||||
end
|
||||
|
||||
-- Copy methods locally into the database object, to avoid hitting
|
||||
-- the metatable when calling methods
|
||||
|
||||
if not parent then
|
||||
for name, func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
-- hack this one in
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
db.ResetProfile = DBObjectLib.ResetProfile
|
||||
end
|
||||
|
||||
-- Set some properties in the database object
|
||||
db.profiles = sv.profiles
|
||||
db.keys = keyTbl
|
||||
db.sv = sv
|
||||
--db.sv_name = name
|
||||
db.defaults = defaults
|
||||
db.parent = parent
|
||||
|
||||
-- store the DB in the registry
|
||||
AceDB.db_registry[db] = true
|
||||
|
||||
return db
|
||||
end
|
||||
|
||||
-- handle PLAYER_LOGOUT
|
||||
-- strip all defaults from all databases
|
||||
-- and cleans up empty sections
|
||||
local function logoutHandler()
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
db.callbacks:Fire("OnDatabaseShutdown", 1, db)
|
||||
db:RegisterDefaults(nil)
|
||||
|
||||
-- cleanup sections that are empty without defaults
|
||||
local sv = rawget(db, "sv")
|
||||
for section in pairs(db.keys) do
|
||||
if rawget(sv, section) then
|
||||
-- global is special, all other sections have sub-entrys
|
||||
-- also don't delete empty profiles on main dbs, only on namespaces
|
||||
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
|
||||
for key in pairs(sv[section]) do
|
||||
if not next(sv[section][key]) then
|
||||
sv[section][key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if not next(sv[section]) then
|
||||
sv[section] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
|
||||
AceDB.frame:SetScript("OnEvent", logoutHandler)
|
||||
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Object Method Definitions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
--- Sets the defaults table for the given database object by clearing any
|
||||
-- that are currently set, and then setting the new defaults.
|
||||
-- @param defaults A table of defaults for this database
|
||||
function DBObjectLib:RegisterDefaults(defaults)
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
validateDefaults(defaults, self.keys)
|
||||
|
||||
-- Remove any currently set defaults
|
||||
if self.defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if self.defaults[section] and rawget(self, section) then
|
||||
removeDefaults(self[section], self.defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the DBObject.defaults table
|
||||
self.defaults = defaults
|
||||
|
||||
-- Copy in any defaults, only touching those sections already created
|
||||
if defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if defaults[section] and rawget(self, section) then
|
||||
copyDefaults(self[section], defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Changes the profile of the database and all of it's namespaces to the
|
||||
-- supplied named profile
|
||||
-- @param name The name of the profile to set as the current profile
|
||||
function DBObjectLib:SetProfile(name)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
-- changing to the same profile, dont do anything
|
||||
if name == self.keys.profile then return end
|
||||
|
||||
local oldProfile = self.profile
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
|
||||
-- Callback: OnProfileShutdown, database
|
||||
self.callbacks:Fire("OnProfileShutdown", 1, self)
|
||||
|
||||
if oldProfile and defaults then
|
||||
-- Remove the defaults from the old profile
|
||||
removeDefaults(oldProfile, defaults)
|
||||
end
|
||||
|
||||
self.profile = nil
|
||||
self.keys["profile"] = name
|
||||
|
||||
-- if the storage exists, save the new profile
|
||||
-- this won't exist on namespaces.
|
||||
if self.sv.profileKeys then
|
||||
self.sv.profileKeys[charKey] = name
|
||||
end
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.SetProfile(db, name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileChanged, database, newProfileKey
|
||||
self.callbacks:Fire("OnProfileChanged", 2, self, name)
|
||||
end
|
||||
|
||||
--- Returns a table with the names of the existing profiles in the database.
|
||||
-- You can optionally supply a table to re-use for this purpose.
|
||||
-- @param tbl A table to store the profile names in (optional)
|
||||
function DBObjectLib:GetProfiles(tbl)
|
||||
if tbl and type(tbl) ~= "table" then
|
||||
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
-- Clear the container table
|
||||
if tbl then
|
||||
for k,v in pairs(tbl) do tbl[k] = nil end
|
||||
else
|
||||
tbl = {}
|
||||
end
|
||||
|
||||
local curProfile = self.keys.profile
|
||||
|
||||
local i = 0
|
||||
for profileKey in pairs(self.profiles) do
|
||||
i = i + 1
|
||||
tbl[i] = profileKey
|
||||
if curProfile and profileKey == curProfile then curProfile = nil end
|
||||
end
|
||||
|
||||
-- Add the current profile, if it hasn't been created yet
|
||||
if curProfile then
|
||||
i = i + 1
|
||||
tbl[i] = curProfile
|
||||
end
|
||||
|
||||
return tbl, i
|
||||
end
|
||||
|
||||
--- Returns the current profile name used by the database
|
||||
function DBObjectLib:GetCurrentProfile()
|
||||
return self.keys.profile
|
||||
end
|
||||
|
||||
--- Deletes a named profile. This profile must not be the active profile.
|
||||
-- @param name The name of the profile to be deleted
|
||||
-- @param silent If true, do not raise an error when the profile does not exist
|
||||
function DBObjectLib:DeleteProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if self.keys.profile == name then
|
||||
error("Cannot delete the active profile in an AceDBObject.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.profiles, name) and not silent then
|
||||
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
self.profiles[name] = nil
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.DeleteProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- switch all characters that use this profile back to the default
|
||||
if self.sv.profileKeys then
|
||||
for key, profile in pairs(self.sv.profileKeys) do
|
||||
if profile == name then
|
||||
self.sv.profileKeys[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileDeleted, database, profileKey
|
||||
self.callbacks:Fire("OnProfileDeleted", 2, self, name)
|
||||
end
|
||||
|
||||
--- Copies a named profile into the current profile, overwriting any conflicting
|
||||
-- settings.
|
||||
-- @param name The name of the profile to be copied into the current profile
|
||||
-- @param silent If true, do not raise an error when the profile does not exist
|
||||
function DBObjectLib:CopyProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if name == self.keys.profile then
|
||||
error("Cannot have the same source and destination profiles.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.profiles, name) and not silent then
|
||||
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
-- Reset the profile before copying
|
||||
DBObjectLib.ResetProfile(self, nil, true)
|
||||
|
||||
local profile = self.profile
|
||||
local source = self.profiles[name]
|
||||
|
||||
copyTable(source, profile)
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.CopyProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileCopied, database, sourceProfileKey
|
||||
self.callbacks:Fire("OnProfileCopied", 2, self, name)
|
||||
end
|
||||
|
||||
--- Resets the current profile to the default values (if specified).
|
||||
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
|
||||
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
|
||||
function DBObjectLib:ResetProfile(noChildren, noCallbacks)
|
||||
local profile = self.profile
|
||||
|
||||
for k,v in pairs(profile) do
|
||||
profile[k] = nil
|
||||
end
|
||||
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
if defaults then
|
||||
copyDefaults(profile, defaults)
|
||||
end
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children and not noChildren then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.ResetProfile(db, nil, noCallbacks)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileReset, database
|
||||
if not noCallbacks then
|
||||
self.callbacks:Fire("OnProfileReset", 2, self, self.keys["profile"])
|
||||
end
|
||||
end
|
||||
|
||||
--- Resets the entire database, using the string defaultProfile as the new default
|
||||
-- profile.
|
||||
-- @param defaultProfile The profile name to use as the default
|
||||
function DBObjectLib:ResetDB(defaultProfile)
|
||||
if defaultProfile and type(defaultProfile) ~= "string" then
|
||||
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
for k,v in pairs(sv) do
|
||||
sv[k] = nil
|
||||
end
|
||||
|
||||
local parent = self.parent
|
||||
|
||||
initdb(sv, self.defaults, defaultProfile, self)
|
||||
|
||||
-- fix the child namespaces
|
||||
if self.children then
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
for name, db in pairs(self.children) do
|
||||
if not sv.namespaces[name] then sv.namespaces[name] = {} end
|
||||
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnDatabaseReset, database
|
||||
self.callbacks:Fire("OnDatabaseReset", 1, self)
|
||||
-- Callback: OnProfileChanged, database, profileKey
|
||||
self.callbacks:Fire("OnProfileChanged", 2, self, self.keys["profile"])
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a new database namespace, directly tied to the database. This
|
||||
-- is a full scale database in it's own rights other than the fact that
|
||||
-- it cannot control its profile individually
|
||||
-- @param name The name of the new namespace
|
||||
-- @param defaults A table of values to use as defaults
|
||||
function DBObjectLib:RegisterNamespace(name, defaults)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
|
||||
end
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
if self.children and self.children[name] then
|
||||
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
if not sv.namespaces[name] then
|
||||
sv.namespaces[name] = {}
|
||||
end
|
||||
|
||||
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
|
||||
|
||||
if not self.children then self.children = {} end
|
||||
self.children[name] = newDB
|
||||
return newDB
|
||||
end
|
||||
|
||||
--- Returns an already existing namespace from the database object.
|
||||
-- @param name The name of the new namespace
|
||||
-- @param silent if true, the addon is optional, silently return nil if its not found
|
||||
-- @usage
|
||||
-- local namespace = self.db:GetNamespace('namespace')
|
||||
-- @return the namespace object if found
|
||||
function DBObjectLib:GetNamespace(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
|
||||
end
|
||||
if not silent and not (self.children and self.children[name]) then
|
||||
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
|
||||
end
|
||||
if not self.children then self.children = {} end
|
||||
return self.children[name]
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Exposed Methods
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
--- Creates a new database object that can be used to handle database settings and profiles.
|
||||
-- By default, an empty DB is created, using a character specific profile.
|
||||
--
|
||||
-- You can override the default profile used by passing any profile name as the third argument,
|
||||
-- or by passing //true// as the third argument to use a globally shared profile called "Default".
|
||||
--
|
||||
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
|
||||
-- will use a profile named "char", and not a character-specific profile.
|
||||
-- @param tbl The name of variable, or table to use for the database
|
||||
-- @param defaults A table of database defaults
|
||||
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
|
||||
-- You can also pass //true// to use a shared global profile called "Default".
|
||||
-- @usage
|
||||
-- -- Create an empty DB using a character-specific default profile.
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
|
||||
-- @usage
|
||||
-- -- Create a DB using defaults and using a shared default profile
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
|
||||
function AceDB:New(tbl, defaults, defaultProfile)
|
||||
if type(tbl) == "string" then
|
||||
local name = tbl
|
||||
tbl = _G[name]
|
||||
if not tbl then
|
||||
tbl = {}
|
||||
_G[name] = tbl
|
||||
end
|
||||
end
|
||||
|
||||
if type(tbl) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
|
||||
end
|
||||
|
||||
return initdb(tbl, defaults, defaultProfile)
|
||||
end
|
||||
|
||||
-- upgrade existing databases
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
if not db.parent then
|
||||
for name,func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
db.ResetProfile = DBObjectLib.ResetProfile
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceDB-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,129 @@
|
||||
--- AceEvent-3.0 provides event registration and secure dispatching.
|
||||
-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
|
||||
-- CallbackHandler, and dispatches all game events or addon message to the registrees.
|
||||
--
|
||||
-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
|
||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||
-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
|
||||
-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceEvent.
|
||||
-- @class file
|
||||
-- @name AceEvent-3.0
|
||||
-- @release $Id: AceEvent-3.0.lua 975 2010-10-23 11:26:18Z nevcairiel $
|
||||
local MAJOR, MINOR = "AceEvent-3.0", 3
|
||||
local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceEvent then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
local CallbackHandler = LibStub("CallbackHandler-1.0")
|
||||
|
||||
AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
|
||||
AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
|
||||
|
||||
-- APIs and registry for blizzard events, using CallbackHandler lib
|
||||
if not AceEvent.events then
|
||||
AceEvent.events = CallbackHandler:New(AceEvent,
|
||||
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
|
||||
end
|
||||
|
||||
function AceEvent.events:OnUsed(target, eventname)
|
||||
AceEvent.frame:RegisterEvent(eventname)
|
||||
end
|
||||
|
||||
function AceEvent.events:OnUnused(target, eventname)
|
||||
AceEvent.frame:UnregisterEvent(eventname)
|
||||
end
|
||||
|
||||
|
||||
-- APIs and registry for IPC messages, using CallbackHandler lib
|
||||
if not AceEvent.messages then
|
||||
AceEvent.messages = CallbackHandler:New(AceEvent,
|
||||
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
|
||||
)
|
||||
AceEvent.SendMessage = AceEvent.messages.Fire
|
||||
end
|
||||
|
||||
--- embedding and embed handling
|
||||
local mixins = {
|
||||
"RegisterEvent", "UnregisterEvent",
|
||||
"RegisterMessage", "UnregisterMessage",
|
||||
"SendMessage",
|
||||
"UnregisterAllEvents", "UnregisterAllMessages",
|
||||
}
|
||||
|
||||
--- Register for a Blizzard Event.
|
||||
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
|
||||
-- Any arguments to the event will be passed on after that.
|
||||
-- @name AceEvent:RegisterEvent
|
||||
-- @class function
|
||||
-- @paramsig event[, callback [, arg]]
|
||||
-- @param event The event to register for
|
||||
-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
|
||||
-- @param arg An optional argument to pass to the callback function
|
||||
|
||||
--- Unregister an event.
|
||||
-- @name AceEvent:UnregisterEvent
|
||||
-- @class function
|
||||
-- @paramsig event
|
||||
-- @param event The event to unregister
|
||||
|
||||
--- Register for a custom AceEvent-internal message.
|
||||
-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
|
||||
-- Any arguments to the event will be passed on after that.
|
||||
-- @name AceEvent:RegisterMessage
|
||||
-- @class function
|
||||
-- @paramsig message[, callback [, arg]]
|
||||
-- @param message The message to register for
|
||||
-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
|
||||
-- @param arg An optional argument to pass to the callback function
|
||||
|
||||
--- Unregister a message
|
||||
-- @name AceEvent:UnregisterMessage
|
||||
-- @class function
|
||||
-- @paramsig message
|
||||
-- @param message The message to unregister
|
||||
|
||||
--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
|
||||
-- @name AceEvent:SendMessage
|
||||
-- @class function
|
||||
-- @paramsig message, ...
|
||||
-- @param message The message to send
|
||||
-- @param ... Any arguments to the message
|
||||
|
||||
|
||||
-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
|
||||
-- @param target target object to embed AceEvent in
|
||||
function AceEvent:Embed(target)
|
||||
for k, v in pairs(mixins) do
|
||||
target[v] = self[v]
|
||||
end
|
||||
self.embeds[target] = true
|
||||
return target
|
||||
end
|
||||
|
||||
-- AceEvent:OnEmbedDisable( target )
|
||||
-- target (object) - target object that is being disabled
|
||||
--
|
||||
-- Unregister all events messages etc when the target disables.
|
||||
-- this method should be called by the target manually or by an addon framework
|
||||
function AceEvent:OnEmbedDisable(target)
|
||||
target:UnregisterAllEvents()
|
||||
target:UnregisterAllMessages()
|
||||
end
|
||||
|
||||
-- Script to fire blizzard events into the event listeners
|
||||
-- Ace3v: in vanilla the arguments are set to global:
|
||||
-- event, arg1, arg2, arg3 ...
|
||||
-- the user have always access to them, so we save the table cost here
|
||||
local events = AceEvent.events
|
||||
AceEvent.frame:SetScript("OnEvent", function()
|
||||
events:Fire(event)
|
||||
end)
|
||||
|
||||
--- Finally: upgrade our old embeds
|
||||
for target, v in pairs(AceEvent.embeds) do
|
||||
AceEvent:Embed(target)
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceEvent-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,540 @@
|
||||
--- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
|
||||
-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
|
||||
-- when you manually restore the original function.
|
||||
--
|
||||
-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
|
||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||
-- and can be accessed directly, without having to explicitly call AceHook itself.\\
|
||||
-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceHook.
|
||||
-- @class file
|
||||
-- @name AceHook-3.0
|
||||
-- @release $Id: AceHook-3.0.lua 1118 2014-10-12 08:21:54Z nevcairiel $
|
||||
local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 8
|
||||
local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
|
||||
|
||||
if not AceHook then return end -- No upgrade needed
|
||||
|
||||
local AceCore = LibStub("AceCore-3.0")
|
||||
local new, del = AceCore.new, AceCore.del
|
||||
|
||||
AceHook.embeded = AceHook.embeded or {}
|
||||
AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
|
||||
AceHook.handlers = AceHook.handlers or {}
|
||||
AceHook.actives = AceHook.actives or {}
|
||||
AceHook.scripts = AceHook.scripts or {}
|
||||
AceHook.onceSecure = AceHook.onceSecure or {}
|
||||
AceHook.hooks = AceHook.hooks or {}
|
||||
|
||||
-- local upvalues
|
||||
local registry = AceHook.registry
|
||||
local handlers = AceHook.handlers
|
||||
local actives = AceHook.actives
|
||||
local scripts = AceHook.scripts
|
||||
local onceSecure = AceHook.onceSecure
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, next, type = pairs, next, type
|
||||
local format = string.format
|
||||
local assert, error = assert, error
|
||||
|
||||
-- WoW APIs
|
||||
local hooksecurefunc, issecurevariable = AceCore.hooksecurefunc, AceCore.issecurevariable
|
||||
|
||||
local _G = AceCore._G
|
||||
|
||||
local protectedScripts = {
|
||||
OnClick = true,
|
||||
}
|
||||
|
||||
-- upgrading of embeded is done at the bottom of the file
|
||||
|
||||
local mixins = {
|
||||
"Hook", "SecureHook",
|
||||
"HookScript", "SecureHookScript",
|
||||
"Unhook", "UnhookAll",
|
||||
"IsHooked",
|
||||
"RawHook", "RawHookScript"
|
||||
}
|
||||
|
||||
-- AceHook:Embed( target )
|
||||
-- target (object) - target object to embed AceHook in
|
||||
--
|
||||
-- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
|
||||
function AceHook:Embed( target )
|
||||
for k, v in pairs( mixins ) do
|
||||
target[v] = self[v]
|
||||
end
|
||||
self.embeded[target] = true
|
||||
-- inject the hooks table safely
|
||||
target.hooks = target.hooks or {}
|
||||
return target
|
||||
end
|
||||
|
||||
-- AceHook:OnEmbedDisable( target )
|
||||
-- target (object) - target object that is being disabled
|
||||
--
|
||||
-- Unhooks all hooks when the target disables.
|
||||
-- this method should be called by the target manually or by an addon framework
|
||||
function AceHook:OnEmbedDisable( target )
|
||||
target:UnhookAll()
|
||||
end
|
||||
|
||||
-- failsafe means even the hooking method fails, the original method will
|
||||
-- always be called
|
||||
local function createHook(self, handler, orig, secure, failsafe)
|
||||
local uid
|
||||
local method = type(handler) == "string"
|
||||
-- Ace3v: when this function called in the "hook" function, we have
|
||||
-- failsafe = not (raw or secure), so the first check condition
|
||||
-- is same as "if failsafe" or "if not raw and not secure"
|
||||
if failsafe and not secure then
|
||||
-- failsafe hook creation
|
||||
uid = function(...)
|
||||
if actives[uid] then
|
||||
if method then
|
||||
self[handler](self,unpack(arg))
|
||||
else
|
||||
handler(unpack(arg))
|
||||
end
|
||||
end
|
||||
return orig(unpack(arg))
|
||||
end
|
||||
-- /failsafe hook
|
||||
else
|
||||
-- all other hooks
|
||||
uid = function(...)
|
||||
if actives[uid] then
|
||||
if method then
|
||||
return self[handler](self,unpack(arg))
|
||||
else
|
||||
return handler(unpack(arg))
|
||||
end
|
||||
elseif not secure then -- backup on non secure
|
||||
return orig(unpack(arg))
|
||||
end
|
||||
end
|
||||
-- /hook
|
||||
end
|
||||
return uid
|
||||
end
|
||||
|
||||
local function donothing() end
|
||||
|
||||
-- @param self
|
||||
-- @param obj nil or a frame object, use with script = true
|
||||
-- @param method string, the name of a global function or the name of an object method
|
||||
-- @param handler function, or string when it's a method of 'self', if nil then will use the same value as method
|
||||
-- @param script boolean, must be true, if the hooked object is a frame
|
||||
-- @param secure boolean, if hooking a secure script, if true the original script will be called first, else later
|
||||
-- @param raw boolean, if raw hooking (replacing the original method)
|
||||
-- @param forceSecure boolean, if forcing to hook a secure method
|
||||
-- @param usage
|
||||
local function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
|
||||
if not handler then handler = method end
|
||||
|
||||
-- These asserts make sure AceHooks's devs play by the rules.
|
||||
assert(not script or type(script) == "boolean")
|
||||
assert(not secure or type(secure) == "boolean")
|
||||
assert(not raw or type(raw) == "boolean")
|
||||
assert(not forceSecure or type(forceSecure) == "boolean")
|
||||
assert(usage)
|
||||
|
||||
-- Error checking Battery!
|
||||
if obj and type(obj) ~= "table" then
|
||||
error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
|
||||
end
|
||||
if type(method) ~= "string" then
|
||||
error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
|
||||
end
|
||||
if type(handler) ~= "string" and type(handler) ~= "function" then
|
||||
error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
|
||||
end
|
||||
if type(handler) == "string" and type(self[handler]) ~= "function" then
|
||||
error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
|
||||
end
|
||||
if script then
|
||||
if not obj or not obj.GetScript or not obj:HasScript(method) then
|
||||
error(format("%s: You can only hook a script on a frame object", usage), 3)
|
||||
end
|
||||
if not secure and obj.IsProtected and obj:IsProtected() and protectedScripts[method] then
|
||||
error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
|
||||
end
|
||||
else
|
||||
local issecure
|
||||
if obj then
|
||||
issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
|
||||
else
|
||||
issecure = onceSecure[method] or issecurevariable(method)
|
||||
end
|
||||
if issecure then
|
||||
if forceSecure then
|
||||
if obj then
|
||||
onceSecure[obj] = onceSecure[obj] or {}
|
||||
onceSecure[obj][method] = true
|
||||
else
|
||||
onceSecure[method] = true
|
||||
end
|
||||
elseif not secure then
|
||||
error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local uid
|
||||
if obj then
|
||||
uid = registry[self][obj] and registry[self][obj][method]
|
||||
else
|
||||
uid = registry[self][method]
|
||||
end
|
||||
|
||||
if uid then
|
||||
if actives[uid] then
|
||||
-- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
|
||||
-- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
|
||||
error(format("Attempting to rehook already active hook %s.", method))
|
||||
end
|
||||
|
||||
if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
|
||||
actives[uid] = true
|
||||
return
|
||||
elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
|
||||
if self.hooks and self.hooks[obj] then
|
||||
self.hooks[obj][method] = nil
|
||||
end
|
||||
registry[self][obj][method] = nil
|
||||
else
|
||||
if self.hooks then
|
||||
self.hooks[method] = nil
|
||||
end
|
||||
registry[self][method] = nil
|
||||
end
|
||||
handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
|
||||
uid = nil
|
||||
end
|
||||
|
||||
local orig
|
||||
if script then
|
||||
-- Sometimes there is not a original function for a script.
|
||||
orig = obj:GetScript(method) or donothing
|
||||
elseif obj then
|
||||
orig = obj[method]
|
||||
else
|
||||
orig = _G[method]
|
||||
end
|
||||
|
||||
if not orig then
|
||||
error(format("%s: Attempting to hook a non existing target", usage), 3)
|
||||
end
|
||||
|
||||
uid = createHook(self, handler, orig, secure, not (raw or secure))
|
||||
|
||||
if obj then
|
||||
registry[self][obj] = registry[self][obj] or new()
|
||||
registry[self][obj][method] = uid
|
||||
|
||||
if not secure then
|
||||
self.hooks[obj] = self.hooks[obj] or new()
|
||||
self.hooks[obj][method] = orig
|
||||
end
|
||||
|
||||
if script then
|
||||
if not secure then
|
||||
obj:SetScript(method, uid)
|
||||
else
|
||||
obj:SetScript(method, function(...)
|
||||
local tmp = {orig(unpack(arg))}
|
||||
uid(unpack(arg))
|
||||
return unpack(tmp)
|
||||
end)
|
||||
--obj:HookScript(method, uid) -- Ace3v: vanilla frame has no HookScript
|
||||
end
|
||||
else
|
||||
if not secure then
|
||||
obj[method] = uid
|
||||
else
|
||||
hooksecurefunc(obj, method, uid)
|
||||
end
|
||||
end
|
||||
else
|
||||
registry[self][method] = uid
|
||||
|
||||
if not secure then
|
||||
_G[method] = uid
|
||||
self.hooks[method] = orig
|
||||
else
|
||||
hooksecurefunc(method, uid)
|
||||
end
|
||||
end
|
||||
|
||||
actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
|
||||
end
|
||||
|
||||
--- Hook a function or a method on an object.
|
||||
-- The hook created will be a "safe hook", that means that your handler will be called
|
||||
-- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
|
||||
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
|
||||
-- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
|
||||
-- @paramsig [object], method, [handler], [hookSecure]
|
||||
-- @param object The object to hook a method from
|
||||
-- @param method If object was specified, the name of the method, or the name of the function to hook.
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
|
||||
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
|
||||
-- @usage
|
||||
-- -- create an addon with AceHook embeded
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
|
||||
-- self:Hook("ActionButton_UpdateHotkeys", true)
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
|
||||
-- print(button:GetName() .. " is updating its HotKey")
|
||||
-- end
|
||||
function AceHook:Hook(object, method, handler, hookSecure)
|
||||
if type(object) == "string" then
|
||||
method, handler, hookSecure, object = object, method, handler, nil
|
||||
end
|
||||
|
||||
if handler == true then
|
||||
handler, hookSecure = nil, true
|
||||
end
|
||||
|
||||
hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
|
||||
end
|
||||
|
||||
--- RawHook a function or a method on an object.
|
||||
-- The hook created will be a "raw hook", that means that your handler will completly replace
|
||||
-- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
|
||||
-- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
|
||||
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
|
||||
-- or want to control execution of the original function.
|
||||
-- @paramsig [object], method, [handler], [hookSecure]
|
||||
-- @param object The object to hook a method from
|
||||
-- @param method If object was specified, the name of the method, or the name of the function to hook.
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
|
||||
-- @param hookSecure If true, AceHook will allow hooking of secure functions.
|
||||
-- @usage
|
||||
-- -- create an addon with AceHook embeded
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
|
||||
-- self:RawHook("ActionButton_UpdateHotkeys", true)
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
|
||||
-- if button:GetName() == "MyButton" then
|
||||
-- -- do stuff here
|
||||
-- else
|
||||
-- self.hooks.ActionButton_UpdateHotkeys(button, type)
|
||||
-- end
|
||||
-- end
|
||||
function AceHook:RawHook(object, method, handler, hookSecure)
|
||||
if type(object) == "string" then
|
||||
method, handler, hookSecure, object = object, method, handler, nil
|
||||
end
|
||||
|
||||
if handler == true then
|
||||
handler, hookSecure = nil, true
|
||||
end
|
||||
|
||||
hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
|
||||
end
|
||||
|
||||
--- SecureHook a function or a method on an object.
|
||||
-- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
|
||||
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
|
||||
-- required anymore, or the addon is being disabled.\\
|
||||
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
|
||||
-- and taint would block execution. Secure Hooks are always called after the original function was called
|
||||
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
|
||||
-- @paramsig [object], method, [handler]
|
||||
-- @param object The object to hook a method from
|
||||
-- @param method If object was specified, the name of the method, or the name of the function to hook.
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
|
||||
function AceHook:SecureHook(object, method, handler)
|
||||
if type(object) == "string" then
|
||||
method, handler, object = object, method, nil
|
||||
end
|
||||
|
||||
hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
|
||||
end
|
||||
|
||||
--- Hook a script handler on a frame.
|
||||
-- The hook created will be a "safe hook", that means that your handler will be called
|
||||
-- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
|
||||
-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
|
||||
-- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
|
||||
-- when a certain event happens to a frame.
|
||||
-- @paramsig frame, script, [handler]
|
||||
-- @param frame The Frame to hook the script on
|
||||
-- @param script The script to hook
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
|
||||
-- @usage
|
||||
-- -- create an addon with AceHook embeded
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- -- Hook the OnShow of FriendsFrame
|
||||
-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:FriendsFrameOnShow(frame)
|
||||
-- print("The FriendsFrame was shown!")
|
||||
-- end
|
||||
function AceHook:HookScript(frame, script, handler)
|
||||
hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])")
|
||||
end
|
||||
|
||||
--- RawHook a script handler on a frame.
|
||||
-- The hook created will be a "raw hook", that means that your handler will completly replace
|
||||
-- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
|
||||
-- The original script will be stored in `self.hooks[frame][script]`.\\
|
||||
-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
|
||||
-- or want to control execution of the original script.
|
||||
-- @paramsig frame, script, [handler]
|
||||
-- @param frame The Frame to hook the script on
|
||||
-- @param script The script to hook
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
|
||||
-- @usage
|
||||
-- -- create an addon with AceHook embeded
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- -- Hook the OnShow of FriendsFrame
|
||||
-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:FriendsFrameOnShow(frame)
|
||||
-- -- Call the original function
|
||||
-- self.hooks[frame].OnShow(frame)
|
||||
-- -- Do our processing
|
||||
-- -- .. stuff
|
||||
-- end
|
||||
function AceHook:RawHookScript(frame, script, handler)
|
||||
hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
|
||||
end
|
||||
|
||||
--- SecureHook a script handler on a frame.
|
||||
-- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
|
||||
-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
|
||||
-- required anymore, or the addon is being disabled.\\
|
||||
-- Secure Hooks should be used if the secure-status of the function is vital to its function,
|
||||
-- and taint would block execution. Secure Hooks are always called after the original function was called
|
||||
-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
|
||||
-- @paramsig frame, script, [handler]
|
||||
-- @param frame The Frame to hook the script on
|
||||
-- @param script The script to hook
|
||||
-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
|
||||
function AceHook:SecureHookScript(frame, script, handler)
|
||||
hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
|
||||
end
|
||||
|
||||
--- Unhook from the specified function, method or script.
|
||||
-- @paramsig [obj], method
|
||||
-- @param obj The object or frame to unhook from
|
||||
-- @param method The name of the method, function or script to unhook from.
|
||||
function AceHook:Unhook(obj, method)
|
||||
local usage = "Usage: Unhook([obj], method)"
|
||||
if type(obj) == "string" then
|
||||
method, obj = obj, nil
|
||||
end
|
||||
|
||||
if obj and type(obj) ~= "table" then
|
||||
error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
|
||||
end
|
||||
if type(method) ~= "string" then
|
||||
error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
|
||||
end
|
||||
|
||||
local uid
|
||||
if obj then
|
||||
uid = registry[self][obj] and registry[self][obj][method]
|
||||
else
|
||||
uid = registry[self][method]
|
||||
end
|
||||
|
||||
if not uid or not actives[uid] then
|
||||
-- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
|
||||
return false
|
||||
end
|
||||
|
||||
actives[uid], handlers[uid] = nil, nil
|
||||
|
||||
if obj then
|
||||
local tmp = registry[self][obj]
|
||||
tmp[method] = nil
|
||||
if not next(tmp) then
|
||||
del(tmp)
|
||||
registry[self][obj] = nil
|
||||
end
|
||||
|
||||
-- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
|
||||
if not self.hooks[obj] or not self.hooks[obj][method] then return true end
|
||||
|
||||
if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
|
||||
obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
|
||||
scripts[uid] = nil
|
||||
elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
|
||||
obj[method] = self.hooks[obj][method]
|
||||
end
|
||||
|
||||
tmp = self.hooks[obj]
|
||||
tmp[method] = nil
|
||||
if not next(tmp) then
|
||||
del(tmp)
|
||||
self.hooks[obj] = nil
|
||||
end
|
||||
else
|
||||
registry[self][method] = nil
|
||||
|
||||
-- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
|
||||
if not self.hooks[method] then return true end
|
||||
|
||||
if self.hooks[method] and _G[method] == uid then -- unhooks functions
|
||||
_G[method] = self.hooks[method]
|
||||
end
|
||||
|
||||
self.hooks[method] = nil
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Unhook all existing hooks for this addon.
|
||||
function AceHook:UnhookAll()
|
||||
for key, value in pairs(registry[self]) do
|
||||
if type(key) == "table" then
|
||||
for method in pairs(value) do
|
||||
self:Unhook(key, method)
|
||||
end
|
||||
else
|
||||
self:Unhook(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Check if the specific function, method or script is already hooked.
|
||||
-- @paramsig [obj], method
|
||||
-- @param obj The object or frame to unhook from
|
||||
-- @param method The name of the method, function or script to unhook from.
|
||||
function AceHook:IsHooked(obj, method)
|
||||
-- we don't check if registry[self] exists, this is done by evil magicks in the metatable
|
||||
if type(obj) == "string" then
|
||||
if registry[self][obj] and actives[registry[self][obj]] then
|
||||
return true, handlers[registry[self][obj]]
|
||||
end
|
||||
else
|
||||
if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
|
||||
return true, handlers[registry[self][obj][method]]
|
||||
end
|
||||
end
|
||||
|
||||
return false, nil
|
||||
end
|
||||
|
||||
--- Upgrade our old embeded
|
||||
for target, v in pairs( AceHook.embeded ) do
|
||||
AceHook:Embed( target )
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceHook-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,137 @@
|
||||
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
|
||||
-- @class file
|
||||
-- @name AceLocale-3.0
|
||||
-- @release $Id: AceLocale-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $
|
||||
local MAJOR,MINOR = "AceLocale-3.0", 6
|
||||
|
||||
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceLocale then return end -- no upgrade needed
|
||||
|
||||
-- Lua APIs
|
||||
local assert, tostring, error = assert, tostring, error
|
||||
local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GAME_LOCALE, geterrorhandler
|
||||
|
||||
local gameLocale = GetLocale()
|
||||
if gameLocale == "enGB" then
|
||||
gameLocale = "enUS"
|
||||
end
|
||||
|
||||
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
|
||||
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
|
||||
|
||||
-- This metatable is used on all tables returned from GetLocale
|
||||
local readmeta = {
|
||||
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
|
||||
rawset(self, key, key) -- only need to see the warning once, really
|
||||
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
|
||||
return key
|
||||
end
|
||||
}
|
||||
|
||||
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
|
||||
local readmetasilent = {
|
||||
__index = function(self, key) -- requesting totally unknown entries: return key
|
||||
rawset(self, key, key) -- only need to invoke this function once
|
||||
return key
|
||||
end
|
||||
}
|
||||
|
||||
-- Remember the locale table being registered right now (it gets set by :NewLocale())
|
||||
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
|
||||
local registering
|
||||
|
||||
-- local assert false function
|
||||
local assertfalse = function() assert(false) end
|
||||
|
||||
-- This metatable proxy is used when registering nondefault locales
|
||||
local writeproxy = setmetatable({}, {
|
||||
__newindex = function(self, key, value)
|
||||
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
|
||||
end,
|
||||
__index = assertfalse
|
||||
})
|
||||
|
||||
-- This metatable proxy is used when registering the default locale.
|
||||
-- It refuses to overwrite existing values
|
||||
-- Reason 1: Allows loading locales in any order
|
||||
-- Reason 2: If 2 modules have the same string, but only the first one to be
|
||||
-- loaded has a translation for the current locale, the translation
|
||||
-- doesn't get overwritten.
|
||||
--
|
||||
local writedefaultproxy = setmetatable({}, {
|
||||
__newindex = function(self, key, value)
|
||||
if not rawget(registering, key) then
|
||||
rawset(registering, key, value == true and key or value)
|
||||
end
|
||||
end,
|
||||
__index = assertfalse
|
||||
})
|
||||
|
||||
--- Register a new locale (or extend an existing one) for the specified application.
|
||||
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
|
||||
-- game locale.
|
||||
-- @paramsig application, locale[, isDefault[, silent]]
|
||||
-- @param application Unique name of addon / module
|
||||
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
|
||||
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
|
||||
-- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
|
||||
-- @usage
|
||||
-- -- enUS.lua
|
||||
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
|
||||
-- L["string1"] = true
|
||||
--
|
||||
-- -- deDE.lua
|
||||
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
|
||||
-- if not L then return end
|
||||
-- L["string1"] = "Zeichenkette1"
|
||||
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
|
||||
function AceLocale:NewLocale(application, locale, isDefault, silent)
|
||||
|
||||
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
|
||||
local gameLocale = GAME_LOCALE or gameLocale
|
||||
|
||||
local app = AceLocale.apps[application]
|
||||
|
||||
if silent and app and getmetatable(app) ~= readmetasilent then
|
||||
geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
|
||||
end
|
||||
|
||||
if not app then
|
||||
if silent=="raw" then
|
||||
app = {}
|
||||
else
|
||||
app = setmetatable({}, silent and readmetasilent or readmeta)
|
||||
end
|
||||
AceLocale.apps[application] = app
|
||||
AceLocale.appnames[app] = application
|
||||
end
|
||||
|
||||
if locale ~= gameLocale and not isDefault then
|
||||
return nil -- nop, we don't need these translations
|
||||
end
|
||||
|
||||
registering = app -- remember globally for writeproxy and writedefaultproxy
|
||||
|
||||
if isDefault then
|
||||
return writedefaultproxy
|
||||
end
|
||||
|
||||
return writeproxy
|
||||
end
|
||||
|
||||
--- Returns localizations for the current locale (or default locale if translations are missing).
|
||||
-- Errors if nothing is registered (spank developer, not just a missing translation)
|
||||
-- @param application Unique name of addon / module
|
||||
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
|
||||
-- @return The locale table for the current language.
|
||||
function AceLocale:GetLocale(application, silent)
|
||||
if not silent and not AceLocale.apps[application] then
|
||||
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
|
||||
end
|
||||
return AceLocale.apps[application]
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceLocale-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,286 @@
|
||||
--- **AceSerializer-3.0** can serialize any variable (except functions or userdata) into a string format,
|
||||
-- that can be send over the addon comm channel. AceSerializer was designed to keep all data intact, especially
|
||||
-- very large numbers or floating point numbers, and table structures. The only caveat currently is, that multiple
|
||||
-- references to the same table will be send individually.
|
||||
--
|
||||
-- **AceSerializer-3.0** can be embeded into your addon, either explicitly by calling AceSerializer:Embed(MyAddon) or by
|
||||
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
|
||||
-- and can be accessed directly, without having to explicitly call AceSerializer itself.\\
|
||||
-- It is recommended to embed AceSerializer, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceSerializer.
|
||||
-- @class file
|
||||
-- @name AceSerializer-3.0
|
||||
-- @release $Id: AceSerializer-3.0.lua 1135 2015-09-19 20:39:16Z nevcairiel $
|
||||
local MAJOR,MINOR = "AceSerializer-3.0", 5
|
||||
local AceSerializer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceSerializer then return end
|
||||
|
||||
-- Lua APIs
|
||||
local strbyte, strchar, gsub, gfind, format = string.byte, string.char, string.gsub, string.gfind, string.format
|
||||
local assert, error, pcall = assert, error, pcall
|
||||
local type, tostring, tonumber = type, tostring, tonumber
|
||||
local pairs, select, frexp = pairs, select, math.frexp
|
||||
local tconcat, tgetn = table.concat, table.getn
|
||||
|
||||
-- quick copies of string representations of wonky numbers
|
||||
local inf = 1/0
|
||||
|
||||
local serNaN -- can't do this in 4.3, see ace3 ticket 268
|
||||
local serInf, serInfMac = "1.#INF", "inf"
|
||||
local serNegInf, serNegInfMac = "-1.#INF", "-inf"
|
||||
|
||||
|
||||
-- Serialization functions
|
||||
|
||||
local function SerializeStringHelper(ch) -- Used by SerializeValue for strings
|
||||
-- We use \126 ("~") as an escape character for all nonprints plus a few more
|
||||
local n = strbyte(ch)
|
||||
if n==30 then -- v3 / ticket 115: catch a nonprint that ends up being "~^" when encoded... DOH
|
||||
return "\126\122"
|
||||
elseif n<=32 then -- nonprint + space
|
||||
return "\126"..strchar(n+64)
|
||||
elseif n==94 then -- value separator
|
||||
return "\126\125"
|
||||
elseif n==126 then -- our own escape character
|
||||
return "\126\124"
|
||||
elseif n==127 then -- nonprint (DEL)
|
||||
return "\126\123"
|
||||
else
|
||||
assert(false) -- can't be reached if caller uses a sane regex
|
||||
end
|
||||
end
|
||||
|
||||
local function SerializeValue(v, res, nres)
|
||||
-- We use "^" as a value separator, followed by one byte for type indicator
|
||||
local t=type(v)
|
||||
|
||||
if t=="string" then -- ^S = string (escaped to remove nonprints, "^"s, etc)
|
||||
res[nres+1] = "^S"
|
||||
res[nres+2] = gsub(v,"[%c \94\126\127]", SerializeStringHelper)
|
||||
nres=nres+2
|
||||
|
||||
elseif t=="number" then -- ^N = number (just tostring()ed) or ^F (float components)
|
||||
local str = tostring(v)
|
||||
if tonumber(str)==v --[[not in 4.3 or str==serNaN]] then
|
||||
-- translates just fine, transmit as-is
|
||||
res[nres+1] = "^N"
|
||||
res[nres+2] = str
|
||||
nres=nres+2
|
||||
elseif v == inf or v == -inf then
|
||||
res[nres+1] = "^N"
|
||||
res[nres+2] = v == inf and serInf or serNegInf
|
||||
nres=nres+2
|
||||
else
|
||||
local m,e = frexp(v)
|
||||
res[nres+1] = "^F"
|
||||
res[nres+2] = format("%.0f",m*2^53) -- force mantissa to become integer (it's originally 0.5--0.9999)
|
||||
res[nres+3] = "^f"
|
||||
res[nres+4] = tostring(e-53) -- adjust exponent to counteract mantissa manipulation
|
||||
nres=nres+4
|
||||
end
|
||||
|
||||
elseif t=="table" then -- ^T...^t = table (list of key,value pairs)
|
||||
nres=nres+1
|
||||
res[nres] = "^T"
|
||||
for k,v in pairs(v) do
|
||||
nres = SerializeValue(k, res, nres)
|
||||
nres = SerializeValue(v, res, nres)
|
||||
end
|
||||
nres=nres+1
|
||||
res[nres] = "^t"
|
||||
|
||||
elseif t=="boolean" then -- ^B = true, ^b = false
|
||||
nres=nres+1
|
||||
if v then
|
||||
res[nres] = "^B" -- true
|
||||
else
|
||||
res[nres] = "^b" -- false
|
||||
end
|
||||
|
||||
elseif t=="nil" then -- ^Z = nil (zero, "N" was taken :P)
|
||||
nres=nres+1
|
||||
res[nres] = "^Z"
|
||||
|
||||
else
|
||||
error(MAJOR..": Cannot serialize a value of type '"..t.."'") -- can't produce error on right level, this is wildly recursive
|
||||
end
|
||||
|
||||
return nres
|
||||
end
|
||||
|
||||
|
||||
|
||||
local serializeTbl = { "^1" } -- "^1" = Hi, I'm data serialized by AceSerializer protocol rev 1
|
||||
|
||||
--- Serialize the data passed into the function.
|
||||
-- Takes a list of values (strings, numbers, booleans, nils, tables)
|
||||
-- and returns it in serialized form (a string).\\
|
||||
-- May throw errors on invalid data types.
|
||||
-- @param ... List of values to serialize
|
||||
-- @return The data in its serialized form (string)
|
||||
function AceSerializer:Serialize(...)
|
||||
local nres = 1
|
||||
for i = 1,tgetn(arg) do
|
||||
local v = arg[i]
|
||||
nres = SerializeValue(v, serializeTbl, nres)
|
||||
end
|
||||
|
||||
serializeTbl[nres+1] = "^^" -- "^^" = End of serialized data
|
||||
|
||||
return tconcat(serializeTbl, "", 1, nres+1)
|
||||
end
|
||||
|
||||
-- Deserialization functions
|
||||
local function DeserializeStringHelper(escape)
|
||||
if escape<"~\122" then
|
||||
return strchar(strbyte(escape,2,2)-64)
|
||||
elseif escape=="~\122" then -- v3 / ticket 115: special case encode since 30+64=94 ("^") - OOPS.
|
||||
return "\030"
|
||||
elseif escape=="~\123" then
|
||||
return "\127"
|
||||
elseif escape=="~\124" then
|
||||
return "\126"
|
||||
elseif escape=="~\125" then
|
||||
return "\94"
|
||||
end
|
||||
error("DeserializeStringHelper got called for '"..escape.."'?!?") -- can't be reached unless regex is screwed up
|
||||
end
|
||||
|
||||
local function DeserializeNumberHelper(number)
|
||||
--[[ not in 4.3 if number == serNaN then
|
||||
return 0/0
|
||||
else]]if number == serNegInf or number == serNegInfMac then
|
||||
return -inf
|
||||
elseif number == serInf or number == serInfMac then
|
||||
return inf
|
||||
else
|
||||
return tonumber(number)
|
||||
end
|
||||
end
|
||||
|
||||
-- DeserializeValue: worker function for :Deserialize()
|
||||
-- It works in two modes:
|
||||
-- Main (top-level) mode: Deserialize a list of values and return them all
|
||||
-- Recursive (table) mode: Deserialize only a single value (_may_ of course be another table with lots of subvalues in it)
|
||||
--
|
||||
-- The function _always_ works recursively due to having to build a list of values to return
|
||||
--
|
||||
-- Callers are expected to pcall(DeserializeValue) to trap errors
|
||||
|
||||
local function DeserializeValue(iter,single,ctl,data)
|
||||
|
||||
if not single then
|
||||
ctl,data = iter()
|
||||
end
|
||||
|
||||
if not ctl then
|
||||
error("Supplied data misses AceSerializer terminator ('^^')")
|
||||
end
|
||||
|
||||
if ctl=="^^" then
|
||||
-- ignore extraneous data
|
||||
return
|
||||
end
|
||||
|
||||
local res
|
||||
|
||||
if ctl=="^S" then
|
||||
res = gsub(data, "~.", DeserializeStringHelper)
|
||||
elseif ctl=="^N" then
|
||||
res = DeserializeNumberHelper(data)
|
||||
if not res then
|
||||
error("Invalid serialized number: '"..tostring(data).."'")
|
||||
end
|
||||
elseif ctl=="^F" then -- ^F<mantissa>^f<exponent>
|
||||
local ctl2,e = iter()
|
||||
if ctl2~="^f" then
|
||||
error("Invalid serialized floating-point number, expected '^f', not '"..tostring(ctl2).."'")
|
||||
end
|
||||
local m=tonumber(data)
|
||||
e=tonumber(e)
|
||||
if not (m and e) then
|
||||
error("Invalid serialized floating-point number, expected mantissa and exponent, got '"..tostring(m).."' and '"..tostring(e).."'")
|
||||
end
|
||||
res = m*(2^e)
|
||||
elseif ctl=="^B" then -- yeah yeah ignore data portion
|
||||
res = true
|
||||
elseif ctl=="^b" then -- yeah yeah ignore data portion
|
||||
res = false
|
||||
elseif ctl=="^Z" then -- yeah yeah ignore data portion
|
||||
res = nil
|
||||
elseif ctl=="^T" then
|
||||
-- ignore ^T's data, future extensibility?
|
||||
res = {}
|
||||
local k,v
|
||||
while true do
|
||||
ctl,data = iter()
|
||||
if ctl=="^t" then break end -- ignore ^t's data
|
||||
k = DeserializeValue(iter,true,ctl,data)
|
||||
if k==nil then
|
||||
error("Invalid AceSerializer table format (no table end marker)")
|
||||
end
|
||||
ctl,data = iter()
|
||||
v = DeserializeValue(iter,true,ctl,data)
|
||||
if v==nil then
|
||||
error("Invalid AceSerializer table format (no table end marker)")
|
||||
end
|
||||
res[k]=v
|
||||
end
|
||||
else
|
||||
error("Invalid AceSerializer control code '"..ctl.."'")
|
||||
end
|
||||
|
||||
if not single then
|
||||
return res,DeserializeValue(iter)
|
||||
else
|
||||
return res
|
||||
end
|
||||
end
|
||||
|
||||
--- Deserializes the data into its original values.
|
||||
-- Accepts serialized data, ignoring all control characters and whitespace.
|
||||
-- @param str The serialized data (from :Serialize)
|
||||
-- @return true followed by a list of values, OR false followed by an error message
|
||||
function AceSerializer:Deserialize(str)
|
||||
str = gsub(str, "[%c ]", "") -- ignore all control characters; nice for embedding in email and stuff
|
||||
|
||||
local iter = gfind(str, "(^.)([^^]*)") -- Any ^x followed by string of non-^
|
||||
local ctl,data = iter()
|
||||
if not ctl or ctl~="^1" then
|
||||
-- we purposefully ignore the data portion of the start code, it can be used as an extension mechanism
|
||||
return false, "Supplied data is not AceSerializer data (rev 1)"
|
||||
end
|
||||
|
||||
return pcall(DeserializeValue, iter)
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------
|
||||
-- Base library stuff
|
||||
----------------------------------------
|
||||
|
||||
AceSerializer.internals = { -- for test scripts
|
||||
SerializeValue = SerializeValue,
|
||||
SerializeStringHelper = SerializeStringHelper,
|
||||
}
|
||||
|
||||
local mixins = {
|
||||
"Serialize",
|
||||
"Deserialize",
|
||||
}
|
||||
|
||||
AceSerializer.embeds = AceSerializer.embeds or {}
|
||||
|
||||
function AceSerializer:Embed(target)
|
||||
for k, v in pairs(mixins) do
|
||||
target[v] = self[v]
|
||||
end
|
||||
self.embeds[target] = true
|
||||
return target
|
||||
end
|
||||
|
||||
-- Update embeds
|
||||
for target, v in pairs(AceSerializer.embeds) do
|
||||
AceSerializer:Embed(target)
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceSerializer-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,474 @@
|
||||
--- **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
|
||||
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled
|
||||
-- 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
|
||||
-- in the future, but for now it seemed like a good compromise in efficiency and accuracy.
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
-- **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
|
||||
-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
|
||||
-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
|
||||
-- make into AceTimer.
|
||||
-- @class file
|
||||
-- @name AceTimer-3.0
|
||||
-- @release $Id: AceTimer-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
|
||||
|
||||
--[[
|
||||
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)
|
||||
|
||||
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)
|
||||
-- Linked list gets around ACE-88 and ACE-90.
|
||||
AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
|
||||
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
|
||||
|
||||
-- Lua APIs
|
||||
local assert, error, loadstring = assert, error, loadstring
|
||||
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
|
||||
local select, pairs, type, next, tostring = select, pairs, type, next, tostring
|
||||
local floor, max, min = math.floor, math.max, math.min
|
||||
local tconcat = table.concat
|
||||
|
||||
-- WoW APIs
|
||||
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.
|
||||
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
|
||||
If this is ever LOWERED, all existing timers need to be enforced to have a delay >= 1/HZ on lib upgrade.
|
||||
If this number is ever changed, all entries need to be rehashed on lib upgrade.
|
||||
]]
|
||||
local HZ = 11
|
||||
|
||||
--[[
|
||||
Prime for good distribution
|
||||
If this number is ever changed, all entries need to be rehashed on lib upgrade.
|
||||
]]
|
||||
local BUCKETS = 131
|
||||
|
||||
local hash = AceTimer.hash
|
||||
for i=1,BUCKETS do
|
||||
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
|
||||
end
|
||||
|
||||
--[[
|
||||
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[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
|
||||
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
|
||||
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'self' - must be a table.", 3)
|
||||
end
|
||||
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
|
||||
|
||||
if delay < (1 / (HZ - 1)) then
|
||||
delay = 1 / (HZ - 1)
|
||||
end
|
||||
|
||||
-- Create and stuff timer in the correct hash bucket
|
||||
local now = GetTime()
|
||||
|
||||
local timer = timerCache or {} -- Get new timer object (from cache if available)
|
||||
timerCache = nil
|
||||
|
||||
timer.object = self
|
||||
timer.callback = callback
|
||||
timer.delay = (repeating and delay)
|
||||
timer.arg = arg
|
||||
timer.when = now + delay
|
||||
|
||||
local bucket = (math.mod(floor((now+delay)*HZ), BUCKETS)) + 1
|
||||
timer.next = hash[bucket]
|
||||
hash[bucket] = timer
|
||||
|
||||
-- Insert timer in our self->handle->timer registry
|
||||
local handle = tostring(timer)
|
||||
|
||||
local selftimers = AceTimer.selfs[self]
|
||||
if not selftimers then
|
||||
selftimers = {}
|
||||
AceTimer.selfs[self] = selftimers
|
||||
end
|
||||
selftimers[handle] = timer
|
||||
selftimers.__ops = (selftimers.__ops or 0) + 1
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
--- Schedule a new one-shot timer.
|
||||
-- The timer will fire once in `delay` seconds, unless canceled before.
|
||||
-- @param callback Callback function for the timer pulse (funcref or method name).
|
||||
-- @param delay Delay for the timer, in seconds.
|
||||
-- @param arg An optional argument to be passed to the callback function.
|
||||
-- @usage
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- self:ScheduleTimer("TimerFeedback", 5)
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:TimerFeedback()
|
||||
-- print("5 seconds passed")
|
||||
-- end
|
||||
function AceTimer:ScheduleTimer(callback, delay, arg)
|
||||
return Reg(self, callback, delay, arg)
|
||||
end
|
||||
|
||||
--- Schedule a repeating timer.
|
||||
-- The timer will fire every `delay` seconds, until canceled.
|
||||
-- @param callback Callback function for the timer pulse (funcref or method name).
|
||||
-- @param delay Delay for the timer, in seconds.
|
||||
-- @param arg An optional argument to be passed to the callback function.
|
||||
-- @usage
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
|
||||
--
|
||||
-- function MyAddon:OnEnable()
|
||||
-- self.timerCount = 0
|
||||
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
|
||||
-- end
|
||||
--
|
||||
-- function MyAddon:TimerFeedback()
|
||||
-- self.timerCount = self.timerCount + 1
|
||||
-- print(("%d seconds passed"):format(5 * self.timerCount))
|
||||
-- -- run 30 seconds in total
|
||||
-- if self.timerCount == 6 then
|
||||
-- self:CancelTimer(self.testTimer)
|
||||
-- end
|
||||
-- end
|
||||
function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
|
||||
return Reg(self, callback, delay, arg, true)
|
||||
end
|
||||
|
||||
--- Cancels a timer with the given handle, 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
|
||||
-- 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 silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
|
||||
-- @return True if the timer was successfully cancelled.
|
||||
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
|
||||
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
|
||||
return false
|
||||
end
|
||||
if not timer.callback then
|
||||
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
|
||||
return false
|
||||
end
|
||||
timer.callback = nil -- don't run it again
|
||||
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--- Cancels all timers registered to the current addon object ('self')
|
||||
function AceTimer:CancelAllTimers()
|
||||
if not(type(self) == "string" or type(self) == "table") then
|
||||
error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
|
||||
end
|
||||
if self == AceTimer then
|
||||
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
|
||||
end
|
||||
|
||||
local selftimers = AceTimer.selfs[self]
|
||||
if selftimers then
|
||||
for handle,v in pairs(selftimers) do
|
||||
if type(v) == "table" then -- avoid __ops, etc
|
||||
AceTimer.CancelTimer(self, handle, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
|
||||
-- This function will raise a warning when the handle is invalid, but not stop execution.
|
||||
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
|
||||
-- @return The time left on the timer, or false if the handle is invalid.
|
||||
function AceTimer:TimeLeft(handle)
|
||||
if not handle then return end
|
||||
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
|
||||
geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
|
||||
return false
|
||||
end
|
||||
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
|
||||
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.
|
||||
if n>BUCKETS then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
|
||||
end
|
||||
|
||||
selfs[self] = newlist
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Embed handling
|
||||
|
||||
AceTimer.embeds = AceTimer.embeds or {}
|
||||
|
||||
local mixins = {
|
||||
"ScheduleTimer", "ScheduleRepeatingTimer",
|
||||
"CancelTimer", "CancelAllTimers",
|
||||
"TimeLeft"
|
||||
}
|
||||
|
||||
function AceTimer:Embed(target)
|
||||
AceTimer.embeds[target] = true
|
||||
for _,v in pairs(mixins) do
|
||||
target[v] = AceTimer[v]
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
-- AceTimer:OnEmbedDisable( target )
|
||||
-- target (object) - target object that AceTimer is embedded in.
|
||||
--
|
||||
-- cancel all timers registered for the object
|
||||
function AceTimer:OnEmbedDisable( target )
|
||||
target:CancelAllTimers()
|
||||
end
|
||||
|
||||
|
||||
for addon in pairs(AceTimer.embeds) do
|
||||
AceTimer:Embed(addon)
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Debug tools (expose copies of internals to test suites)
|
||||
AceTimer.debug = AceTimer.debug or {}
|
||||
AceTimer.debug.HZ = HZ
|
||||
AceTimer.debug.BUCKETS = BUCKETS
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Finishing touchups
|
||||
|
||||
AceTimer.frame:SetScript("OnUpdate", OnUpdate)
|
||||
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.
|
||||
-- However, this job is fairly expensive, and the chance that there will
|
||||
-- actually be zero timers running is diminuitive to say the least.
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="AceTimer-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,234 @@
|
||||
--[[ $Id: CallbackHandler-1.0.lua 18 2014-10-16 02:52:20Z mikk $ ]]
|
||||
local MAJOR, MINOR = "CallbackHandler-1.0", 6
|
||||
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not CallbackHandler then return end -- No upgrade needed
|
||||
|
||||
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
|
||||
|
||||
-- Lua APIs
|
||||
local tconcat = table.concat
|
||||
local assert, error, loadstring = assert, error, loadstring
|
||||
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
|
||||
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: geterrorhandler
|
||||
|
||||
local xpcall = xpcall
|
||||
|
||||
local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
local method, ARGS
|
||||
local function call() method(ARGS) end
|
||||
|
||||
local function dispatch(handlers, ...)
|
||||
local index
|
||||
index, method = next(handlers)
|
||||
if not method then return end
|
||||
local OLD_ARGS = ARGS
|
||||
ARGS = unpack(arg)
|
||||
repeat
|
||||
xpcall(call, function(err) return geterrorhandler()(err) end)
|
||||
index, method = next(handlers, index)
|
||||
until not method
|
||||
ARGS = OLD_ARGS
|
||||
end
|
||||
|
||||
return dispatch
|
||||
]]
|
||||
|
||||
local ARGS, OLD_ARGS = {}, {}
|
||||
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
|
||||
code = gsub(gsub(code, "OLD_ARGS", tconcat(OLD_ARGS, ", ")), "ARGS", tconcat(ARGS, ", "))
|
||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
|
||||
end
|
||||
|
||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher = CreateDispatcher(argCount)
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- CallbackHandler:New
|
||||
--
|
||||
-- target - target object to embed public APIs in
|
||||
-- RegisterName - name of the callback registration API, default "RegisterCallback"
|
||||
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
|
||||
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
|
||||
|
||||
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName)
|
||||
|
||||
RegisterName = RegisterName or "RegisterCallback"
|
||||
UnregisterName = UnregisterName or "UnregisterCallback"
|
||||
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
|
||||
UnregisterAllName = "UnregisterAllCallbacks"
|
||||
end
|
||||
|
||||
-- we declare all objects and exported APIs inside this closure to quickly gain access
|
||||
-- to e.g. function names, the "target" parameter, etc
|
||||
|
||||
|
||||
-- Create the registry object
|
||||
local events = setmetatable({}, meta)
|
||||
local registry = { recurse=0, events=events }
|
||||
|
||||
-- registry:Fire() - fires the given event/message into the registry
|
||||
function registry:Fire(eventname, ...)
|
||||
if not rawget(events, eventname) or not next(events[eventname]) then return end
|
||||
local oldrecurse = registry.recurse
|
||||
registry.recurse = oldrecurse + 1
|
||||
|
||||
Dispatchers[getn(arg) + 1](events[eventname], eventname, unpack(arg))
|
||||
|
||||
registry.recurse = oldrecurse
|
||||
|
||||
if registry.insertQueue and oldrecurse==0 then
|
||||
-- Something in one of our callbacks wanted to register more callbacks; they got queued
|
||||
for eventname,callbacks in pairs(registry.insertQueue) do
|
||||
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
|
||||
for self,func in pairs(callbacks) do
|
||||
events[eventname][self] = func
|
||||
-- fire OnUsed callback?
|
||||
if first and registry.OnUsed then
|
||||
registry.OnUsed(registry, target, eventname)
|
||||
first = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
registry.insertQueue = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Registration of a callback, handles:
|
||||
-- self["method"], leads to self["method"](self, ...)
|
||||
-- self with function ref, leads to functionref(...)
|
||||
-- "addonId" (instead of self) with function ref, leads to functionref(...)
|
||||
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
|
||||
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
|
||||
if type(eventname) ~= "string" then
|
||||
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
|
||||
end
|
||||
|
||||
method = method or eventname
|
||||
|
||||
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
|
||||
|
||||
if type(method) ~= "string" and type(method) ~= "function" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
|
||||
end
|
||||
|
||||
local regfunc
|
||||
|
||||
if type(method) == "string" then
|
||||
-- self["method"] calling style
|
||||
if type(self) ~= "table" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
|
||||
elseif self==target then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
|
||||
elseif type(self[method]) ~= "function" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
|
||||
end
|
||||
|
||||
if getn(arg)>=1 then -- this is not the same as testing for arg==nil!
|
||||
regfunc = function(...) self[method](self,arg1,unpack(arg)) end
|
||||
else
|
||||
regfunc = function(...) self[method](self,unpack(arg)) end
|
||||
end
|
||||
else
|
||||
-- function ref with self=object or self="addonId" or self=thread
|
||||
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
|
||||
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
|
||||
end
|
||||
|
||||
if getn(arg)>=1 then -- this is not the same as testing for arg==nil!
|
||||
regfunc = function(...) method(arg1,unpack(arg)) end
|
||||
else
|
||||
regfunc = method
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if events[eventname][self] or registry.recurse<1 then
|
||||
-- if registry.recurse<1 then
|
||||
-- we're overwriting an existing entry, or not currently recursing. just set it.
|
||||
events[eventname][self] = regfunc
|
||||
-- fire OnUsed callback?
|
||||
if registry.OnUsed and first then
|
||||
registry.OnUsed(registry, target, eventname)
|
||||
end
|
||||
else
|
||||
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
|
||||
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
|
||||
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
|
||||
registry.insertQueue[eventname][self] = regfunc
|
||||
end
|
||||
end
|
||||
|
||||
-- Unregister a callback
|
||||
target[UnregisterName] = function(self, eventname)
|
||||
if not self or self==target then
|
||||
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
|
||||
end
|
||||
if type(eventname) ~= "string" then
|
||||
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
|
||||
end
|
||||
if rawget(events, eventname) and events[eventname][self] then
|
||||
events[eventname][self] = nil
|
||||
-- Fire OnUnused callback?
|
||||
if registry.OnUnused and not next(events[eventname]) then
|
||||
registry.OnUnused(registry, target, eventname)
|
||||
end
|
||||
end
|
||||
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
|
||||
registry.insertQueue[eventname][self] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
|
||||
if UnregisterAllName then
|
||||
target[UnregisterAllName] = function(...)
|
||||
if getn(arg)<1 then
|
||||
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
|
||||
end
|
||||
if getn(arg)==1 and arg1==target then
|
||||
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
|
||||
end
|
||||
|
||||
|
||||
for i=1,getn(arg) do
|
||||
local self = arg[i]
|
||||
if registry.insertQueue then
|
||||
for eventname, callbacks in pairs(registry.insertQueue) do
|
||||
if callbacks[self] then
|
||||
callbacks[self] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
for eventname, callbacks in pairs(events) do
|
||||
if callbacks[self] then
|
||||
callbacks[self] = nil
|
||||
-- Fire OnUnused callback?
|
||||
if registry.OnUnused and not next(callbacks) then
|
||||
registry.OnUnused(registry, target, eventname)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return registry
|
||||
end
|
||||
|
||||
|
||||
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
|
||||
-- try to upgrade old implicit embeds since the system is selfcontained and
|
||||
-- relies on closures to work.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="CallbackHandler-1.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,819 @@
|
||||
-- LibAnim by Hydra
|
||||
local Version = 2.01
|
||||
|
||||
if (_LibAnim and _LibAnim >= Version) then
|
||||
return
|
||||
end
|
||||
|
||||
local _G = getfenv()
|
||||
local cos = cos
|
||||
local sin = sin
|
||||
local pairs = pairs
|
||||
local floor = floor
|
||||
local getn = getn
|
||||
local tinsert = tinsert
|
||||
local tremove = tremove
|
||||
local strlower = strlower
|
||||
local Updater = CreateFrame("StatusBar")
|
||||
local Texture = Updater:CreateTexture()
|
||||
local Text = Updater:CreateFontString()
|
||||
local AnimTypes = {}
|
||||
local UpdateFuncs = {}
|
||||
local Callbacks = {["onplay"] = {}, ["onpause"] = {}, ["onresume"] = {}, ["onstop"] = {}, ["onreset"] = {}, ["onfinished"] = {}}
|
||||
|
||||
-- Update all current animations
|
||||
local AnimationOnUpdate = function(self, elapsed)
|
||||
for i = 1, getn(self) do
|
||||
if self[i] then -- Double check the the index still exists, due to pauses/stops removing them on the fly
|
||||
self[i]:Update(elapsed, i)
|
||||
end
|
||||
end
|
||||
|
||||
if (getn(self) == 0) then
|
||||
self:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
|
||||
local StartUpdating = function(anim)
|
||||
tinsert(Updater, anim)
|
||||
|
||||
if (not Updater:GetScript("OnUpdate")) then
|
||||
Updater:SetScript("OnUpdate", AnimationOnUpdate)
|
||||
end
|
||||
end
|
||||
|
||||
local GetColor = function(p, r1, g1, b1, r2, g2, b2)
|
||||
return r1 + (r2 - r1) * p, g1 + (g2 - g1) * p, b1 + (b2 - b1) * p
|
||||
end
|
||||
|
||||
local Set = {
|
||||
["backdrop"] = Updater.SetBackdropColor,
|
||||
["border"] = Updater.SetBackdropBorderColor,
|
||||
["statusbar"] = Updater.SetStatusBarColor,
|
||||
["text"] = Text.SetTextColor,
|
||||
["texture"] = Texture.SetTexture,
|
||||
["vertex"] = Texture.SetVertexColor,
|
||||
}
|
||||
|
||||
local Get = {
|
||||
["backdrop"] = Updater.GetBackdropColor,
|
||||
["border"] = Updater.GetBackdropBorderColor,
|
||||
["statusbar"] = Updater.GetStatusBarColor,
|
||||
["text"] = Text.GetTextColor,
|
||||
["texture"] = Texture.GetVertexColor,
|
||||
["vertex"] = Texture.GetVertexColor,
|
||||
}
|
||||
|
||||
local Smoothing = {
|
||||
["none"] = function(t, b, c, d)
|
||||
return c * t / d + b
|
||||
end,
|
||||
|
||||
["in"] = function(t, b, c, d)
|
||||
t = t / d
|
||||
|
||||
return c * t * t + b
|
||||
end,
|
||||
|
||||
["out"] = function(t, b, c, d)
|
||||
t = t / d
|
||||
|
||||
return -c * t * (t - 2) + b
|
||||
end,
|
||||
|
||||
["inout"] = function(t, b, c, d)
|
||||
t = t / (d / 2)
|
||||
|
||||
if (t < 1) then
|
||||
return c / 2 * t * t + b
|
||||
end
|
||||
|
||||
t = t - 1
|
||||
return -c / 2 * (t * (t - 2) - 1) + b
|
||||
end,
|
||||
|
||||
["bounce"] = function(t, b, c, d)
|
||||
t = t / d
|
||||
|
||||
if (t < (1 / 2.75)) then
|
||||
return c * (7.5625 * t * t) + b
|
||||
elseif (t < (2 / 2.75)) then
|
||||
t = t - (1.5 / 2.75)
|
||||
|
||||
return c * (7.5625 * t * t + 0.75) + b
|
||||
elseif (t < (2.5 / 2.75)) then
|
||||
t = t - (2.25 / 2.75)
|
||||
|
||||
return c * (7.5625 * t * t + 0.9375) + b
|
||||
else
|
||||
t = t - (2.625 / 2.75)
|
||||
|
||||
return c * (7.5625 * (t) * t + 0.984375) + b
|
||||
end
|
||||
end,
|
||||
["elastic"] = function(t, b, c, d)
|
||||
local s, p, a = 1.70158, d * .3, c;
|
||||
if t == 0 then
|
||||
return b
|
||||
end
|
||||
t = t / d
|
||||
|
||||
if t == 1 then
|
||||
return b + c
|
||||
end
|
||||
|
||||
if a < math.abs(c) then
|
||||
a = c
|
||||
s = p / 4
|
||||
else
|
||||
s = p / (2 * math.pi) * math.asin(c / a)
|
||||
end
|
||||
|
||||
return a * math.pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p) + c + b
|
||||
end
|
||||
}
|
||||
|
||||
local AnimMethods = {
|
||||
All = {
|
||||
Play = function(self)
|
||||
if (not self.Paused) then
|
||||
AnimTypes[self.Type](self)
|
||||
self:Callback("OnPlay")
|
||||
else
|
||||
StartUpdating(self)
|
||||
self:Callback("OnResume")
|
||||
end
|
||||
|
||||
self.Playing = true
|
||||
self.Paused = false
|
||||
self.Stopped = false
|
||||
end,
|
||||
|
||||
IsPlaying = function(self)
|
||||
return self.Playing
|
||||
end,
|
||||
|
||||
Pause = function(self)
|
||||
for i = 1, getn(Updater) do
|
||||
if (Updater[i] == self) then
|
||||
tremove(Updater, i)
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.Playing = false
|
||||
self.Paused = true
|
||||
self.Stopped = false
|
||||
self:Callback("OnPause")
|
||||
end,
|
||||
|
||||
IsPaused = function(self)
|
||||
return self.Paused
|
||||
end,
|
||||
|
||||
Stop = function(self, reset)
|
||||
for i = 1, getn(Updater) do
|
||||
if (Updater[i] == self) then
|
||||
tremove(Updater, i)
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.Playing = false
|
||||
self.Paused = false
|
||||
self.Stopped = true
|
||||
|
||||
if reset then
|
||||
self:Reset()
|
||||
self:Callback("OnReset")
|
||||
else
|
||||
self:Callback("OnStop")
|
||||
end
|
||||
end,
|
||||
|
||||
IsStopped = function(self)
|
||||
return self.Stopped
|
||||
end,
|
||||
|
||||
SetSmoothing = function(self, smoothType)
|
||||
smoothType = strlower(smoothType)
|
||||
|
||||
self.Smoothing = Smoothing[smoothType] and smoothType or "none"
|
||||
end,
|
||||
|
||||
GetSmoothing = function(self)
|
||||
return self.Smoothing
|
||||
end,
|
||||
|
||||
SetDuration = function(self, duration)
|
||||
self.Duration = duration or 0
|
||||
end,
|
||||
|
||||
GetDuration = function(self)
|
||||
return self.Duration
|
||||
end,
|
||||
|
||||
GetProgressByTimer = function(self)
|
||||
return self.Timer
|
||||
end,
|
||||
|
||||
SetOrder = function(self, order)
|
||||
self.Order = order or 1
|
||||
|
||||
if (order > self.Group.MaxOrder) then
|
||||
self.Group.MaxOrder = order
|
||||
end
|
||||
end,
|
||||
|
||||
GetOrder = function(self)
|
||||
return self.Order
|
||||
end,
|
||||
|
||||
GetParent = function(self)
|
||||
return self.Parent
|
||||
end,
|
||||
|
||||
SetScript = function(self, handler, func)
|
||||
handler = strlower(handler)
|
||||
|
||||
if (not Callbacks[handler]) then
|
||||
return
|
||||
end
|
||||
|
||||
Callbacks[handler][self] = func
|
||||
end,
|
||||
|
||||
GetScript = function(self, handler)
|
||||
handler = strlower(handler)
|
||||
|
||||
if (Callbacks[handler] and Callbacks[handler][self]) then
|
||||
return Callbacks[handler][self]
|
||||
end
|
||||
end,
|
||||
|
||||
Callback = function(self, handler)
|
||||
handler = strlower(handler)
|
||||
|
||||
if Callbacks[handler][self] then
|
||||
Callbacks[handler][self](self)
|
||||
end
|
||||
end,
|
||||
},
|
||||
|
||||
move = {
|
||||
SetOffset = function(self, x, y)
|
||||
self.XSetting = x or 0
|
||||
self.YSetting = y or 0
|
||||
end,
|
||||
|
||||
GetOffset = function(self)
|
||||
return self.XSetting, self.YSetting
|
||||
end,
|
||||
|
||||
SetRounded = function(self, flag)
|
||||
self.IsRounded = flag
|
||||
end,
|
||||
|
||||
GetRounded = function(self)
|
||||
return self.IsRounded
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.XOffset, self.YOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:ClearAllPoints()
|
||||
self.Parent:SetPoint(self.A1, self.P, self.A2, self.StartX, self.StartY)
|
||||
end,
|
||||
},
|
||||
|
||||
fade = {
|
||||
SetChange = function(self, alpha)
|
||||
self.EndAlphaSetting = alpha or 0
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndAlphaSetting
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.AlphaOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:SetAlpha(self.StartAlpha)
|
||||
end,
|
||||
},
|
||||
|
||||
height = {
|
||||
SetChange = function(self, height)
|
||||
self.EndHeightSetting = height or 0
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndHeightSetting
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.HeightOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:SetHeight(self.StartHeight)
|
||||
end,
|
||||
},
|
||||
|
||||
width = {
|
||||
SetChange = function(self, width)
|
||||
self.EndWidthSetting = width or 0
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndWidthSetting
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.WidthOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:SetWidth(self.StartWidth)
|
||||
end,
|
||||
},
|
||||
|
||||
color = {
|
||||
SetChange = function(self, r, g, b)
|
||||
self.EndRSetting = r or 1
|
||||
self.EndGSetting = g or 1
|
||||
self.EndBSetting = b or 1
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndRSetting, self.EndGSetting, self.EndBSetting
|
||||
end,
|
||||
|
||||
SetColorType = function(self, type)
|
||||
type = strlower(type)
|
||||
|
||||
self.ColorType = Set[type] and type or "border"
|
||||
end,
|
||||
|
||||
GetColorType = function(self)
|
||||
return self.ColorType
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.ColorOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
Set[self.ColorType](self.Parent, self.StartR, self.StartG, self.StartB)
|
||||
end,
|
||||
},
|
||||
|
||||
progress = {
|
||||
SetChange = function(self, value)
|
||||
self.EndValueSetting = value or 0
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndValueSetting
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.ValueOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:SetValue(self.StartValue)
|
||||
end,
|
||||
},
|
||||
|
||||
number = {
|
||||
SetChange = function(self, value)
|
||||
self.EndNumberSetting = value or 0
|
||||
end,
|
||||
|
||||
GetChange = function(self)
|
||||
return self.EndNumberSetting
|
||||
end,
|
||||
|
||||
SetPrefix = function(self, text)
|
||||
self.Prefix = text or ""
|
||||
end,
|
||||
|
||||
GetPrefix = function(self)
|
||||
return self.Prefix
|
||||
end,
|
||||
|
||||
SetPostfix = function(self, text)
|
||||
self.Postfix = text or ""
|
||||
end,
|
||||
|
||||
GetPostfix = function(self)
|
||||
return self.Postfix
|
||||
end,
|
||||
|
||||
GetProgress = function(self)
|
||||
return self.NumberOffset
|
||||
end,
|
||||
|
||||
Reset = function(self)
|
||||
self.Parent:SetText(self.StartNumer)
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
local GroupMethods = {
|
||||
Play = function(self)
|
||||
-- Play!
|
||||
for i = 1, getn(self.Animations) do
|
||||
if (self.Animations[i].Order == self.Order) then
|
||||
self.Animations[i]:Play()
|
||||
end
|
||||
end
|
||||
|
||||
self.Playing = true
|
||||
self.Paused = false
|
||||
self.Stopped = false
|
||||
end,
|
||||
|
||||
IsPlaying = function(self)
|
||||
return self.Playing
|
||||
end,
|
||||
|
||||
Pause = function(self)
|
||||
-- Only pause current order
|
||||
for i = 1, getn(self.Animations) do
|
||||
if (self.Animations[i].Order == self.Order) then
|
||||
self.Animations[i]:Pause()
|
||||
end
|
||||
end
|
||||
|
||||
self.Playing = false
|
||||
self.Paused = true
|
||||
self.Stopped = false
|
||||
end,
|
||||
|
||||
IsPaused = function(self)
|
||||
return self.Paused
|
||||
end,
|
||||
|
||||
Stop = function(self)
|
||||
for i = 1, getn(self.Animations) do
|
||||
self.Animations[i]:Stop()
|
||||
end
|
||||
|
||||
self.Playing = false
|
||||
self.Paused = false
|
||||
self.Stopped = true
|
||||
end,
|
||||
|
||||
IsStopped = function(self)
|
||||
return self.Stopped
|
||||
end,
|
||||
|
||||
SetLooping = function(self, shouldLoop)
|
||||
self.Looping = shouldLoop
|
||||
end,
|
||||
|
||||
GetLooping = function(self)
|
||||
return self.Looping
|
||||
end,
|
||||
|
||||
GetParent = function(self)
|
||||
return self.Parent
|
||||
end,
|
||||
|
||||
CheckOrder = function(self)
|
||||
-- Check if we're done all animations at the current order, then proceed to the next order.
|
||||
local NumAtOrder = 0
|
||||
local NumDoneAtOrder = 0
|
||||
|
||||
for i = 1, getn(self.Animations) do
|
||||
if (self.Animations[i].Order == self.Order) then
|
||||
NumAtOrder = NumAtOrder + 1
|
||||
|
||||
if (not self.Animations[i].Playing) then
|
||||
NumDoneAtOrder = NumDoneAtOrder + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- All the animations at x order finished, go to next order
|
||||
if (NumAtOrder == NumDoneAtOrder) then
|
||||
self.Order = self.Order + 1
|
||||
|
||||
-- We exceeded max order, reset to 1 and bail the function, or restart if we're looping
|
||||
if (self.Order > self.MaxOrder) then
|
||||
self.Order = 1
|
||||
|
||||
if (self.Stopped or not self.Looping) then
|
||||
self.Playing = false
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Play!
|
||||
for i = 1, getn(self.Animations) do
|
||||
if (self.Animations[i].Order == self.Order) then
|
||||
self.Animations[i]:Play()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
CreateAnimation = function(self, type)
|
||||
type = strlower(type)
|
||||
|
||||
if (not AnimTypes[type]) then
|
||||
return
|
||||
end
|
||||
|
||||
local Animation = {}
|
||||
|
||||
-- General methods
|
||||
for key, func in pairs(AnimMethods.All) do
|
||||
Animation[key] = func
|
||||
end
|
||||
|
||||
-- Animation specific methods
|
||||
if AnimMethods[type] then
|
||||
for key, func in pairs(AnimMethods[type]) do
|
||||
Animation[key] = func
|
||||
end
|
||||
end
|
||||
|
||||
-- Set some attributes and defaults
|
||||
Animation.Paused = false
|
||||
Animation.Playing = false
|
||||
Animation.Stopped = false
|
||||
Animation.Looping = false
|
||||
Animation.Type = type
|
||||
Animation.Group = self
|
||||
Animation.Parent = self.Parent
|
||||
Animation.Order = 1
|
||||
Animation.Duration = 0.3
|
||||
Animation.Smoothing = "none"
|
||||
Animation.Update = UpdateFuncs[type]
|
||||
|
||||
tinsert(self.Animations, Animation)
|
||||
|
||||
return Animation
|
||||
end,
|
||||
}
|
||||
|
||||
CreateAnimationGroup = function(parent)
|
||||
local Group = {Animations = {}}
|
||||
|
||||
-- Add methods to the group
|
||||
for key, func in pairs(GroupMethods) do
|
||||
Group[key] = func
|
||||
end
|
||||
|
||||
Group.Parent = parent
|
||||
Group.Playing = false
|
||||
Group.Paused = false
|
||||
Group.Stopped = false
|
||||
Group.Order = 1
|
||||
Group.MaxOrder = 1
|
||||
|
||||
return Group
|
||||
end
|
||||
|
||||
-- Movement
|
||||
UpdateFuncs["move"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
|
||||
if self.IsRounded then
|
||||
self.ModTimer = Smoothing[self.Smoothing](self.Timer, 0, self.Duration, self.Duration)
|
||||
self.XOffset = self.StartX - (-1) * (self.XChange * (1 - cos(90 * self.ModTimer / self.Duration)))
|
||||
self.YOffset = self.StartY + self.YChange * sin(90 * self.ModTimer / self.Duration)
|
||||
else
|
||||
self.XOffset = Smoothing[self.Smoothing](self.Timer, self.StartX, self.XChange, self.Duration)
|
||||
self.YOffset = Smoothing[self.Smoothing](self.Timer, self.StartY, self.YChange, self.Duration)
|
||||
end
|
||||
|
||||
self.Parent:SetPoint(self.A1, self.P, self.A2, (self.EndX ~= 0 and self.XOffset or self.StartX), (self.EndY ~= 0 and self.YOffset or self.StartY))
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetPoint(self.A1, self.P, self.A2, self.EndX, self.EndY)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["move"] = function(self)
|
||||
if self:IsPlaying() then
|
||||
return
|
||||
end
|
||||
|
||||
local A1, P, A2, X, Y = self.Parent:GetPoint()
|
||||
|
||||
self.Timer = 0
|
||||
self.A1 = A1
|
||||
self.P = P
|
||||
self.A2 = A2
|
||||
self.StartX = X
|
||||
self.EndX = X + self.XSetting or 0
|
||||
self.StartY = Y
|
||||
self.EndY = Y + self.YSetting or 0
|
||||
self.XChange = self.EndX - self.StartX
|
||||
self.YChange = self.EndY - self.StartY
|
||||
|
||||
if self.IsRounded then
|
||||
if (self.XChange == 0 or self.YChange == 0) then -- Double check if we're valid to be rounded
|
||||
self.IsRounded = false
|
||||
else
|
||||
self.ModTimer = 0
|
||||
end
|
||||
end
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Fade
|
||||
UpdateFuncs["fade"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.AlphaOffset = Smoothing[self.Smoothing](self.Timer, self.StartAlpha, self.Change, self.Duration)
|
||||
self.Parent:SetAlpha(self.AlphaOffset)
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetAlpha(self.EndAlpha)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["fade"] = function(self)
|
||||
if self:IsPlaying() then
|
||||
return
|
||||
end
|
||||
|
||||
self.Timer = 0
|
||||
self.StartAlpha = self.Parent:GetAlpha() or 1
|
||||
self.EndAlpha = self.EndAlphaSetting or 0
|
||||
self.Change = self.EndAlpha - self.StartAlpha
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Height
|
||||
UpdateFuncs["height"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.HeightOffset = Smoothing[self.Smoothing](self.Timer, self.StartHeight, self.HeightChange, self.Duration)
|
||||
self.Parent:SetHeight(self.HeightOffset)
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetHeight(self.EndHeight)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["height"] = function(self)
|
||||
if self:IsPlaying() then
|
||||
return
|
||||
end
|
||||
|
||||
self.Timer = 0
|
||||
self.StartHeight = self.Parent:GetHeight() or 0
|
||||
self.EndHeight = self.EndHeightSetting or 0
|
||||
self.HeightChange = self.EndHeight - self.StartHeight
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Width
|
||||
UpdateFuncs["width"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.WidthOffset = Smoothing[self.Smoothing](self.Timer, self.StartWidth, self.WidthChange, self.Duration)
|
||||
self.Parent:SetWidth(self.WidthOffset)
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetWidth(self.EndWidth)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["width"] = function(self)
|
||||
if self:IsPlaying() then
|
||||
return
|
||||
end
|
||||
|
||||
self.Timer = 0
|
||||
self.StartWidth = self.Parent:GetWidth() or 0
|
||||
self.EndWidth = self.EndWidthSetting or 0
|
||||
self.WidthChange = self.EndWidth - self.StartWidth
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Color
|
||||
UpdateFuncs["color"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.ColorOffset = Smoothing[self.Smoothing](self.Timer, 0, self.Duration, self.Duration)
|
||||
Set[self.ColorType](self.Parent, GetColor(self.Timer / self.Duration, self.StartR, self.StartG, self.StartB, self.EndR, self.EndG, self.EndB))
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
Set[self.ColorType](self.Parent, self.EndR, self.EndG, self.EndB)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["color"] = function(self)
|
||||
self.Timer = 0
|
||||
self.ColorType = self.ColorType or "backdrop"
|
||||
self.StartR, self.StartG, self.StartB = Get[self.ColorType](self.Parent)
|
||||
self.EndR = self.EndRSetting or 1
|
||||
self.EndG = self.EndGSetting or 1
|
||||
self.EndB = self.EndBSetting or 1
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Progress
|
||||
UpdateFuncs["progress"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.ValueOffset = Smoothing[self.Smoothing](self.Timer, self.StartValue, self.ProgressChange, self.Duration)
|
||||
self.Parent:SetValue(self.ValueOffset)
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetValue(self.EndValue)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["progress"] = function(self)
|
||||
self.Timer = 0
|
||||
self.StartValue = self.Parent:GetValue() or 0
|
||||
self.EndValue = self.EndValueSetting or 0
|
||||
self.ProgressChange = self.EndValue - self.StartValue
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Sleep
|
||||
UpdateFuncs["sleep"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["sleep"] = function(self)
|
||||
self.Timer = 0
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
-- Number
|
||||
UpdateFuncs["number"] = function(self, elapsed, i)
|
||||
self.Timer = self.Timer + elapsed
|
||||
self.NumberOffset = Smoothing[self.Smoothing](self.Timer, self.StartNumber, self.NumberChange, self.Duration)
|
||||
self.Parent:SetText(self.Prefix..floor(self.NumberOffset)..self.Postfix)
|
||||
|
||||
if (self.Timer >= self.Duration) then
|
||||
tremove(Updater, i)
|
||||
self.Parent:SetText(self.Prefix..floor(self.EndNumber)..self.Postfix)
|
||||
self.Playing = false
|
||||
self:Callback("OnFinished")
|
||||
self.Group:CheckOrder()
|
||||
end
|
||||
end
|
||||
|
||||
AnimTypes["number"] = function(self)
|
||||
self.Timer = 0
|
||||
self.StartNumber = tonumber(self.Parent:GetText()) or 0
|
||||
self.EndNumber = self.EndNumberSetting or 0
|
||||
self.NumberChange = self.EndNumberSetting - self.StartNumber
|
||||
self.Prefix = self.Prefix or ""
|
||||
self.Postfix = self.Postfix or ""
|
||||
|
||||
StartUpdating(self)
|
||||
end
|
||||
|
||||
_G["_LibAnim"] = Version
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibAnim.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,212 @@
|
||||
--[[
|
||||
Name: LibBase64-1.0
|
||||
Author(s): ckknight (ckknight@gmail.com)
|
||||
Website: http://www.wowace.com/projects/libbase64-1-0/
|
||||
Description: A library to encode and decode Base64 strings
|
||||
License: MIT
|
||||
]]
|
||||
|
||||
local LibBase64 = LibStub:NewLibrary("LibBase64-1.0-ElvUI", 1)
|
||||
|
||||
if not LibBase64 then
|
||||
return
|
||||
end
|
||||
|
||||
local _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
local byteToNum = {}
|
||||
local numToChar = {}
|
||||
for i = 1, #_chars do
|
||||
numToChar[i - 1] = _chars:sub(i, i)
|
||||
byteToNum[_chars:byte(i)] = i - 1
|
||||
end
|
||||
_chars = nil
|
||||
local A_byte = ("A"):byte()
|
||||
local Z_byte = ("Z"):byte()
|
||||
local a_byte = ("a"):byte()
|
||||
local z_byte = ("z"):byte()
|
||||
local zero_byte = ("0"):byte()
|
||||
local nine_byte = ("9"):byte()
|
||||
local plus_byte = ("+"):byte()
|
||||
local slash_byte = ("/"):byte()
|
||||
local equals_byte = ("="):byte()
|
||||
local whitespace = {
|
||||
[(" "):byte()] = true,
|
||||
[("\t"):byte()] = true,
|
||||
[("\n"):byte()] = true,
|
||||
[("\r"):byte()] = true,
|
||||
}
|
||||
|
||||
local t = {}
|
||||
|
||||
--- Encode a normal bytestring into a Base64-encoded string
|
||||
-- @param text a bytestring, can be binary data
|
||||
-- @param maxLineLength This should be a multiple of 4, greater than 0 or nil. If non-nil, it will break up the output into lines no longer than the given number of characters. 76 is recommended.
|
||||
-- @param lineEnding a string to end each line with. This is "\r\n" by default.
|
||||
-- @usage LibBase64.Encode("Hello, how are you doing today?") == "SGVsbG8sIGhvdyBhcmUgeW91IGRvaW5nIHRvZGF5Pw=="
|
||||
-- @return a Base64-encoded string
|
||||
function LibBase64:Encode(text, maxLineLength, lineEnding)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `Encode'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
end
|
||||
|
||||
if maxLineLength == nil then
|
||||
-- do nothing
|
||||
elseif type(maxLineLength) ~= "number" then
|
||||
error(("Bad argument #2 to `Encode'. Expected %q or %q, got %q"):format("number", "nil", type(maxLineLength)), 2)
|
||||
elseif (maxLineLength % 4) ~= 0 then
|
||||
error(("Bad argument #2 to `Encode'. Expected a multiple of 4, got %s"):format(maxLineLength), 2)
|
||||
elseif maxLineLength <= 0 then
|
||||
error(("Bad argument #2 to `Encode'. Expected a number > 0, got %s"):format(maxLineLength), 2)
|
||||
end
|
||||
|
||||
if lineEnding == nil then
|
||||
lineEnding = "\r\n"
|
||||
elseif type(lineEnding) ~= "string" then
|
||||
error(("Bad argument #3 to `Encode'. Expected %q, got %q"):format("string", type(lineEnding)), 2)
|
||||
end
|
||||
|
||||
local currentLength = 0
|
||||
|
||||
for i = 1, #text, 3 do
|
||||
local a, b, c = text:byte(i, i+2)
|
||||
local nilNum = 0
|
||||
if not b then
|
||||
nilNum = 2
|
||||
b = 0
|
||||
c = 0
|
||||
elseif not c then
|
||||
nilNum = 1
|
||||
c = 0
|
||||
end
|
||||
local num = a * 2^16 + b * 2^8 + c
|
||||
|
||||
local d = num % 2^6
|
||||
num = (num - d) / 2^6
|
||||
|
||||
local c = num % 2^6
|
||||
num = (num - c) / 2^6
|
||||
|
||||
local b = num % 2^6
|
||||
num = (num - b) / 2^6
|
||||
|
||||
local a = num % 2^6
|
||||
|
||||
t[#t+1] = numToChar[a]
|
||||
|
||||
t[#t+1] = numToChar[b]
|
||||
|
||||
t[#t+1] = (nilNum >= 2) and "=" or numToChar[c]
|
||||
|
||||
t[#t+1] = (nilNum >= 1) and "=" or numToChar[d]
|
||||
|
||||
currentLength = currentLength + 4
|
||||
if maxLineLength and (currentLength % maxLineLength) == 0 then
|
||||
t[#t+1] = lineEnding
|
||||
end
|
||||
end
|
||||
|
||||
local s = table.concat(t)
|
||||
for i = 1, #t do
|
||||
t[i] = nil
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local t2 = {}
|
||||
|
||||
--- Decode a Base64-encoded string into a bytestring
|
||||
-- this will raise an error if the data passed in is not a Base64-encoded string
|
||||
-- this will ignore whitespace, but not invalid characters
|
||||
-- @param text a Base64-encoded string
|
||||
-- @usage LibBase64.Encode("SGVsbG8sIGhvdyBhcmUgeW91IGRvaW5nIHRvZGF5Pw==") == "Hello, how are you doing today?"
|
||||
-- @return a bytestring
|
||||
function LibBase64:Decode(text)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `Decode'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
end
|
||||
|
||||
for i = 1, #text do
|
||||
local byte = text:byte(i)
|
||||
if whitespace[byte] or byte == equals_byte then
|
||||
-- do nothing
|
||||
else
|
||||
local num = byteToNum[byte]
|
||||
if not num then
|
||||
for i = 1, #t2 do
|
||||
t2[k] = nil
|
||||
end
|
||||
|
||||
error(("Bad argument #1 to `Decode'. Received an invalid char: %q"):format(text:sub(i, i)), 2)
|
||||
end
|
||||
t2[#t2+1] = num
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #t2, 4 do
|
||||
local a, b, c, d = t2[i], t2[i+1], t2[i+2], t2[i+3]
|
||||
|
||||
local nilNum = 0
|
||||
if not c then
|
||||
nilNum = 2
|
||||
c = 0
|
||||
d = 0
|
||||
elseif not d then
|
||||
nilNum = 1
|
||||
d = 0
|
||||
end
|
||||
|
||||
local num = a * 2^18 + b * 2^12 + c * 2^6 + d
|
||||
|
||||
local c = num % 2^8
|
||||
num = (num - c) / 2^8
|
||||
|
||||
local b = num % 2^8
|
||||
num = (num - b) / 2^8
|
||||
|
||||
local a = num % 2^8
|
||||
|
||||
t[#t+1] = string.char(a)
|
||||
if nilNum < 2 then
|
||||
t[#t+1] = string.char(b)
|
||||
end
|
||||
if nilNum < 1 then
|
||||
t[#t+1] = string.char(c)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #t2 do
|
||||
t2[i] = nil
|
||||
end
|
||||
|
||||
local s = table.concat(t)
|
||||
|
||||
for i = 1, #t do
|
||||
t[i] = nil
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
function LibBase64:IsBase64(text)
|
||||
if type(text) ~= "string" then
|
||||
error(("Bad argument #1 to `IsBase64'. Expected %q, got %q"):format("string", type(text)), 2)
|
||||
end
|
||||
|
||||
if #text % 4 ~= 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
for i = 1, #text do
|
||||
local byte = text:byte(i)
|
||||
if whitespace[byte] or byte == equals_byte then
|
||||
-- do nothing
|
||||
else
|
||||
local num = byteToNum[byte]
|
||||
if not num then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibBase64-1.0.lua"/>
|
||||
</Ui>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibCompress.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
assert(LibStub, "LibDataBroker-1.1 requires LibStub")
|
||||
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
|
||||
|
||||
local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
|
||||
if not lib then return end
|
||||
oldminor = oldminor or 0
|
||||
|
||||
|
||||
lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
|
||||
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
|
||||
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
|
||||
|
||||
if oldminor < 2 then
|
||||
lib.domt = {
|
||||
__metatable = "access denied",
|
||||
__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
|
||||
}
|
||||
end
|
||||
|
||||
if oldminor < 3 then
|
||||
lib.domt.__newindex = function(self, key, value)
|
||||
if not attributestorage[self] then attributestorage[self] = {} end
|
||||
if attributestorage[self][key] == value then return end
|
||||
attributestorage[self][key] = value
|
||||
local name = namestorage[self]
|
||||
if not name then return end
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
|
||||
callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 2 then
|
||||
function lib:NewDataObject(name, dataobj)
|
||||
if self.proxystorage[name] then return end
|
||||
|
||||
if dataobj then
|
||||
assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
|
||||
self.attributestorage[dataobj] = {}
|
||||
for i,v in pairs(dataobj) do
|
||||
self.attributestorage[dataobj][i] = v
|
||||
dataobj[i] = nil
|
||||
end
|
||||
end
|
||||
dataobj = setmetatable(dataobj or {}, self.domt)
|
||||
self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
|
||||
self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
|
||||
return dataobj
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 1 then
|
||||
function lib:DataObjectIterator()
|
||||
return pairs(self.proxystorage)
|
||||
end
|
||||
|
||||
function lib:GetDataObjectByName(dataobjectname)
|
||||
return self.proxystorage[dataobjectname]
|
||||
end
|
||||
|
||||
function lib:GetNameByDataObject(dataobject)
|
||||
return self.namestorage[dataobject]
|
||||
end
|
||||
end
|
||||
|
||||
if oldminor < 4 then
|
||||
local next = pairs(attributestorage)
|
||||
function lib:pairs(dataobject_or_name)
|
||||
local t = type(dataobject_or_name)
|
||||
assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
|
||||
|
||||
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
|
||||
assert(attributestorage[dataobj], "Data object not found")
|
||||
|
||||
return next, attributestorage[dataobj], nil
|
||||
end
|
||||
|
||||
local ipairs_iter = ipairs(attributestorage)
|
||||
function lib:ipairs(dataobject_or_name)
|
||||
local t = type(dataobject_or_name)
|
||||
assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
|
||||
|
||||
local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
|
||||
assert(attributestorage[dataobj], "Data object not found")
|
||||
|
||||
return ipairs_iter, attributestorage[dataobj], 0
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibDataBroker-1.1.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,226 @@
|
||||
local MAJOR, MINOR = "LibElvUIPlugin-1.0", 13
|
||||
local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
if not lib then return end
|
||||
|
||||
--Cache global variables
|
||||
--Lua functions
|
||||
local pairs, tonumber = pairs, tonumber
|
||||
local format, strsplit = format, strsplit
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame;
|
||||
local GetNumPartyMembers, GetNumRaidMembers = GetNumPartyMembers, GetNumRaidMembers
|
||||
local GetAddOnMetadata = GetAddOnMetadata
|
||||
local IsAddOnLoaded = IsAddOnLoaded
|
||||
local SendAddonMessage = SendAddonMessage
|
||||
|
||||
--Global variables that we don't cache, list them here for the mikk's Find Globals script
|
||||
-- GLOBALS: ElvUI
|
||||
|
||||
lib.plugins = {}
|
||||
lib.index = 0
|
||||
lib.prefix = "ElvUIPluginVC"
|
||||
|
||||
-- MULTI Language Support (Default Language: English)
|
||||
local MSG_OUTDATED = "Your version of %s is out of date (latest is version %s). You can download the latest version from https://github.com/ElvUI-Vanilla/ElvUI/"
|
||||
local HDR_CONFIG = "Plugins"
|
||||
local HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - Plugins Loaded (|cff2BC226Green|r means you have current version, |cffFF0000Red|r means out of date)"
|
||||
local INFO_BY = "by"
|
||||
local INFO_VERSION = "Version:"
|
||||
local INFO_NEW = "Newest:"
|
||||
local LIBRARY = "Library"
|
||||
|
||||
if GetLocale() == "deDE" then -- German Translation
|
||||
MSG_OUTDATED = "Deine Version von %s ist veraltet (akutelle Version ist %s). Du kannst die aktuelle Version von https://github.com/ElvUI-Vanilla/ElvUI/ herunterrladen."
|
||||
HDR_CONFIG = "Plugins"
|
||||
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - Plugins geladen (|cff2BC226Grün|r bedeutet du hast die aktuelle Version, |cffFF0000Rot|r bedeutet es ist veraltet)"
|
||||
INFO_BY = "von"
|
||||
INFO_VERSION = "Version:"
|
||||
INFO_NEW = "Neuste:"
|
||||
LIBRARY = "Bibliothek"
|
||||
end
|
||||
|
||||
if GetLocale() == "ruRU" then -- Russian Translations
|
||||
MSG_OUTDATED = "Ваша версия %s устарела (последняя версия %s). Вы можете скачать последнюю версию на https://github.com/ElvUI-Vanilla/ElvUI/"
|
||||
HDR_CONFIG = "Плагины"
|
||||
HDR_INFORMATION = "LibElvUIPlugin-1.0.%d - Загруженные плагины (|cff2BC226Зеленый|r означает, что у вас последняя версия, |cffFF0000Красный|r - устаревшая)"
|
||||
INFO_BY = "от"
|
||||
INFO_VERSION = "Версия:"
|
||||
INFO_NEW = "Последняя:"
|
||||
LIBRARY = "Библиотека"
|
||||
end
|
||||
|
||||
--
|
||||
-- Plugin table format:
|
||||
-- { name (string) - The name of the plugin,
|
||||
-- version (string) - The version of the plugin,
|
||||
-- optionCallback (string) - The callback to call when ElvUI_Config is loaded
|
||||
-- }
|
||||
--
|
||||
|
||||
--
|
||||
-- RegisterPlugin(name,callback)
|
||||
-- Registers a module with the given name and option callback, pulls version info from metadata
|
||||
--
|
||||
|
||||
function lib:RegisterPlugin(name,callback, isLib)
|
||||
local plugin = {}
|
||||
plugin.name = name
|
||||
plugin.version = name == MAJOR and MINOR or GetAddOnMetadata(name, "Version")
|
||||
if isLib then plugin.isLib = true; plugin.version = 1 end
|
||||
plugin.callback = callback
|
||||
lib.plugins[name] = plugin
|
||||
local loaded = IsAddOnLoaded("ElvUI_Config")
|
||||
|
||||
if not lib.vcframe then
|
||||
local f = CreateFrame('Frame')
|
||||
f:RegisterEvent("RAID_ROSTER_UPDATE");
|
||||
f:RegisterEvent("PARTY_MEMBERS_CHANGED");
|
||||
f:RegisterEvent("CHAT_MSG_ADDON")
|
||||
f:SetScript("OnEvent", lib.VersionCheck)
|
||||
lib.vcframe = f
|
||||
end
|
||||
|
||||
if not loaded then
|
||||
if not lib.ConfigFrame then
|
||||
local configFrame = CreateFrame("Frame")
|
||||
configFrame:RegisterEvent("ADDON_LOADED")
|
||||
configFrame:SetScript("OnEvent", function(self,event,addon)
|
||||
if addon == "ElvUI_Config" then
|
||||
for _, plugin in pairs(lib.plugins) do
|
||||
if(plugin.callback) then
|
||||
plugin.callback()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
lib.ConfigFrame = configFrame
|
||||
end
|
||||
elseif loaded then
|
||||
-- Need to update plugins list
|
||||
if name ~= MAJOR then
|
||||
ElvUI[1].Options.args.plugins.args.plugins.name = lib:GeneratePluginList()
|
||||
end
|
||||
callback()
|
||||
end
|
||||
|
||||
return plugin
|
||||
end
|
||||
|
||||
function lib:GetPluginOptions()
|
||||
ElvUI[1].Options.args.plugins = {
|
||||
order = -10,
|
||||
type = "group",
|
||||
name = HDR_CONFIG,
|
||||
guiInline = false,
|
||||
args = {
|
||||
pluginheader = {
|
||||
order = 1,
|
||||
type = "header",
|
||||
name = format(HDR_INFORMATION, MINOR),
|
||||
},
|
||||
plugins = {
|
||||
order = 2,
|
||||
type = "description",
|
||||
name = lib:GeneratePluginList(),
|
||||
},
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function lib:GenerateVersionCheckMessage()
|
||||
local list = ""
|
||||
for _, plugin in pairs(lib.plugins) do
|
||||
if plugin.name ~= MAJOR then
|
||||
list = list..plugin.name.."="..plugin.version..";"
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
local function SendPluginVersionCheck(self)
|
||||
lib:SendPluginVersionCheck(lib:GenerateVersionCheckMessage())
|
||||
|
||||
if self["ElvUIPluginSendMSGTimer"] then
|
||||
self:CancelTimer(self["ElvUIPluginSendMSGTimer"])
|
||||
self["ElvUIPluginSendMSGTimer"] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function lib:VersionCheck(event, prefix, message, channel, sender)
|
||||
if(not ElvUI[1].global.general.versionCheck) then return; end
|
||||
|
||||
local E = ElvUI[1]
|
||||
if event == "CHAT_MSG_ADDON" then
|
||||
if sender == E.myname or not sender or prefix ~= lib.prefix then return end
|
||||
if not E["pluginRecievedOutOfDateMessage"] then
|
||||
for _, p in pairs({strsplit(";",message)}) do
|
||||
local name, version = p:match("([%w_]+)=([%d%p]+)")
|
||||
if lib.plugins[name] then
|
||||
local plugin = lib.plugins[name]
|
||||
if plugin.version ~= "BETA" and version ~= nil and tonumber(version) ~= nil and plugin.version ~= nil and tonumber(plugin.version) ~= nil and tonumber(version) > tonumber(plugin.version) then
|
||||
plugin.old = true
|
||||
plugin.newversion = tonumber(version)
|
||||
local Pname = GetAddOnMetadata(plugin.name, "Title")
|
||||
E:Print(format(MSG_OUTDATED,Pname,plugin.newversion))
|
||||
E["pluginRecievedOutOfDateMessage"] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
E.SendPluginVersionCheck = E.SendPluginVersionCheck or SendPluginVersionCheck
|
||||
E["ElvUIPluginSendMSGTimer"] = E:ScheduleTimer("SendPluginVersionCheck", 2)
|
||||
end
|
||||
end
|
||||
|
||||
function lib:GeneratePluginList()
|
||||
local list = ""
|
||||
local E = ElvUI[1]
|
||||
for _, plugin in pairs(lib.plugins) do
|
||||
if plugin.name ~= MAJOR then
|
||||
local author = GetAddOnMetadata(plugin.name, "Author")
|
||||
local Pname = GetAddOnMetadata(plugin.name, "Title") or plugin.name
|
||||
local color = plugin.old and E:RGBToHex(1,0,0) or E:RGBToHex(0,1,0)
|
||||
list = list..Pname
|
||||
if author then
|
||||
list = list.." ".. INFO_BY .." "..author
|
||||
end
|
||||
list = list..color.." - "..(plugin.isLib and LIBRARY or INFO_VERSION .." "..plugin.version)
|
||||
if plugin.old then
|
||||
list = list.." ("..INFO_NEW .." "..plugin.newversion..")"
|
||||
end
|
||||
list = list.."|r\n"
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function lib:SendPluginVersionCheck(message)
|
||||
local plist = {strsplit(";",message)}
|
||||
local m = ""
|
||||
local delay = 1
|
||||
local E = ElvUI[1]
|
||||
for _, p in pairs(plist) do
|
||||
if(getn(m..p..";") < 230) then
|
||||
m = m..p..";"
|
||||
else
|
||||
local numParty, numRaid = GetNumPartyMembers(), GetNumRaidMembers();
|
||||
if(numRaid > 0) then
|
||||
E:Delay(delay, SendAddonMessage(lib.prefix, m, "RAID"))
|
||||
elseif(numParty > 0) then
|
||||
E:Delay(delay, SendAddonMessage(lib.prefix, m, "PARTY"))
|
||||
end
|
||||
m = p..";"
|
||||
delay = delay + 1
|
||||
end
|
||||
end
|
||||
-- Send the last message
|
||||
local numParty, numRaid = GetNumPartyMembers(), GetNumRaidMembers();
|
||||
if(numRaid > 0) then
|
||||
E:Delay(delay+1, SendAddonMessage(lib.prefix, m, "RAID"))
|
||||
elseif(numParty > 0) then
|
||||
E:Delay(delay+1, SendAddonMessage(lib.prefix, m, "PARTY"))
|
||||
end
|
||||
end
|
||||
|
||||
lib:RegisterPlugin(MAJOR, lib.GetPluginOptions)
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibElvUIPlugin-1.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,203 @@
|
||||
--[[
|
||||
Copyright 2013 João Cardoso
|
||||
CustomSearch is distributed under the terms of the GNU General Public License (Version 3).
|
||||
As a special exception, the copyright holders of this library give you permission to embed it
|
||||
with independent modules to produce an addon, regardless of the license terms of these
|
||||
independent modules, and to copy and distribute the resulting software under terms of your
|
||||
choice, provided that you also meet, for each embedded independent module, the terms and
|
||||
conditions of the license of that module. Permission is not granted to modify this library.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the library. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
This file is part of CustomSearch.
|
||||
--]]
|
||||
|
||||
local Lib = LibStub:NewLibrary('CustomSearch-1.0', 9)
|
||||
if not Lib then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--[[ Parsing ]]--
|
||||
|
||||
function Lib:Matches(object, search, filters)
|
||||
if object then
|
||||
self.filters = filters
|
||||
self.object = object
|
||||
|
||||
return self:MatchAll(search or '')
|
||||
end
|
||||
end
|
||||
|
||||
function Lib:MatchAll(search)
|
||||
for phrase in self:Clean(search):gmatch('[^&]+') do
|
||||
if not self:MatchAny(phrase) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Lib:MatchAny(search)
|
||||
for phrase in search:gmatch('[^|]+') do
|
||||
if self:Match(phrase) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lib:Match(search)
|
||||
local tag, rest = search:match('^%s*(%S+):(.*)$')
|
||||
if tag then
|
||||
tag = '^' .. tag
|
||||
search = rest
|
||||
end
|
||||
|
||||
local words = search:gmatch('%S+')
|
||||
local failed
|
||||
|
||||
for word in words do
|
||||
if word == self.OR then
|
||||
if failed then
|
||||
failed = false
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
else
|
||||
local negate, rest = word:match('^([!~]=*)(.*)$')
|
||||
if negate or word == self.NOT_MATCH then
|
||||
word = rest and rest ~= '' and rest or words() or ''
|
||||
negate = -1
|
||||
else
|
||||
negate = 1
|
||||
end
|
||||
|
||||
local operator, rest = word:match('^(=*[<>]=*)(.*)$')
|
||||
if operator then
|
||||
word = rest ~= '' and rest or words()
|
||||
end
|
||||
|
||||
local result = self:Filter(tag, operator, word) and 1 or -1
|
||||
if result * negate ~= 1 then
|
||||
failed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return not failed
|
||||
end
|
||||
|
||||
|
||||
--[[ Filtering ]]--
|
||||
|
||||
function Lib:Filter(tag, operator, search)
|
||||
if not search then
|
||||
return true
|
||||
end
|
||||
|
||||
if tag then
|
||||
for _, filter in pairs(self.filters) do
|
||||
for _, value in pairs(filter.tags or {}) do
|
||||
if value:find(tag) then
|
||||
return self:UseFilter(filter, operator, search)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, filter in pairs(self.filters) do
|
||||
if not filter.onlyTags and self:UseFilter(filter, operator, search) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lib:UseFilter(filter, operator, search)
|
||||
local data = {filter:canSearch(operator, search, self.object)}
|
||||
if data[1] then
|
||||
return filter:match(self.object, operator, unpack(data))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[ Utilities ]]--
|
||||
|
||||
function Lib:Find(search, ...)
|
||||
for i = 1, select('#', ...) do
|
||||
local text = select(i, ...)
|
||||
if text and self:Clean(text):find(search) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lib:Clean(string)
|
||||
string = string:lower()
|
||||
string = string:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', function(c) return '%'..c end)
|
||||
|
||||
for accent, char in pairs(self.ACCENTS) do
|
||||
string = string:gsub(accent, char)
|
||||
end
|
||||
|
||||
return string
|
||||
end
|
||||
|
||||
function Lib:Compare(op, a, b)
|
||||
if op then
|
||||
if op:find('<') then
|
||||
if op:find('=') then
|
||||
return a <= b
|
||||
end
|
||||
|
||||
return a < b
|
||||
end
|
||||
|
||||
if op:find('>')then
|
||||
if op:find('=') then
|
||||
return a >= b
|
||||
end
|
||||
|
||||
return a > b
|
||||
end
|
||||
end
|
||||
|
||||
return a == b
|
||||
end
|
||||
|
||||
|
||||
--[[ Localization ]]--
|
||||
|
||||
do
|
||||
local no = {enUS = 'Not', frFR = 'Pas', deDE = 'Nicht', ruRU = 'Нет'}
|
||||
local just_or = {enUS = 'Or', frFR = 'Ou', deDE = 'Oder', ruRU = 'Или'}
|
||||
local accents = {
|
||||
a = {'à','â','ã','å'},
|
||||
e = {'è','é','ê','ê','ë'},
|
||||
i = {'ì', 'í', 'î', 'ï'},
|
||||
o = {'ó','ò','ô','õ'},
|
||||
u = {'ù', 'ú', 'û', 'ü'},
|
||||
c = {'ç'}, n = {'ñ'}
|
||||
}
|
||||
|
||||
Lib.ACCENTS = {}
|
||||
for char, accents in pairs(accents) do
|
||||
for _, accent in ipairs(accents) do
|
||||
Lib.ACCENTS[accent] = char
|
||||
end
|
||||
end
|
||||
|
||||
Lib.OR = Lib:Clean(just_or[GetLocale()] or "")
|
||||
Lib.NOT = no[GetLocale()] or NO
|
||||
Lib.NOT_MATCH = Lib:Clean(Lib.NOT)
|
||||
setmetatable(Lib, {__call = Lib.Matches})
|
||||
end
|
||||
|
||||
return Lib
|
||||
@@ -0,0 +1,278 @@
|
||||
--[[
|
||||
ItemSearch
|
||||
An item text search engine of some sort
|
||||
--]]
|
||||
|
||||
local Search = LibStub("CustomSearch-1.0");
|
||||
local Unfit = LibStub("Unfit-1.0");
|
||||
local Lib = LibStub:NewLibrary("LibItemSearch-1.2", 11);
|
||||
if(Lib) then
|
||||
Lib.Filters = {};
|
||||
else
|
||||
return;
|
||||
end
|
||||
|
||||
--[[ User API ]]--
|
||||
|
||||
function Lib:Matches(link, search)
|
||||
return Search(link, search, self.Filters);
|
||||
end
|
||||
|
||||
function Lib:Tooltip(link, search)
|
||||
return link and self.Filters.tip:match(link, nil, search);
|
||||
end
|
||||
|
||||
function Lib:TooltipPhrase(link, search)
|
||||
return link and self.Filters.tipPhrases:match(link, nil, search);
|
||||
end
|
||||
|
||||
function Lib:InSet(link, search)
|
||||
if(IsEquippableItem(link)) then
|
||||
local id = tonumber(link:match("item:(%-?%d+)"));
|
||||
return self:BelongsToSet(id, (search or ""):lower());
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Basics ]]--
|
||||
|
||||
Lib.Filters.name = {
|
||||
tags = {"n", "name"},
|
||||
|
||||
canSearch = function(self, operator, search)
|
||||
return not operator and search;
|
||||
end,
|
||||
|
||||
match = function(self, item, _, search)
|
||||
local name = item:match("%[(.-)%]");
|
||||
return Search:Find(search, name);
|
||||
end
|
||||
};
|
||||
|
||||
Lib.Filters.type = {
|
||||
tags = {"t", "type", "s", "slot"},
|
||||
|
||||
canSearch = function(self, operator, search)
|
||||
return not operator and search;
|
||||
end,
|
||||
|
||||
match = function(self, item, _, search)
|
||||
local type, subType, _, equipSlot = select(6, GetItemInfo(item));
|
||||
return Search:Find(search, type, subType, _G[equipSlot]);
|
||||
end
|
||||
};
|
||||
|
||||
Lib.Filters.level = {
|
||||
tags = {"l", "level", "lvl", "ilvl"},
|
||||
|
||||
canSearch = function(self, _, search)
|
||||
return tonumber(search);
|
||||
end,
|
||||
|
||||
match = function(self, link, operator, num)
|
||||
local lvl = select(4, GetItemInfo(link));
|
||||
if(lvl) then
|
||||
return Search:Compare(operator, lvl, num);
|
||||
end
|
||||
end
|
||||
};
|
||||
|
||||
Lib.Filters.requiredlevel = {
|
||||
tags = {"r", "req", "rl", "reql", "reqlvl"},
|
||||
|
||||
canSearch = function(self, _, search)
|
||||
return tonumber(search);
|
||||
end,
|
||||
|
||||
match = function(self, link, operator, num)
|
||||
local lvl = select(5, GetItemInfo(link));
|
||||
if(lvl) then
|
||||
return Search:Compare(operator, lvl, num);
|
||||
end
|
||||
end
|
||||
};
|
||||
|
||||
--[[ Quality ]]--
|
||||
|
||||
local qualities = {};
|
||||
for i = 0, #ITEM_QUALITY_COLORS do
|
||||
qualities[i] = _G["ITEM_QUALITY" .. i .. "_DESC"]:lower();
|
||||
end
|
||||
|
||||
Lib.Filters.quality = {
|
||||
tags = {"q", "quality"},
|
||||
|
||||
canSearch = function(self, _, search)
|
||||
for i, name in pairs(qualities) do
|
||||
if(name:find(search)) then
|
||||
return i;
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
match = function(self, link, operator, num)
|
||||
local quality = select(3, GetItemInfo(link));
|
||||
return Search:Compare(operator, quality, num);
|
||||
end,
|
||||
};
|
||||
|
||||
--[[ Usable ]]--
|
||||
|
||||
Lib.Filters.usable = {
|
||||
tags = {},
|
||||
|
||||
canSearch = function(self, operator, search)
|
||||
return not operator and search == "usable";
|
||||
end,
|
||||
|
||||
match = function(self, link)
|
||||
if(not Unfit:IsItemUnusable(link)) then
|
||||
local lvl = select(5, GetItemInfo(link));
|
||||
return lvl and (lvl ~= 0 and lvl <= UnitLevel("player"));
|
||||
end
|
||||
end
|
||||
};
|
||||
|
||||
--[[ Tooltip Searches ]]--
|
||||
|
||||
local scanner = LibItemSearchTooltipScanner or CreateFrame("GameTooltip", "LibItemSearchTooltipScanner", UIParent, "GameTooltipTemplate");
|
||||
|
||||
Lib.Filters.tip = {
|
||||
tags = {"tt", "tip", "tooltip"},
|
||||
|
||||
onlyTags = true,
|
||||
|
||||
canSearch = function(self, _, search)
|
||||
return search;
|
||||
end,
|
||||
|
||||
match = function(self, link, _, search)
|
||||
if(link:find("item:")) then
|
||||
scanner:SetOwner(UIParent, "ANCHOR_NONE");
|
||||
scanner:SetHyperlink(link)
|
||||
|
||||
for i = 1, scanner:NumLines() do
|
||||
if(Search:Find(search, _G[scanner:GetName() .. "TextLeft" .. i]:GetText())) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
};
|
||||
|
||||
local escapes = {
|
||||
["|c%x%x%x%x%x%x%x%x"] = "",
|
||||
["|r"] = ""
|
||||
};
|
||||
|
||||
local function CleanString(str)
|
||||
for k, v in pairs(escapes) do
|
||||
str = str:gsub(k, v);
|
||||
end
|
||||
return str;
|
||||
end
|
||||
|
||||
Lib.Filters.tipPhrases = {
|
||||
canSearch = function(self, _, search)
|
||||
return self.keywords[search];
|
||||
end,
|
||||
|
||||
match = function(self, link, _, search)
|
||||
local id = link:match("item:(%d+)");
|
||||
if(not id) then
|
||||
return;
|
||||
end
|
||||
|
||||
local cached = self.cache[search][id];
|
||||
if(cached ~= nil) then
|
||||
return cached;
|
||||
end
|
||||
|
||||
scanner:SetOwner(UIParent, "ANCHOR_NONE");
|
||||
scanner:SetHyperlink(link);
|
||||
|
||||
local matches = false
|
||||
for i = 1, scanner:NumLines() do
|
||||
local text = _G["LibItemSearchTooltipScannerTextLeft" .. i]:GetText();
|
||||
text = CleanString(text);
|
||||
if(search == text) then
|
||||
matches = true;
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
self.cache[search][id] = matches;
|
||||
return matches;
|
||||
end,
|
||||
|
||||
cache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end}),
|
||||
|
||||
keywords = {
|
||||
[ITEM_SOULBOUND:lower()] = ITEM_BIND_ON_PICKUP,
|
||||
["bound"] = ITEM_BIND_ON_PICKUP,
|
||||
["bop"] = ITEM_BIND_ON_PICKUP,
|
||||
["boe"] = ITEM_BIND_ON_EQUIP,
|
||||
["bou"] = ITEM_BIND_ON_USE,
|
||||
["boa"] = ITEM_BIND_TO_ACCOUNT,
|
||||
[QUESTS_LABEL:lower()] = ITEM_BIND_QUEST
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
--[[ Equipment Sets ]]--
|
||||
|
||||
if IsAddOnLoaded("ItemRack") then
|
||||
local sameID = ItemRack.SameID
|
||||
|
||||
function Lib:BelongsToSet(id, search)
|
||||
for name, set in pairs(ItemRackUser.Sets) do
|
||||
if name:sub(1,1) ~= "" and Search:Find(search, name) then
|
||||
for _, item in pairs(set.equip) do
|
||||
if sameID(id, item) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif IsAddOnLoaded("Wardrobe") then
|
||||
function Lib:BelongsToSet(id, search)
|
||||
for _, outfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
|
||||
local name = outfit.OutfitName
|
||||
if Search:Find(search, name) or search == "matchall" then
|
||||
for _, item in pairs(outfit.Item) do
|
||||
if item.IsSlotUsed == 1 and item.ItemID == id then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
function Lib:BelongsToSet(id, search)
|
||||
for i = 1, GetNumEquipmentSets() do
|
||||
local name = GetEquipmentSetInfo(i)
|
||||
if Search:Find(search, name) then
|
||||
local items = GetEquipmentSetItemIDs(name)
|
||||
for _, item in pairs(items) do
|
||||
if id == item then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Lib.Filters.sets = {
|
||||
tags = {"s", "set"},
|
||||
|
||||
canSearch = function(self, operator, search)
|
||||
return not operator and search
|
||||
end,
|
||||
|
||||
match = function(self, link, _, search)
|
||||
return Lib:InSet(link, search)
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<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">
|
||||
<Script file="CustomSearch-1.0\CustomSearch-1.0.lua"/>
|
||||
<Script file="Unfit-1.0\Unfit-1.0.lua"/>
|
||||
<Script file="LibItemSearch-1.2.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,116 @@
|
||||
--[[
|
||||
Copyright 2011-2016 João Cardoso
|
||||
Unfit is distributed under the terms of the GNU General Public License (Version 3).
|
||||
As a special exception, the copyright holders of this library give you permission to embed it
|
||||
with independent modules to produce an addon, regardless of the license terms of these
|
||||
independent modules, and to copy and distribute the resulting software under terms of your
|
||||
choice, provided that you also meet, for each embedded independent module, the terms and
|
||||
conditions of the license of that module. Permission is not granted to modify this library.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the library. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
This file is part of Unfit.
|
||||
--]]
|
||||
|
||||
local Lib = LibStub:NewLibrary('Unfit-1.0', 9)
|
||||
if not Lib then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--[[ Data ]]--
|
||||
|
||||
do
|
||||
local _, Class = UnitClass('player')
|
||||
local Unusable
|
||||
|
||||
if Class == 'DEATHKNIGHT' then
|
||||
Unusable = {
|
||||
{3, 4, 10, 11, 13, 14, 15, 16},
|
||||
{7}
|
||||
}
|
||||
elseif Class == 'DRUID' then
|
||||
Unusable = {
|
||||
{1, 2, 3, 4, 8, 9, 14, 15, 16},
|
||||
{4, 5, 7},
|
||||
true
|
||||
}
|
||||
elseif Class == 'HUNTER' then
|
||||
Unusable = {
|
||||
{5, 6, 16},
|
||||
{5, 6}
|
||||
}
|
||||
elseif Class == 'MAGE' then
|
||||
Unusable = {
|
||||
{1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15},
|
||||
{3, 4, 5, 7},
|
||||
true
|
||||
}
|
||||
elseif Class == 'PALADIN' then
|
||||
Unusable = {
|
||||
{3, 4, 10, 11, 13, 14, 15, 16},
|
||||
{},
|
||||
true
|
||||
}
|
||||
elseif Class == 'PRIEST' then
|
||||
Unusable = {
|
||||
{1, 2, 3, 4, 6, 7, 8, 9, 11, 14, 15},
|
||||
{3, 4, 5, 7},
|
||||
true
|
||||
}
|
||||
elseif Class == 'ROGUE' then
|
||||
Unusable = {
|
||||
{2, 6, 7, 9, 10, 16},
|
||||
{4, 5, 6}
|
||||
}
|
||||
elseif Class == 'SHAMAN' then
|
||||
Unusable = {
|
||||
{3, 4, 7, 8, 9, 14, 15, 16},
|
||||
{5}
|
||||
}
|
||||
elseif Class == 'WARLOCK' then
|
||||
Unusable = {
|
||||
{1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15},
|
||||
{3, 4, 5, 7},
|
||||
true
|
||||
}
|
||||
elseif Class == 'WARRIOR' then
|
||||
Unusable = {{16}, {}}
|
||||
else
|
||||
Unusable = {{}, {}}
|
||||
end
|
||||
|
||||
for class = 1, 2 do
|
||||
local subs = {GetAuctionItemSubClasses(class)}
|
||||
for i, subclass in ipairs(Unusable[class]) do
|
||||
Unusable[subs[subclass]] = true
|
||||
end
|
||||
|
||||
Unusable[class] = nil
|
||||
subs = nil
|
||||
end
|
||||
|
||||
Lib.unusable = Unusable
|
||||
Lib.cannotDual = Unusable[3]
|
||||
end
|
||||
|
||||
--[[ API ]]--
|
||||
|
||||
function Lib:IsItemUnusable(...)
|
||||
if ... then
|
||||
local subclass, _, slot = select(7, GetItemInfo(...))
|
||||
return Lib:IsClassUnusable(subclass, slot)
|
||||
end
|
||||
end
|
||||
|
||||
function Lib:IsClassUnusable(subclass, slot)
|
||||
if subclass then
|
||||
return slot ~= '' and Unusable[subclass] or slot == 'INVTYPE_WEAPONOFFHAND' and Lib.cannotDual
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,237 @@
|
||||
--[[
|
||||
Name: LibSharedMedia-3.0
|
||||
Revision: $Revision: 62 $
|
||||
Author: Elkano (elkano@gmx.de)
|
||||
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com)
|
||||
Website: http://www.wowace.com/projects/libsharedmedia-3-0/
|
||||
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons.
|
||||
Dependencies: LibStub, CallbackHandler-1.0
|
||||
License: LGPL v2.1
|
||||
]]
|
||||
|
||||
local MAJOR, MINOR = "LibSharedMedia-3.0", 2040001 -- 2.4.3 / increase manually on changes
|
||||
local lib = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not lib then return end
|
||||
|
||||
local _G = getfenv(0)
|
||||
|
||||
local pairs = _G.pairs
|
||||
local type = _G.type
|
||||
|
||||
local band = _G.bit.band
|
||||
|
||||
local table_insert = _G.table.insert
|
||||
local table_sort = _G.table.sort
|
||||
|
||||
local locale = GetLocale()
|
||||
local locale_is_western
|
||||
local LOCALE_MASK = 0
|
||||
lib.LOCALE_BIT_koKR = 1
|
||||
lib.LOCALE_BIT_ruRU = 2
|
||||
lib.LOCALE_BIT_zhCN = 4
|
||||
lib.LOCALE_BIT_zhTW = 8
|
||||
lib.LOCALE_BIT_western = 128
|
||||
|
||||
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||
|
||||
lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
|
||||
|
||||
lib.DefaultMedia = lib.DefaultMedia or {}
|
||||
lib.MediaList = lib.MediaList or {}
|
||||
lib.MediaTable = lib.MediaTable or {}
|
||||
lib.MediaType = lib.MediaType or {}
|
||||
lib.OverrideMedia = lib.OverrideMedia or {}
|
||||
|
||||
local defaultMedia = lib.DefaultMedia
|
||||
local mediaList = lib.MediaList
|
||||
local mediaTable = lib.MediaTable
|
||||
local overrideMedia = lib.OverrideMedia
|
||||
|
||||
|
||||
-- create mediatype constants
|
||||
lib.MediaType.BACKGROUND = "background" -- background textures
|
||||
lib.MediaType.BORDER = "border" -- border textures
|
||||
lib.MediaType.FONT = "font" -- fonts
|
||||
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures
|
||||
lib.MediaType.SOUND = "sound" -- sound files
|
||||
|
||||
-- populate lib with default Blizzard data
|
||||
-- BACKGROUND
|
||||
if not lib.MediaTable.background then lib.MediaTable.background = {} end
|
||||
lib.MediaTable.background["None"] = [[]]
|
||||
lib.MediaTable.background["Blizzard Dialog Background"] = [[Interface\DialogFrame\UI-DialogBox-Background]]
|
||||
lib.MediaTable.background["Blizzard Dialog Background Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Background]]
|
||||
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]]
|
||||
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]]
|
||||
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]]
|
||||
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]]
|
||||
lib.MediaTable.background["Solid"] = [[Interface\Buttons\WHITE8X8]]
|
||||
lib.DefaultMedia.background = "None"
|
||||
|
||||
-- BORDER
|
||||
if not lib.MediaTable.border then lib.MediaTable.border = {} end
|
||||
lib.MediaTable.border["None"] = [[]]
|
||||
lib.MediaTable.border["Blizzard Chat Bubble"] = [[Interface\Tooltips\ChatBubble-Backdrop]]
|
||||
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]]
|
||||
lib.MediaTable.border["Blizzard Dialog Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]]
|
||||
lib.MediaTable.border["Blizzard Party"] = [[Interface\CHARACTERFRAME\UI-Party-Border]]
|
||||
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]]
|
||||
lib.DefaultMedia.border = "None"
|
||||
|
||||
-- FONT
|
||||
if not lib.MediaTable.font then lib.MediaTable.font = {} end
|
||||
local SML_MT_font = lib.MediaTable.font
|
||||
if locale == "koKR" then
|
||||
LOCALE_MASK = lib.LOCALE_BIT_koKR
|
||||
--
|
||||
SML_MT_font["굵은 글꼴"] = [[Fonts\2002B.TTF]]
|
||||
SML_MT_font["기본 글꼴"] = [[Fonts\2002.TTF]]
|
||||
SML_MT_font["데미지 글꼴"] = [[Fonts\K_Damage.TTF]]
|
||||
SML_MT_font["퀘스트 글꼴"] = [[Fonts\K_Pagetext.TTF]]
|
||||
--
|
||||
lib.DefaultMedia["font"] = "기본 글꼴" -- someone from koKR please adjust if needed
|
||||
--
|
||||
elseif locale == "zhCN" then
|
||||
LOCALE_MASK = lib.LOCALE_BIT_zhCN
|
||||
--
|
||||
SML_MT_font["伤害数字"] = [[Fonts\ZYKai_C.ttf]]
|
||||
SML_MT_font["默认"] = [[Fonts\ZYKai_T.ttf]]
|
||||
SML_MT_font["聊天"] = [[Fonts\ZYHei.ttf]]
|
||||
--
|
||||
lib.DefaultMedia["font"] = "默认" -- someone from zhCN please adjust if needed
|
||||
--
|
||||
elseif locale == "zhTW" then
|
||||
LOCALE_MASK = lib.LOCALE_BIT_zhTW
|
||||
--
|
||||
SML_MT_font["提示訊息"] = [[Fonts\bHEI00M.ttf]]
|
||||
SML_MT_font["聊天"] = [[Fonts\bHEI01B.ttf]]
|
||||
SML_MT_font["傷害數字"] = [[Fonts\bKAI00M.ttf]]
|
||||
SML_MT_font["預設"] = [[Fonts\bLEI00D.ttf]]
|
||||
--
|
||||
lib.DefaultMedia["font"] = "預設" -- someone from zhTW please adjust if needed
|
||||
|
||||
elseif locale == "ruRU" then
|
||||
LOCALE_MASK = lib.LOCALE_BIT_ruRU
|
||||
--
|
||||
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
|
||||
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
|
||||
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
|
||||
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]]
|
||||
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
|
||||
|
||||
lib.DefaultMedia.font = "Arial Narrow"
|
||||
--
|
||||
else
|
||||
LOCALE_MASK = lib.LOCALE_BIT_western
|
||||
locale_is_western = true
|
||||
--
|
||||
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
|
||||
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
|
||||
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
|
||||
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
|
||||
--
|
||||
lib.DefaultMedia.font = "Friz Quadrata TT"
|
||||
--
|
||||
end
|
||||
|
||||
-- STATUSBAR
|
||||
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end
|
||||
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]]
|
||||
lib.DefaultMedia.statusbar = "Blizzard"
|
||||
|
||||
-- SOUND
|
||||
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
|
||||
lib.MediaTable.sound["None"] = [[Interface\Quiet.ogg]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input.
|
||||
lib.DefaultMedia.sound = "None"
|
||||
|
||||
local function rebuildMediaList(mediatype)
|
||||
local mtable = mediaTable[mediatype]
|
||||
if not mtable then return end
|
||||
if not mediaList[mediatype] then mediaList[mediatype] = {} end
|
||||
local mlist = mediaList[mediatype]
|
||||
-- list can only get larger, so simply overwrite it
|
||||
local i = 0
|
||||
for k in pairs(mtable) do
|
||||
i = i + 1
|
||||
mlist[i] = k
|
||||
end
|
||||
table_sort(mlist)
|
||||
end
|
||||
|
||||
function lib:Register(mediatype, key, data, langmask)
|
||||
if type(mediatype) ~= "string" then
|
||||
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype))
|
||||
end
|
||||
if type(key) ~= "string" then
|
||||
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key))
|
||||
end
|
||||
mediatype = string.lower(mediatype)
|
||||
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end
|
||||
if mediatype == lib.MediaType.SOUND and type(data) == "string" then
|
||||
local path = data
|
||||
-- Only wav, ogg and mp3 are valid sounds.
|
||||
if not string.find(path, ".ogg", nil, true) and not string.find(path, ".mp3", nil, true) and not string.find(path, ".wav", nil, true) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end
|
||||
local mtable = mediaTable[mediatype]
|
||||
if mtable[key] then return false end
|
||||
|
||||
mtable[key] = data
|
||||
rebuildMediaList(mediatype)
|
||||
self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key)
|
||||
return true
|
||||
end
|
||||
|
||||
function lib:Fetch(mediatype, key, noDefault)
|
||||
local mtt = mediaTable[mediatype]
|
||||
local overridekey = overrideMedia[mediatype]
|
||||
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil
|
||||
return result ~= "" and result or nil
|
||||
end
|
||||
|
||||
function lib:IsValid(mediatype, key)
|
||||
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
|
||||
end
|
||||
|
||||
function lib:HashTable(mediatype)
|
||||
return mediaTable[mediatype]
|
||||
end
|
||||
|
||||
function lib:List(mediatype)
|
||||
if not mediaTable[mediatype] then
|
||||
return nil
|
||||
end
|
||||
if not mediaList[mediatype] then
|
||||
rebuildMediaList(mediatype)
|
||||
end
|
||||
return mediaList[mediatype]
|
||||
end
|
||||
|
||||
function lib:GetGlobal(mediatype)
|
||||
return overrideMedia[mediatype]
|
||||
end
|
||||
|
||||
function lib:SetGlobal(mediatype, key)
|
||||
if not mediaTable[mediatype] then
|
||||
return false
|
||||
end
|
||||
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil
|
||||
self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype])
|
||||
return true
|
||||
end
|
||||
|
||||
function lib:GetDefault(mediatype)
|
||||
return defaultMedia[mediatype]
|
||||
end
|
||||
|
||||
function lib:SetDefault(mediatype, key)
|
||||
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
|
||||
defaultMedia[mediatype] = key
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibSharedMedia-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,280 @@
|
||||
--[[---------------------------------------------------------------------------------
|
||||
General Library providing an alternate StartMoving() that allows you to
|
||||
specify a number of frames to snap-to when moving the frame around
|
||||
|
||||
Example Usage:
|
||||
|
||||
<OnLoad>
|
||||
this:RegisterForDrag("LeftButton")
|
||||
</OnLoad>
|
||||
<OnDragStart>
|
||||
StickyFrames:StartMoving(this, {WatchDogFrame_player, WatchDogFrame_target, WatchDogFrame_party1, WatchDogFrame_party2, WatchDogFrame_party3, WatchDogFrame_party4},3,3,3,3)
|
||||
</OnDragStart>
|
||||
<OnDragStop>
|
||||
StickyFrames:StopMoving(this)
|
||||
StickyFrames:AnchorFrame(this)
|
||||
</OnDragStop>
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
This is a modified version by Elv for ElvUI
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
local MAJOR, MINOR = "LibSimpleSticky-1.0", 2
|
||||
local StickyFrames, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not StickyFrames then return end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Class declaration, along with a temporary table to hold any existing OnUpdate
|
||||
scripts.
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
StickyFrames.scripts = StickyFrames.scripts or {}
|
||||
StickyFrames.rangeX = 15
|
||||
StickyFrames.rangeY = 15
|
||||
StickyFrames.sticky = StickyFrames.sticky or {}
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
StickyFrames:StartMoving() - Sets a custom OnUpdate for the frame so it follows
|
||||
the mouse and snaps to the frames you specify
|
||||
|
||||
frame: The frame we want to move. Is typically "this"
|
||||
|
||||
frameList: A integer indexed list of frames that the given frame should try to
|
||||
stick to. These don't have to have anything special done to them,
|
||||
and they don't really even need to exist. You can inclue the
|
||||
moving frame in this list, it will be ignored. This helps you
|
||||
if you have a number of frames, just make ONE list to pass.
|
||||
|
||||
{WatchDogFrame_player, WatchDogFrame_party1, .. WatchDogFrame_party4}
|
||||
|
||||
left: If your frame has a tranparent border around the entire frame
|
||||
(think backdrops with borders). This can be used to fine tune the
|
||||
edges when you're stickying groups. Refers to any offset on the
|
||||
LEFT edge of the frame being moved.
|
||||
|
||||
top: same
|
||||
right: same
|
||||
bottom: same
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
function StickyFrames:StartMoving(frame, frameList, left, top, right, bottom)
|
||||
local x,y = GetCursorPosition()
|
||||
local aX,aY = frame:GetCenter()
|
||||
local aS = frame:GetEffectiveScale()
|
||||
|
||||
aX,aY = aX*aS,aY*aS
|
||||
local xoffset,yoffset = (aX - x),(aY - y)
|
||||
self.scripts[frame] = frame:GetScript("OnUpdate")
|
||||
frame:SetScript("OnUpdate", self:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom))
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
This stops the OnUpdate, leaving the frame at its last position. This will
|
||||
leave it anchored to UIParent. You can call StickyFrames:AnchorFrame() to
|
||||
anchor it back "TOPLEFT" , "TOPLEFT" to the parent.
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
function StickyFrames:StopMoving(frame)
|
||||
frame:SetScript("OnUpdate", self.scripts[frame])
|
||||
self.scripts[frame] = nil
|
||||
|
||||
if StickyFrames.sticky[frame] then
|
||||
local sticky = StickyFrames.sticky[frame]
|
||||
StickyFrames.sticky[frame] = nil
|
||||
return true, sticky
|
||||
else
|
||||
return false, nil
|
||||
end
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
This can be called in conjunction with StickyFrames:StopMoving() to anchor the
|
||||
frame right back to the parent, so you can manipulate its children as a group
|
||||
(This is useful in WatchDog)
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
function StickyFrames:AnchorFrame(frame)
|
||||
local xA,yA = frame:GetCenter()
|
||||
local parent = frame:GetParent() or UIParent
|
||||
local xP,yP = parent:GetCenter()
|
||||
local sA,sP = frame:GetEffectiveScale(), parent:GetEffectiveScale()
|
||||
|
||||
xP,yP = (xP*sP) / sA, (yP*sP) / sA
|
||||
|
||||
local xo,yo = (xP - xA)*-1, (yP - yA)*-1
|
||||
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("CENTER", parent, "CENTER", xo, yo)
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Internal Functions -- Do not call these.
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Returns an anonymous OnUpdate function for the frame in question. Need
|
||||
to provide the frame, frameList along with the x and y offset (difference between
|
||||
where the mouse picked up the frame, and the insets (left,top,right,bottom) in the
|
||||
case of borders, etc.w
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
function StickyFrames:GetUpdateFunc(frame, frameList, xoffset, yoffset, left, top, right, bottom)
|
||||
return function()
|
||||
local x,y = GetCursorPosition()
|
||||
local s = frame:GetEffectiveScale()
|
||||
local sticky = nil
|
||||
|
||||
x,y = x/s,y/s
|
||||
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x+xoffset, y+yoffset)
|
||||
|
||||
StickyFrames.sticky[frame] = nil
|
||||
for i = 1, table.getn(frameList) do
|
||||
local v = frameList[i]
|
||||
if frame ~= v and frame ~= v:GetParent() and not IsShiftKeyDown() and v:IsVisible() then
|
||||
if self:SnapFrame(frame, v, left, top, right, bottom) then
|
||||
StickyFrames.sticky[frame] = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Internal debug function.
|
||||
------------------------------------------------------------------------------------]]
|
||||
|
||||
function StickyFrames:debug(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffff00StickyFrames: |r"..tostring(msg))
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
This is called when finding an overlap between two sticky frame. If frameA is near
|
||||
a sticky edge of frameB, then it will snap to that edge and return true. If there
|
||||
is no sticky edge collision, will return false so we can test other frames for
|
||||
stickyness.
|
||||
------------------------------------------------------------------------------------]]
|
||||
function StickyFrames:SnapFrame(frameA, frameB, left, top, right, bottom)
|
||||
local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale()
|
||||
local xA, yA = frameA:GetCenter()
|
||||
local xB, yB = frameB:GetCenter()
|
||||
local hA, hB = frameA:GetHeight() / 2, ((frameB:GetHeight() * sB) / sA) / 2
|
||||
local wA, wB = frameA:GetWidth() / 2, ((frameB:GetWidth() * sB) / sA) / 2
|
||||
|
||||
local newX, newY = xA, yA
|
||||
|
||||
if not left then left = 0 end
|
||||
if not top then top = 0 end
|
||||
if not right then right = 0 end
|
||||
if not bottom then bottom = 0 end
|
||||
|
||||
-- Lets translate B's coords into A's scale
|
||||
if not xB or not yB or not sB or not sA or not sB then return end
|
||||
xB, yB = (xB*sB) / sA, (yB*sB) / sA
|
||||
|
||||
local stickyAx, stickyAy = wA * 0.75, hA * 0.75
|
||||
local stickyBx, stickyBy = wB * 0.75, hB * 0.75
|
||||
|
||||
-- Grab the edges of each frame, for easier comparison
|
||||
|
||||
local lA, tA, rA, bA = frameA:GetLeft(), frameA:GetTop(), frameA:GetRight(), frameA:GetBottom()
|
||||
local lB, tB, rB, bB = frameB:GetLeft(), frameB:GetTop(), frameB:GetRight(), frameB:GetBottom()
|
||||
local snap = nil
|
||||
|
||||
-- Translate into A's scale
|
||||
lB, tB, rB, bB = (lB * sB) / sA, (tB * sB) / sA, (rB * sB) / sA, (bB * sB) / sA
|
||||
|
||||
if (bA <= tB and bB <= tA) then
|
||||
|
||||
-- Horizontal Centers
|
||||
if xA <= (xB + StickyFrames.rangeX) and xA >= (xB - StickyFrames.rangeX) then
|
||||
newX = xB
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Interior Left
|
||||
if lA <= (lB + StickyFrames.rangeX) and lA >= (lB - StickyFrames.rangeX) then
|
||||
newX = lB + wA
|
||||
if frameB == UIParent or frameB == WorldFrame or frameB == ElvUIParent then
|
||||
newX = newX + 4
|
||||
end
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Interior Right
|
||||
if rA <= (rB + StickyFrames.rangeX) and rA >= (rB - StickyFrames.rangeX) then
|
||||
newX = rB - wA
|
||||
if frameB == UIParent or frameB == WorldFrame or frameB == ElvUIParent then
|
||||
newX = newX - 4
|
||||
end
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Exterior Left to Right
|
||||
if lA <= (rB + StickyFrames.rangeX) and lA >= (rB - StickyFrames.rangeX) then
|
||||
newX = rB + (wA - left)
|
||||
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Exterior Right to Left
|
||||
if rA <= (lB + StickyFrames.rangeX) and rA >= (lB - StickyFrames.rangeX) then
|
||||
newX = lB - (wA - right)
|
||||
snap = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (lA <= rB and lB <= rA) then
|
||||
|
||||
-- Vertical Centers
|
||||
if yA <= (yB + StickyFrames.rangeY) and yA >= (yB - StickyFrames.rangeY) then
|
||||
newY = yB
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Interior Top
|
||||
if tA <= (tB + StickyFrames.rangeY) and tA >= (tB - StickyFrames.rangeY) then
|
||||
newY = tB - hA
|
||||
if frameB == UIParent or frameB == WorldFrame or frameB == ElvUIParent then
|
||||
newY = newY - 4
|
||||
end
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Interior Bottom
|
||||
if bA <= (bB + StickyFrames.rangeY) and bA >= (bB - StickyFrames.rangeY) then
|
||||
newY = bB + hA
|
||||
if frameB == UIParent or frameB == WorldFrame or frameB == ElvUIParent then
|
||||
newY = newY + 4
|
||||
end
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Exterior Top to Bottom
|
||||
if tA <= (bB + StickyFrames.rangeY + bottom) and tA >= (bB - StickyFrames.rangeY + bottom) then
|
||||
newY = bB - (hA - top)
|
||||
snap = true
|
||||
end
|
||||
|
||||
-- Exterior Bottom to Top
|
||||
if bA <= (tB + StickyFrames.rangeY - top) and bA >= (tB - StickyFrames.rangeY - top) then
|
||||
newY = tB + (hA - bottom)
|
||||
snap = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if snap then
|
||||
frameA:ClearAllPoints()
|
||||
frameA:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY)
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibSimpleSticky.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,33 @@
|
||||
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/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 _G = getfenv()
|
||||
local strfind, strfmt = string.find, string.format
|
||||
local LibStub = _G[LIBSTUB_MAJOR]
|
||||
|
||||
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
|
||||
LibStub = LibStub or { libs = {}, minors = {} }
|
||||
_G[LIBSTUB_MAJOR] = LibStub
|
||||
LibStub.minor = LIBSTUB_MINOR
|
||||
|
||||
function LibStub:NewLibrary(major, minor)
|
||||
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
|
||||
local _,_,num = strfind(minor, "(%d+)")
|
||||
minor = assert(tonumber(num), "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
|
||||
|
||||
function LibStub:GetLibrary(major, silent)
|
||||
if not self.libs[major] and not silent then
|
||||
error(strfmt("Cannot find a library instance of %q.", tostring(major)), 2)
|
||||
end
|
||||
return self.libs[major], self.minors[major]
|
||||
end
|
||||
|
||||
function LibStub:IterateLibraries() return pairs(self.libs) end
|
||||
setmetatable(LibStub, { __call = LibStub.GetLibrary })
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="LibStub.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,47 @@
|
||||
--$Id: LibEasyMenu.lua 19 2017-07-02 13:34:55Z arith $
|
||||
-- Simplified Menu Display System
|
||||
-- This is a basic system for displaying a menu from a structure table.
|
||||
--
|
||||
-- See UIDropDownMenu.lua for the menuList details.
|
||||
--
|
||||
-- Args:
|
||||
-- menuList - menu table
|
||||
-- menuFrame - the UI frame to populate
|
||||
-- anchor - where to anchor the frame (e.g. CURSOR)
|
||||
-- x - x offset
|
||||
-- y - y offset
|
||||
-- displayMode - border type
|
||||
-- autoHideDelay - how long until the menu disappears
|
||||
--
|
||||
--
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Localized Lua globals.
|
||||
-- ----------------------------------------------------------------------------
|
||||
local _G = getfenv(0)
|
||||
-- ----------------------------------------------------------------------------
|
||||
local MAJOR_VERSION = "LibEasyMenu-1.04.7030024484"
|
||||
local MINOR_VERSION = 90000 + 19
|
||||
|
||||
local LibStub = _G.LibStub
|
||||
if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
|
||||
local Lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
|
||||
if not Lib then return end
|
||||
|
||||
function L_EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay )
|
||||
if ( displayMode == "MENU" ) then
|
||||
menuFrame.displayMode = displayMode;
|
||||
end
|
||||
L_UIDropDownMenu_Initialize(menuFrame, L_EasyMenu_Initialize, displayMode, nil, menuList);
|
||||
L_ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList, nil, autoHideDelay);
|
||||
end
|
||||
|
||||
function L_EasyMenu_Initialize( frame, level, menuList )
|
||||
for index = 1, getn(menuList) do
|
||||
local value = menuList[index]
|
||||
if (value.text) then
|
||||
value.index = index;
|
||||
L_UIDropDownMenu_AddButton( value, level );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
<!-- $Id: LibUIDropDownMenu.xml 13 2017-05-25 04:26:27Z arith $ -->
|
||||
<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">
|
||||
<Script file="LibUIDropDownMenu.lua"/>
|
||||
<Include file="LibUIDropDownMenuTemplates.xml"/>
|
||||
<Script file="LibEasyMenu.lua"/>
|
||||
<Button name="L_DropDownList1" toplevel="true" frameStrata="FULLSCREEN_DIALOG" inherits="L_UIDropDownListTemplate" hidden="true" id="1">
|
||||
<Size>
|
||||
<AbsDimension x="180" y="10"/>
|
||||
</Size>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
local fontName, fontHeight, fontFlags = getglobal("L_DropDownList1Button1NormalText"):GetFont();
|
||||
L_UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = fontHeight;
|
||||
tinsert(UIMenus, "L_DropDownList1"); --Allow closing with escape
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="L_DropDownList2" toplevel="true" frameStrata="FULLSCREEN_DIALOG" inherits="L_UIDropDownListTemplate" hidden="true" id="2">
|
||||
<Size>
|
||||
<AbsDimension x="180" y="10"/>
|
||||
</Size>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
tinsert(UIMenus, "L_DropDownList2"); --Allow closing with escape
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Ui>
|
||||
@@ -0,0 +1,438 @@
|
||||
<!-- $Id: LibUIDropDownMenuTemplates.xml 19 2017-07-02 13:34:55Z arith $ -->
|
||||
<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">
|
||||
<Button name="L_UIDropDownMenuButtonTemplate" virtual="true">
|
||||
<Size x="100" y="16"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentHighlight" file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD" setAllPoints="true" hidden="true"/>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentCheck" file="Interface\Buttons\UI-CheckBox-Check">
|
||||
<Size x="16" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="0" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="0.5" top="0.5" bottom="1.0"/>
|
||||
</Texture>
|
||||
<Texture name="$parentUnCheck" file="Interface\Buttons\UI-CheckBox-Check">
|
||||
<Size x="16" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="0" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0.5" right="1.0" top="0.5" bottom="1.0"/>
|
||||
</Texture>
|
||||
<Texture name="$parentIcon" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="16" y="16"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT">
|
||||
<Offset x="0" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentColorSwatch" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="16" y="16"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="-6" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentSwatchBg">
|
||||
<Size>
|
||||
<AbsDimension x="14" y="14"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Color r="1.0" g="1.0" b="1.0"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
securecall("CloseMenus");
|
||||
L_UIDropDownMenuButton_OpenColorPicker(this:GetParent());
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
L_CloseDropDownMenus(this:GetParent():GetParent():GetID() + 1);
|
||||
getglobal(this:GetName().."SwatchBg"):SetVertexColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
|
||||
L_UIDropDownMenu_StopCounting(this:GetParent():GetParent());
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
getglobal(this:GetName().."SwatchBg"):SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
|
||||
L_UIDropDownMenu_StartCounting(this:GetParent():GetParent());
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
<NormalTexture name="$parentNormalTexture" file="Interface\ChatFrame\ChatFrameColorSwatch"/>
|
||||
</Button>
|
||||
<Button name="$parentExpandArrow" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="16" y="16"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
L_ToggleDropDownMenu(this:GetParent():GetParent():GetID() + 1, this:GetParent().value, nil, nil, nil, nil, this:GetParent().menuList, this);
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
local level = this:GetParent():GetParent():GetID() + 1;
|
||||
local listFrame = getglobal("L_DropDownList"..level);
|
||||
if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= this ) then
|
||||
L_ToggleDropDownMenu(level, this:GetParent().value, nil, nil, nil, nil, this:GetParent().menuList, this);
|
||||
end
|
||||
L_UIDropDownMenu_StopCounting(this:GetParent():GetParent());
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
L_UIDropDownMenu_StartCounting(this:GetParent():GetParent());
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
<NormalTexture file="Interface\ChatFrame\ChatFrameExpandArrow"/>
|
||||
</Button>
|
||||
<Button name="$parentInvisibleButton" hidden="true" parentKey="invisibleButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
<Anchor point="RIGHT" relativeTo="$parentColorSwatch" relativePoint="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
L_UIDropDownMenu_StopCounting(this:GetParent():GetParent());
|
||||
L_CloseDropDownMenus(this:GetParent():GetParent():GetID() + 1);
|
||||
local parent = this:GetParent();
|
||||
if ( parent.tooltipTitle and parent.tooltipWhileDisabled) then
|
||||
if ( parent.tooltipOnButton ) then
|
||||
GameTooltip:SetOwner(parent, "ANCHOR_RIGHT");
|
||||
GameTooltip:AddLine(parent.tooltipTitle, 1.0, 1.0, 1.0);
|
||||
GameTooltip:AddLine(parent.tooltipText, nil, nil, nil, true);
|
||||
GameTooltip:Show();
|
||||
else
|
||||
GameTooltip_AddNewbieTip(parent, parent.tooltipTitle, 1.0, 1.0, 1.0, parent.tooltipText, 1);
|
||||
end
|
||||
end
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
L_UIDropDownMenu_StartCounting(this:GetParent():GetParent());
|
||||
GameTooltip:Hide();
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetFrameLevel(this:GetParent():GetFrameLevel()+2);
|
||||
</OnLoad>
|
||||
<OnClick>
|
||||
L_UIDropDownMenuButton_OnClick(this, arg1, arg2);
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
if ( this.hasArrow ) then
|
||||
local level = this:GetParent():GetID() + 1;
|
||||
local listFrame = getglobal("L_DropDownList"..level);
|
||||
if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= this ) then
|
||||
L_ToggleDropDownMenu(this:GetParent():GetID() + 1, this.value, nil, nil, nil, nil, this.menuList, this);
|
||||
end
|
||||
else
|
||||
L_CloseDropDownMenus(this:GetParent():GetID() + 1);
|
||||
end
|
||||
getglobal(this:GetName().."Highlight"):Show();
|
||||
L_UIDropDownMenu_StopCounting(this:GetParent());
|
||||
if ( this.tooltipTitle ) then
|
||||
if ( this.tooltipOnButton ) then
|
||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
|
||||
GameTooltip:AddLine(this.tooltipTitle, 1.0, 1.0, 1.0);
|
||||
GameTooltip:AddLine(this.tooltipText, nil, nil, nil, true);
|
||||
GameTooltip:Show();
|
||||
else
|
||||
GameTooltip_AddNewbieTip(this, this.tooltipTitle, 1.0, 1.0, 1.0, this.tooltipText, 1);
|
||||
end
|
||||
end
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
getglobal(this:GetName().."Highlight"):Hide();
|
||||
L_UIDropDownMenu_StartCounting(this:GetParent());
|
||||
GameTooltip:Hide();
|
||||
</OnLeave>
|
||||
<OnEnable>
|
||||
this.invisibleButton:Hide();
|
||||
</OnEnable>
|
||||
<OnDisable>
|
||||
this.invisibleButton:Show();
|
||||
</OnDisable>
|
||||
</Scripts>
|
||||
<ButtonText name="$parentNormalText">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="-5" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</ButtonText>
|
||||
<NormalFont inherits="GameFontHighlightSmall" justifyH="LEFT"/>
|
||||
<HighlightFont inherits="GameFontHighlightSmall" justifyH="LEFT"/>
|
||||
<DisabledFont inherits="GameFontDisableSmall" justifyH="LEFT"/>
|
||||
</Button>
|
||||
|
||||
<Button name="L_UIDropDownListTemplate" hidden="true" frameStrata="DIALOG" enableMouse="true" virtual="true">
|
||||
<Frames>
|
||||
<Frame name="$parentBackdrop" setAllPoints="true">
|
||||
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background-Dark" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="11" right="12" top="12" bottom="9"/>
|
||||
</BackgroundInsets>
|
||||
<TileSize>
|
||||
<AbsValue val="32"/>
|
||||
</TileSize>
|
||||
<EdgeSize>
|
||||
<AbsValue val="32"/>
|
||||
</EdgeSize>
|
||||
</Backdrop>
|
||||
</Frame>
|
||||
<Frame name="$parentMenuBackdrop" setAllPoints="true">
|
||||
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||
<EdgeSize>
|
||||
<AbsValue val="16"/>
|
||||
</EdgeSize>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="5" right="5" top="5" bottom="4"/>
|
||||
</BackgroundInsets>
|
||||
</Backdrop>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
|
||||
this:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Button name="$parentButton1" inherits="L_UIDropDownMenuButtonTemplate" id="1"/>
|
||||
<Button name="$parentButton2" inherits="L_UIDropDownMenuButtonTemplate" id="2"/>
|
||||
<Button name="$parentButton3" inherits="L_UIDropDownMenuButtonTemplate" id="3"/>
|
||||
<Button name="$parentButton4" inherits="L_UIDropDownMenuButtonTemplate" id="4"/>
|
||||
<Button name="$parentButton5" inherits="L_UIDropDownMenuButtonTemplate" id="5"/>
|
||||
<Button name="$parentButton6" inherits="L_UIDropDownMenuButtonTemplate" id="6"/>
|
||||
<Button name="$parentButton7" inherits="L_UIDropDownMenuButtonTemplate" id="7"/>
|
||||
<Button name="$parentButton8" inherits="L_UIDropDownMenuButtonTemplate" id="8"/>
|
||||
<Button name="$parentButton9" inherits="L_UIDropDownMenuButtonTemplate" id="9"/>
|
||||
<Button name="$parentButton10" inherits="L_UIDropDownMenuButtonTemplate" id="10"/>
|
||||
<Button name="$parentButton11" inherits="L_UIDropDownMenuButtonTemplate" id="11"/>
|
||||
<Button name="$parentButton12" inherits="L_UIDropDownMenuButtonTemplate" id="12"/>
|
||||
<Button name="$parentButton13" inherits="L_UIDropDownMenuButtonTemplate" id="13"/>
|
||||
<Button name="$parentButton14" inherits="L_UIDropDownMenuButtonTemplate" id="14"/>
|
||||
<Button name="$parentButton15" inherits="L_UIDropDownMenuButtonTemplate" id="15"/>
|
||||
<Button name="$parentButton16" inherits="L_UIDropDownMenuButtonTemplate" id="16"/>
|
||||
<Button name="$parentButton17" inherits="L_UIDropDownMenuButtonTemplate" id="17"/>
|
||||
<Button name="$parentButton18" inherits="L_UIDropDownMenuButtonTemplate" id="18"/>
|
||||
<Button name="$parentButton19" inherits="L_UIDropDownMenuButtonTemplate" id="19"/>
|
||||
<Button name="$parentButton20" inherits="L_UIDropDownMenuButtonTemplate" id="20"/>
|
||||
<Button name="$parentButton21" inherits="L_UIDropDownMenuButtonTemplate" id="21"/>
|
||||
<Button name="$parentButton22" inherits="L_UIDropDownMenuButtonTemplate" id="22"/>
|
||||
<Button name="$parentButton23" inherits="L_UIDropDownMenuButtonTemplate" id="23"/>
|
||||
<Button name="$parentButton24" inherits="L_UIDropDownMenuButtonTemplate" id="24"/>
|
||||
<Button name="$parentButton25" inherits="L_UIDropDownMenuButtonTemplate" id="25"/>
|
||||
<Button name="$parentButton26" inherits="L_UIDropDownMenuButtonTemplate" id="26"/>
|
||||
<Button name="$parentButton27" inherits="L_UIDropDownMenuButtonTemplate" id="27"/>
|
||||
<Button name="$parentButton28" inherits="L_UIDropDownMenuButtonTemplate" id="28"/>
|
||||
<Button name="$parentButton29" inherits="L_UIDropDownMenuButtonTemplate" id="29"/>
|
||||
<Button name="$parentButton30" inherits="L_UIDropDownMenuButtonTemplate" id="30"/>
|
||||
<Button name="$parentButton31" inherits="L_UIDropDownMenuButtonTemplate" id="31"/>
|
||||
<Button name="$parentButton32" inherits="L_UIDropDownMenuButtonTemplate" id="32"/>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
this:Hide();
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
L_UIDropDownMenu_StopCounting(this, arg1);
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
L_UIDropDownMenu_StartCounting(this, arg1);
|
||||
</OnLeave>
|
||||
<OnUpdate>
|
||||
L_UIDropDownMenu_OnUpdate(this, arg1);
|
||||
</OnUpdate>
|
||||
<OnShow>
|
||||
for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do
|
||||
if (not this.noResize) then
|
||||
getglobal(this:GetName().."Button"..i):SetWidth(this.maxWidth);
|
||||
end
|
||||
end
|
||||
if (not this.noResize) then
|
||||
this:SetWidth(this.maxWidth+25);
|
||||
end
|
||||
this.showTimer = nil;
|
||||
if ( this:GetID() > 1 ) then
|
||||
this.parent = getglobal("L_DropDownList"..(this:GetID() - 1));
|
||||
end
|
||||
</OnShow>
|
||||
<OnHide>
|
||||
L_UIDropDownMenu_OnHide(this);
|
||||
</OnHide>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Frame name="L_UIDropDownMenuTemplate" virtual="true">
|
||||
<Size>
|
||||
<AbsDimension x="40" y="32"/>
|
||||
</Size>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentLeft" file="Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame">
|
||||
<Size>
|
||||
<AbsDimension x="25" y="64"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="17"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="0.1953125" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentMiddle" file="Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame">
|
||||
<Size>
|
||||
<AbsDimension x="115" y="64"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.1953125" right="0.8046875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentRight" file="Interface\Glues\CharacterCreate\CharacterCreate-LabelFrame">
|
||||
<Size>
|
||||
<AbsDimension x="25" y="64"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativeTo="$parentMiddle" relativePoint="RIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.8046875" right="1" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<FontString parentKey="Text" name="$parentText" inherits="GameFontHighlightSmall" wordwrap="false" justifyH="RIGHT">
|
||||
<Size>
|
||||
<AbsDimension x="0" y="10"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativeTo="$parentRight">
|
||||
<Offset>
|
||||
<AbsDimension x="-43" y="2"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture parentKey="Icon" name="$parentIcon" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="16" y="16"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="30" y="2"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button parentKey="Button" name="$parentButton" motionScriptsWhileDisabled="true" >
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentRight">
|
||||
<Offset>
|
||||
<AbsDimension x="-16" y="-18"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
local parent = this:GetParent();
|
||||
local myscript = parent:GetScript("OnEnter");
|
||||
if(myscript ~= nil) then
|
||||
myscript(parent);
|
||||
end
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
local parent = this:GetParent();
|
||||
local myscript = parent:GetScript("OnLeave");
|
||||
if(myscript ~= nil) then
|
||||
myscript(parent);
|
||||
end
|
||||
</OnLeave>
|
||||
<OnClick>
|
||||
L_ToggleDropDownMenu(nil, nil, this:GetParent());
|
||||
PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
<NormalTexture name="$parentNormalTexture" file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Up">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT"/>
|
||||
</Anchors>
|
||||
</NormalTexture>
|
||||
<PushedTexture name="$parentPushedTexture" file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Down">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT"/>
|
||||
</Anchors>
|
||||
</PushedTexture>
|
||||
<DisabledTexture name="$parentDisabledTexture" file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Disabled">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT"/>
|
||||
</Anchors>
|
||||
</DisabledTexture>
|
||||
<HighlightTexture name="$parentHighlightTexture" file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT"/>
|
||||
</Anchors>
|
||||
</HighlightTexture>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnHide>
|
||||
L_CloseDropDownMenus();
|
||||
</OnHide>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,25 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Include file="LibStub\LibStub.xml"/>
|
||||
<Include file="CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
|
||||
<Include file="AceCore-3.0\AceCore-3.0.xml"/>
|
||||
<Include file="AceAddon-3.0\AceAddon-3.0.xml"/>
|
||||
<Include file="AceEvent-3.0\AceEvent-3.0.xml"/>
|
||||
<Include file="AceConsole-3.0\AceConsole-3.0.xml"/>
|
||||
<Include file="AceDB-3.0\AceDB-3.0.xml"/>
|
||||
<Include file="AceLocale-3.0\AceLocale-3.0.xml"/>
|
||||
<Include file="AceComm-3.0\AceComm-3.0.xml"/>
|
||||
<Include file="AceSerializer-3.0\AceSerializer-3.0.xml"/>
|
||||
<Include file="AceTimer-3.0\AceTimer-3.0.xml"/>
|
||||
<Include file="AceHook-3.0\AceHook-3.0.xml"/>
|
||||
<Include file="LibSharedMedia-3.0\LibSharedMedia-3.0.xml"/>
|
||||
<Include file="LibSimpleSticky\LibSimpleSticky.xml"/>
|
||||
<Include file="LibDataBroker\LibDataBroker-1.1.xml"/>
|
||||
<Include file="LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.xml"/>
|
||||
<!--
|
||||
<Include file="UTF8\UTF8.xml"/>
|
||||
<Include file="LibCompress\LibCompress.xml"/>
|
||||
<Include file="LibBase64-1.0\LibBase64-1.0.xml"/>
|
||||
-->
|
||||
<Include file="LibAnim\LibAnim.xml"/>
|
||||
<Include file="LibUIDropDownMenu\LibUIDropDownMenu.xml"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="utf8.lua"/>
|
||||
<Script file="utf8data.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,318 @@
|
||||
-- $Id: utf8.lua 179 2009-04-03 18:10:03Z pasta $
|
||||
--
|
||||
-- Provides UTF-8 aware string functions implemented in pure lua:
|
||||
-- * string.utf8len(s)
|
||||
-- * string.utf8sub(s, i, j)
|
||||
-- * string.utf8reverse(s)
|
||||
--
|
||||
-- If utf8data.lua (containing the lower<->upper case mappings) is loaded, these
|
||||
-- additional functions are available:
|
||||
-- * string.utf8upper(s)
|
||||
-- * string.utf8lower(s)
|
||||
--
|
||||
-- All functions behave as their non UTF-8 aware counterparts with the exception
|
||||
-- that UTF-8 characters are used instead of bytes for all units.
|
||||
|
||||
--[[
|
||||
Copyright (c) 2006-2007, Kyle Smith
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--]]
|
||||
|
||||
-- ABNF from RFC 3629
|
||||
--
|
||||
-- UTF8-octets = *( UTF8-char )
|
||||
-- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
|
||||
-- UTF8-1 = %x00-7F
|
||||
-- UTF8-2 = %xC2-DF UTF8-tail
|
||||
-- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
|
||||
-- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
|
||||
-- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
|
||||
-- %xF4 %x80-8F 2( UTF8-tail )
|
||||
-- UTF8-tail = %x80-BF
|
||||
--
|
||||
|
||||
local strbyte, strlen, strsub, type = string.byte, string.len, string.sub, type
|
||||
|
||||
-- returns the number of bytes used by the UTF-8 character at byte i in s
|
||||
-- also doubles as a UTF-8 character validator
|
||||
local function utf8charbytes(s, i)
|
||||
-- argument defaults
|
||||
i = i or 1
|
||||
|
||||
-- argument checking
|
||||
if type(s) ~= "string" then
|
||||
error("bad argument #1 to 'utf8charbytes' (string expected, got ".. type(s).. ")")
|
||||
end
|
||||
if type(i) ~= "number" then
|
||||
error("bad argument #2 to 'utf8charbytes' (number expected, got ".. type(i).. ")")
|
||||
end
|
||||
|
||||
local c = strbyte(s, i)
|
||||
|
||||
-- determine bytes needed for character, based on RFC 3629
|
||||
-- validate byte 1
|
||||
if c > 0 and c <= 127 then
|
||||
-- UTF8-1
|
||||
return 1
|
||||
|
||||
elseif c >= 194 and c <= 223 then
|
||||
-- UTF8-2
|
||||
local c2 = strbyte(s, i + 1)
|
||||
|
||||
if not c2 then
|
||||
error("UTF-8 string terminated early")
|
||||
end
|
||||
|
||||
-- validate byte 2
|
||||
if c2 < 128 or c2 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
return 2
|
||||
|
||||
elseif c >= 224 and c <= 239 then
|
||||
-- UTF8-3
|
||||
local c2 = strbyte(s, i + 1)
|
||||
local c3 = strbyte(s, i + 2)
|
||||
|
||||
if not c2 or not c3 then
|
||||
error("UTF-8 string terminated early")
|
||||
end
|
||||
|
||||
-- validate byte 2
|
||||
if c == 224 and (c2 < 160 or c2 > 191) then
|
||||
error("Invalid UTF-8 character")
|
||||
elseif c == 237 and (c2 < 128 or c2 > 159) then
|
||||
error("Invalid UTF-8 character")
|
||||
elseif c2 < 128 or c2 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
-- validate byte 3
|
||||
if c3 < 128 or c3 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
return 3
|
||||
|
||||
elseif c >= 240 and c <= 244 then
|
||||
-- UTF8-4
|
||||
local c2 = strbyte(s, i + 1)
|
||||
local c3 = strbyte(s, i + 2)
|
||||
local c4 = strbyte(s, i + 3)
|
||||
|
||||
if not c2 or not c3 or not c4 then
|
||||
error("UTF-8 string terminated early")
|
||||
end
|
||||
|
||||
-- validate byte 2
|
||||
if c == 240 and (c2 < 144 or c2 > 191) then
|
||||
error("Invalid UTF-8 character")
|
||||
elseif c == 244 and (c2 < 128 or c2 > 143) then
|
||||
error("Invalid UTF-8 character")
|
||||
elseif c2 < 128 or c2 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
-- validate byte 3
|
||||
if c3 < 128 or c3 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
-- validate byte 4
|
||||
if c4 < 128 or c4 > 191 then
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
|
||||
return 4
|
||||
|
||||
else
|
||||
error("Invalid UTF-8 character")
|
||||
end
|
||||
end
|
||||
|
||||
-- returns the number of characters in a UTF-8 string
|
||||
local function utf8len(s)
|
||||
-- argument checking
|
||||
if type(s) ~= "string" then
|
||||
error("bad argument #1 to 'utf8len' (string expected, got ".. type(s).. ")")
|
||||
end
|
||||
|
||||
local pos = 1
|
||||
local bytes = strlen(s)
|
||||
local len = 0
|
||||
|
||||
while pos <= bytes do
|
||||
len = len + 1
|
||||
pos = pos + utf8charbytes(s, pos)
|
||||
end
|
||||
|
||||
return len
|
||||
end
|
||||
|
||||
-- install in the string library
|
||||
if not string.utf8len then
|
||||
string.utf8len = utf8len
|
||||
end
|
||||
|
||||
-- functions identically to string.sub except that i and j are UTF-8 characters
|
||||
-- instead of bytes
|
||||
local function utf8sub(s, i, j)
|
||||
-- argument defaults
|
||||
j = j or -1
|
||||
|
||||
-- argument checking
|
||||
if type(s) ~= "string" then
|
||||
error("bad argument #1 to 'utf8sub' (string expected, got ".. type(s).. ")")
|
||||
end
|
||||
if type(i) ~= "number" then
|
||||
error("bad argument #2 to 'utf8sub' (number expected, got ".. type(i).. ")")
|
||||
end
|
||||
if type(j) ~= "number" then
|
||||
error("bad argument #3 to 'utf8sub' (number expected, got ".. type(j).. ")")
|
||||
end
|
||||
|
||||
local pos = 1
|
||||
local bytes = strlen(s)
|
||||
local len = 0
|
||||
|
||||
-- only set l if i or j is negative
|
||||
local l = (i >= 0 and j >= 0) or utf8len(s)
|
||||
local startChar = (i >= 0) and i or l + i + 1
|
||||
local endChar = (j >= 0) and j or l + j + 1
|
||||
|
||||
-- can't have start before end!
|
||||
if startChar > endChar then
|
||||
return ""
|
||||
end
|
||||
|
||||
-- byte offsets to pass to string.sub
|
||||
local startByte, endByte = 1, bytes
|
||||
|
||||
while pos <= bytes do
|
||||
len = len + 1
|
||||
|
||||
if len == startChar then
|
||||
startByte = pos
|
||||
end
|
||||
|
||||
pos = pos + utf8charbytes(s, pos)
|
||||
|
||||
if len == endChar then
|
||||
endByte = pos - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return strsub(s, startByte, endByte)
|
||||
end
|
||||
|
||||
-- install in the string library
|
||||
if not string.utf8sub then
|
||||
string.utf8sub = utf8sub
|
||||
end
|
||||
|
||||
-- replace UTF-8 characters based on a mapping table
|
||||
local function utf8replace(s, mapping)
|
||||
-- argument checking
|
||||
if type(s) ~= "string" then
|
||||
error("bad argument #1 to 'utf8replace' (string expected, got ".. type(s).. ")")
|
||||
end
|
||||
if type(mapping) ~= "table" then
|
||||
error("bad argument #2 to 'utf8replace' (table expected, got ".. type(mapping).. ")")
|
||||
end
|
||||
|
||||
local pos = 1
|
||||
local bytes = strlen(s)
|
||||
local charbytes
|
||||
local newstr = ""
|
||||
|
||||
while pos <= bytes do
|
||||
charbytes = utf8charbytes(s, pos)
|
||||
local c = strsub(s, pos, pos + charbytes - 1)
|
||||
|
||||
newstr = newstr .. (mapping[c] or c)
|
||||
|
||||
pos = pos + charbytes
|
||||
end
|
||||
|
||||
return newstr
|
||||
end
|
||||
|
||||
-- identical to string.upper except it knows about unicode simple case conversions
|
||||
local function utf8upper(s)
|
||||
return utf8replace(s, utf8_lc_uc)
|
||||
end
|
||||
|
||||
-- install in the string library
|
||||
if not string.utf8upper and utf8_lc_uc then
|
||||
string.utf8upper = utf8upper
|
||||
end
|
||||
|
||||
-- identical to string.lower except it knows about unicode simple case conversions
|
||||
local function utf8lower(s)
|
||||
return utf8replace(s, utf8_uc_lc)
|
||||
end
|
||||
|
||||
-- install in the string library
|
||||
if not string.utf8lower and utf8_uc_lc then
|
||||
string.utf8lower = utf8lower
|
||||
end
|
||||
|
||||
-- identical to string.reverse except that it supports UTF-8
|
||||
local function utf8reverse(s)
|
||||
-- argument checking
|
||||
if type(s) ~= "string" then
|
||||
error("bad argument #1 to 'utf8reverse' (string expected, got ".. type(s).. ")")
|
||||
end
|
||||
|
||||
local bytes = strlen(s)
|
||||
local pos = bytes
|
||||
local charbytes
|
||||
local newstr = ""
|
||||
local c
|
||||
|
||||
while pos > 0 do
|
||||
c = strbyte(s, pos)
|
||||
while c >= 128 and c <= 191 do
|
||||
pos = pos - 1
|
||||
c = strbyte(pos)
|
||||
end
|
||||
|
||||
charbytes = utf8charbytes(s, pos)
|
||||
|
||||
newstr = newstr .. strsub(s, pos, pos + charbytes - 1)
|
||||
|
||||
pos = pos - 1
|
||||
end
|
||||
|
||||
return newstr
|
||||
end
|
||||
|
||||
-- install in the string library
|
||||
if not string.utf8reverse then
|
||||
string.utf8reverse = utf8reverse
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
-- Chinese localization file for zhCN.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "zhCN")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "插件 %s 不相容于 ElvUI 的 %s 模组, 请停用不相容的插件, 或停用模组."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "欢迎使用 %sElvUI|r %s%s|r 版, 请输入/ec进入设定介面. 如需技术支持,请至至 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "绑定"
|
||||
L["Key"] = "键"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "无绑定设定"
|
||||
L["Remove Bar %d Action Page"] = "移除第%d动作条"
|
||||
L["Trigger"] = "触发器"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "银行"
|
||||
L["Hold Control + Right Click:"] = "按住 Ctrl 并按鼠标右键:"
|
||||
L["Hold Shift + Drag:"] = "按住 Shift 并拖动:"
|
||||
L["Purchase Bags"] = "购买背包"
|
||||
L["Reset Position"] = "重设位置"
|
||||
L["Sort Bags"] = "背包整理"
|
||||
L["Temporary Move"] = "移动背包"
|
||||
L["Toggle Bags"] = "背包开关"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "出售灰色物品"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "离开" --Also used in datatexts and tooltip
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "忙碌" --Also used in datatexts and tooltip
|
||||
L["G"] = "公会"
|
||||
L["Invalid Target"] = "无效的目标"
|
||||
L["O"] = "干部"
|
||||
L["P"] = "队伍"
|
||||
L["PL"] = "队长"
|
||||
L["R"] = "团队"
|
||||
L["RL"] = "团队队长"
|
||||
L["RW"] = "团队警告"
|
||||
L["says"] = "说"
|
||||
L["whispers"] = "密语"
|
||||
L["yells"] = "大喊"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(按住Shift) 内存占用"
|
||||
L["Avoidance Breakdown"] = "免伤统计"
|
||||
L["Character: "] = "角色: "
|
||||
L["Chest"] = "胸"
|
||||
L["Combat"] = "战斗"
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = "坐标"
|
||||
L["copperabbrev"] = "|cffeda55f铜|r"
|
||||
L["Deficit:"] = "赤字:"
|
||||
L["DPS"] = "伤害输出"
|
||||
L["Earned:"] = "赚取:"
|
||||
L["Friends List"] = "好友列表"
|
||||
L["Friends"] = "好友" --Also in Skins
|
||||
L["Gold"] = "金"
|
||||
L["goldabbrev"] = "|cffffd700金|r"
|
||||
L["Hit"] = "命中"
|
||||
L["Hold Shift + Right Click:"] = "按住Shift + 右键点击"
|
||||
L["Home Latency:"] = "本机延迟:"
|
||||
L["HP"] = "生命值"
|
||||
L["HPS"] = "治疗输出"
|
||||
L["lvl"] = "等级"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "等级减伤: "
|
||||
L["No Guild"] = "没有公会"
|
||||
L["Profit:"] = "利润:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "重置数据: 按住 Shift + 右键点击"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "已有进度的副本"
|
||||
L["Server: "] = "服务器: "
|
||||
L["Session:"] = "本次登陆:"
|
||||
L["silverabbrev"] = "|cffc7c7cf银|r"
|
||||
L["SP"] = "法术强度"
|
||||
L["Spell/Heal Power"] = "法术/治疗强度"
|
||||
L["Spent:"] = "花费:"
|
||||
L["Stats For:"] = "统计:"
|
||||
L["System"] = "系统信息"
|
||||
L["Total CPU:"] = "CPU占用"
|
||||
L["Total Memory:"] = "总内存:"
|
||||
L["Total: "] = "合计: "
|
||||
L["Unhittable:"] = "未命中:"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s 尝试调用保护函数 '%s'."
|
||||
L["No locals to dump"] = "没有本地文件"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s 试图与你分享过滤器配置. 你是否接受?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s 试图与你分享配置文件 %s. 你是否接受?"
|
||||
L["Data From: %s"] = "数据来源: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "过滤器配置下载于 %s, 你是否现在变更?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "天啊! 太奇葩了! 下载消失了! 就像在风中放了一个屁... 再试一次吧!"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "配置文件从 %s 下载完成, 但是配置文件 %s 已存在. 请更改名称, 否则它会覆盖你的现有配置文件."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "配置文件从 %s 下载完成, 你是否加载配置文件 %s?"
|
||||
L["Profile request sent. Waiting for response from player."] = "已发送文件请求. 等待对方响应."
|
||||
L["Request was denied by user."] = "请求被对方拒绝."
|
||||
L["Your profile was successfully recieved by the player."] = "你的配置文件已被其他玩家成功接收."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "光环条与图标"
|
||||
L["Auras Set"] = "光环样式设置"
|
||||
L["Auras"] = "光环"
|
||||
L["Caster DPS"] = "法系输出"
|
||||
L["Chat Set"] = "对话设定"
|
||||
L["Chat"] = "聊天框"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "为你的个人设置选择一个你喜欢的皮肤主题."
|
||||
L["Classic"] = "经典"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "点击下面的按钮调整聊天框、单位框架的尺寸, 以及移动动作条位置"
|
||||
L["Config Mode:"] = "设置模式:"
|
||||
L["CVars Set"] = "参数设定"
|
||||
L["CVars"] = "参数"
|
||||
L["Dark"] = "黑暗"
|
||||
L["Disable"] = "禁用"
|
||||
L["ElvUI Installation"] = "安装 ElvUI"
|
||||
L["Finished"] = "完成"
|
||||
L["Grid Size:"] = "网格尺寸:"
|
||||
L["Healer"] = "治疗"
|
||||
L["High Resolution"] = "高分辨率"
|
||||
L["high"] = "高"
|
||||
L["Icons Only"] = "图标"
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "如果你有不想显示的图标或光环条, 你可以简单的通过按住Shift右键点击使它隐藏."
|
||||
L["Importance: |cff07D400High|r"] = "重要度: |cff07D400高|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "重要性: |cffD3CF00中|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "重要性:|cffFF0000低|r"
|
||||
L["Installation Complete"] = "安装完成"
|
||||
L["Layout Set"] = "界面布局设置"
|
||||
L["Layout"] = "界面布局"
|
||||
L["Lock"] = "锁定"
|
||||
L["Low Resolution"] = "低分辨率"
|
||||
L["low"] = "低"
|
||||
L["Nudge"] = "微调"
|
||||
L["Physical DPS"] = "物理输出"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "请按下方按钮设定变数并重载介面."
|
||||
L["Please click the button below to setup your CVars."] = "请按下方按钮设定参数."
|
||||
L["Please press the continue button to go onto the next step."] = "请按继续按钮到下一步"
|
||||
L["Resolution Style Set"] = "分辨率样式设置"
|
||||
L["Resolution"] = "分辨率"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "选择你想要在ElvUI的单位框体里使用何种光环系统. 选择光环条和图标将同时使用光环条和图标, 选择图标来仅仅显示图标."
|
||||
L["Setup Chat"] = "设定聊天框"
|
||||
L["Setup CVars"] = "设定参数"
|
||||
L["Skip Process"] = "略过"
|
||||
L["Sticky Frames"] = "框架依附"
|
||||
L["Tank"] = "坦克"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "对话窗口与 WOW 原始对话窗口的操作方式相同, 你可以拖拉、移动分页或重新命名分页.请按下方按钮以设定对话窗口."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "若要进入内建设定选单, 请输入 /ec, 或者按一下小地图旁的 C 按钮.若要略过安装程序, 请按下方按钮."
|
||||
L["Theme Set"] = "主题设置"
|
||||
L["Theme Setup"] = "主题安装"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "此安装程序有助你了解 ElvUI 部份功能, 并可协助你预先设定 UI."
|
||||
L["This is completely optional."] = "这是可选项."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "此安装步骤将会设定聊天框的名称、位置和颜色."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "此安装步骤将会设定 WOW 预设选项, 建议你执行此步骤, 以确保功能均可正常运作."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "这个分辨率不需要你改动任何设置以适应你的屏幕."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "这个分辨率需要你改变一些设置才能适应你的屏幕."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "这将会改变你单位框架和动作条的构架."
|
||||
L["Trade"] = "拾取/交易"
|
||||
L["Welcome to ElvUI version %s!"] = "欢迎使用 ElvUI 版本 %s!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "你已经完成安装过程. 如果你需要技术支持请访问 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "你可以在游戏内的设定选项内更改ElvUI的字体、颜色等设定."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "你现在可以根据你的战斗角色选择合适的布局."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "根据你的分辨率你可能需要改动这些设置."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "你当前的分辨率是 %s, 这被认为是个 %s 分辨率."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% 以上 |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "条"
|
||||
L["Calendar"] = "日历"
|
||||
L["Can't Roll"] = "无法需求此装备"
|
||||
L["Disband Group"] = "解散队伍"
|
||||
L["Empty Slot"] = "空拾取位"
|
||||
L["Enable"] = "启用"
|
||||
L["Experience"] = "经验/声望条"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "贪婪"
|
||||
L["Left Click:"] = "鼠标左键:"
|
||||
L["Raid Menu"] = "团队菜单"
|
||||
L["Remaining:"] = "剩余:"
|
||||
L["Rested:"] = "休息:"
|
||||
L["Right Click:"] = "鼠标右键:"
|
||||
L["Show BG Texts"] = "显示战场资讯文字"
|
||||
L["Toggle Chat Frame"] = "开关聊天框架"
|
||||
L["Toggle Configuration"] = "设置开关"
|
||||
L["XP:"] = "经验:"
|
||||
L["You don't have permission to mark targets."] = "你没有标记目标的权限"
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "竞技场框架"
|
||||
L["Bag Mover (Grow Down)"] = "背包框架(向下)"
|
||||
L["Bag Mover (Grow Up)"] = "背包框架(向上)"
|
||||
L["Bag Mover"] = "背包框架"
|
||||
L["Bags"] = "背包" --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = "银行框架(向下)"
|
||||
L["Bank Mover (Grow Up)"] = "银行框架(向上)"
|
||||
L["Bar "] = "动作条 " --Also in ActionBars
|
||||
L["BNet Frame"] = "战网提示信息"
|
||||
L["Boss Frames"] = "首领框架"
|
||||
L["Classbar"] = "职业特有条"
|
||||
L["Experience Bar"] = "经验条"
|
||||
L["Focus Castbar"] = "焦点目标施法条"
|
||||
L["Focus Frame"] = "焦点目标框架"
|
||||
L["FocusTarget Frame"] = "焦点目标的目标框架"
|
||||
L["GM Ticket Frame"] = "GM对话框"
|
||||
L["Left Chat"] = "左侧对话框"
|
||||
L["Loot / Alert Frames"] = "拾取/提醒框"
|
||||
L["Loot Frame"] = "拾取框架"
|
||||
L["MA Frames"] = "主助理框"
|
||||
L["Micro Bar"] = "微型系统菜单" --Also in ActionBars
|
||||
L["Minimap"] = "小地图"
|
||||
L["MirrorTimer"] = "镜像计时器"
|
||||
L["MT Frames"] = "主坦克框"
|
||||
L["Party Frames"] = "队伍框架"
|
||||
L["Pet Bar"] = "宠物动作条" --Also in ActionBars
|
||||
L["Pet Castbar"] = "宠物施法条"
|
||||
L["Pet Frame"] = "宠物框架"
|
||||
L["PetTarget Frame"] = "宠物目标框架"
|
||||
L["Player Buffs"] = "玩家增益"
|
||||
L["Player Castbar"] = "玩家施法条"
|
||||
L["Player Debuffs"] = "玩家减益"
|
||||
L["Player Frame"] = "玩家框架"
|
||||
L["Player Powerbar"] = "玩家能量条"
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "团队框架"
|
||||
L["Raid Pet Frames"] = "团队宠物框架"
|
||||
L["Raid-40 Frames"] = "40人团队框架"
|
||||
L["Reputation Bar"] = "声望条"
|
||||
L["Right Chat"] = "右侧对话框"
|
||||
L["Stance Bar"] = "姿态条" --Also in ActionBars
|
||||
L["Target Castbar"] = "目标施法条"
|
||||
L["Target Frame"] = "目标框架"
|
||||
L["Target Powerbar"] = "目标能量条"
|
||||
L["TargetTarget Frame"] = "目标的目标框架"
|
||||
L["TargetTargetTarget Frame"] = "目标的目标的目标框架"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "鼠标提示"
|
||||
L["Vehicle Seat Frame"] = "载具座位框"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = "ElvUI插件安装"
|
||||
L["In Progress"] = "正在进行中"
|
||||
L["List of installations in queue:"] = "即将安装的列表:"
|
||||
L["Pending"] = "等待中"
|
||||
L["Steps"] = "步骤"
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00绑定到 |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "%s 个框架锚点冲突, 请移动buff或者debuff锚点让他们彼此不依附.暂时强制debuff依附到主框架."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "取消 |cff00ff00%s|r 所有绑定的快捷键."
|
||||
L["Already Running.. Bailing Out!"] = "正在运行!"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "战场信息暂时隐藏, 你可以通过输入/bgstats 或右键点击小地图旁「C」按钮显示."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "当你处于战场时战场信息将再次显示."
|
||||
L["Binds Discarded"] = "取消绑定"
|
||||
L["Binds Saved"] = "储存绑定"
|
||||
L["Confused.. Try Again!"] = "请再试一次!"
|
||||
L["No gray items to delete."] = "没有要删除的灰色物品"
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "法术'%s'已经被添加到单位框架的光环过滤器中."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = "这个设置引起一个互相矛盾的锚点, '%s' 被依附于他自身. 请检查你的锚点设置. 设置 '%s' 依附到 '%s'."
|
||||
L["Vendored gray items for:"] = "已出售灰色物品:"
|
||||
L["You don't have enough money to repair."] = "没有足够的资金来修复."
|
||||
L["You must be at a vendor."] = "你必需以商人为目标."
|
||||
L["Your items have been repaired for: "] = "装备已修复: "
|
||||
L["Your items have been repaired using guild bank funds for: "] = "物品已使用公会银行资金修复: "
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000LUA错误已接收, 你可以在脱离战斗后检查.|r"
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "你所做的改动只会影响到使用这个插件的本角色, 你需要重新加载界面才能使改动生效."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = "确定要对所有ElvUI元素使用这个字体?"
|
||||
L["Are you sure you want to delete all your gray items?"] = "确定需要摧毁你的灰色物品?"
|
||||
L["Are you sure you want to disband the group?"] = "确定要解散队伍?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "确定需要重置这个配置文件中的所有设置?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "确定需要重置所有框架至默认位置?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "由于大量的改动导致光环系统需要一个新的安装过程. 这是可选的, 最后一步将设置你的光环样式. 点击「完成」将不再提示. 如果由于某些原因反复提示, 请重新开启游戏."
|
||||
L["Can't buy anymore slots!"] = "银行背包栏位已达最大值"
|
||||
L["Disable Warning"] = "停用警告"
|
||||
L["Discard"] = "取消"
|
||||
L["Do you enjoy the new ElvUI?"] = "你喜欢新的ElvUI么?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "你发誓在你没停用其他插件前不会到技术支持询问某些功能失效吗?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI已过期5个或者更多的版本。你可以在 https://github.com/ElvUI-WotLK/ElvUI/ 下载到最新的版本"
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = true;
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI需要进行数据库优化, 请耐性等待."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "移动鼠标到动作条或技能书按钮上绑定快捷键. 按ESC或鼠标右键取消目前快捷键"
|
||||
L["I Swear"] = "我承诺"
|
||||
L["No, Revert Changes!"] = "不, 撤销修改!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "你不能同时使用Elvui和Tukui, 请选择一个禁用."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "已变更一或多个设定, 需重载界面."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "你所做的改动可能会影响到使用这个插件的所有角色, 你需要重新加载界面才能使改动生效."
|
||||
L["Save"] = "储存"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "你尝试导入的配置文件已经存在.请选择一个新的名字或者确认覆盖存在的配置文件."
|
||||
L["Type /hellokitty to revert to old settings."] = "输入/hellokitty以撤销到原来的设定"
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "使用治疗布局时建议你下载 Clique 插件,从而拥有点击施法功能"
|
||||
L["Yes, Keep Changes!"] = "是的, 保存修改!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "你选择了细边框主题选项,你必须完成安装程序来移除任何图像错误"
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "你改变了界面缩放比例, 然而ElvUI的自动缩放选项是开启的.点击接受以关闭ElvUI的自动缩放."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "你导入的设置可能需要重载界面才能生效.确认重载?"
|
||||
L["You must purchase a bank slot first!"] = "你必需购买一个银行背包栏位"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "计数"
|
||||
L["Item Level:"] = "物品等级:"
|
||||
L["Talent Specialization:"] = "天赋专精:"
|
||||
L["Targeted By:"] = "同目标的有:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "你可以通过按ESC键 -> 按键设置, 滚动到ElvUI设置下方设置一个快速标记的快捷键."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "ElvUI可以根据你所使用的天赋自动套用不同的设置档. 你可以在配置文件中使用此功能."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "如需技术支援请至 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "如果你不慎移除了对话框, 你可以重新安装一次重置他们."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "如果你遇到问题, ElvUI会尝试禁用你除了ElvUI之外的插件. 请记住你不能用不同的插件实现同一功能."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "你可以通过 /focus 命令设置焦点目标."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "你可以通过按住Shift拖动技能条中的按键. 你可以在 Blizzard 的动作条设置中更改按键."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "你可以通过右键点击对话框标签栏设置你需要在对话框内显示的频道."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "你可以通过鼠标滑过对话框右上角点击复制图标打开对话复制窗口."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "你可以通过按住Shift并将鼠标滑过目标看到目标的装备等级, 这将显示在你的鼠标提示框内."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "你可以通过输入 /kb 快速绑定按键."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "你可以通过鼠标中键点击小地图或在动作条设置内选择打开微型系统栏."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "使用 /resetui 命令可以重置你的所有框架位置. 你也可以通过命令 /resetui <框架名称> 单独重置某个框架.\n例如: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = "死亡"
|
||||
L["Ghost"] = "鬼魂"
|
||||
L["Offline"] = "离线"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- English localization file for enUS and enGB.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0");
|
||||
local L = AceLocale:NewLocale("ElvUI", "enUS", true, true);
|
||||
if not L then return; end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "The addon %s is not compatible with ElvUI's %s module. Please select either the addon or the ElvUI module to disable."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Welcome to %sElvUI|r version %s%s|r, type /ec to access the in-game configuration menu. If you are in need of technical support you can visit us at https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = true;
|
||||
L["Key"] = true;
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = true;
|
||||
L["Remove Bar %d Action Page"] = true;
|
||||
L["Trigger"] = true;
|
||||
|
||||
--Bags
|
||||
L["Bank"] = true;
|
||||
L["Hold Control + Right Click:"] = true;
|
||||
L["Hold Shift + Drag:"] = true;
|
||||
L["Purchase Bags"] = true;
|
||||
L["Reset Position"] = true;
|
||||
L["Sort Bags"] = true;
|
||||
L["Temporary Move"] = true;
|
||||
L["Toggle Bags"] = true;
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = true;
|
||||
|
||||
--Chat
|
||||
L["AFK"] = true; --Also used in datatexts
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = true; --Also used in datatexts
|
||||
L["G"] = true;
|
||||
L["Invalid Target"] = true;
|
||||
L["O"] = true;
|
||||
L["P"] = true;
|
||||
L["PL"] = true;
|
||||
L["R"] = true;
|
||||
L["RL"] = true;
|
||||
L["RW"] = true;
|
||||
L["says"] = true;
|
||||
L["whispers"] = true;
|
||||
L["yells"] = true;
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = true;
|
||||
L["Avoidance Breakdown"] = true;
|
||||
L["Character: "] = true;
|
||||
L["Chest"] = true;
|
||||
L["Combat"] = true;
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55fc|r" --Also used in Bags
|
||||
L["Deficit:"] = true;
|
||||
L["DPS"] = true;
|
||||
L["Earned:"] = true;
|
||||
L["Friends List"] = true;
|
||||
L["Friends"] = true; --Also in Skins
|
||||
L["Gold"] = true;
|
||||
L["goldabbrev"] = "|cffffd700g|r" --Also used in Bags
|
||||
L["Hit"] = true;
|
||||
L["Hold Shift + Right Click:"] = true;
|
||||
L["Home Latency:"] = true;
|
||||
L["HP"] = true;
|
||||
L["HPS"] = true;
|
||||
L["lvl"] = true;
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = true;
|
||||
L["No Guild"] = true;
|
||||
L["Profit:"] = true;
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = true;
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = true;
|
||||
L["Server: "] = true;
|
||||
L["Session:"] = true;
|
||||
L["silverabbrev"] = "|cffc7c7cfs|r" --Also used in Bags
|
||||
L["SP"] = true;
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = true;
|
||||
L["Stats For:"] = true;
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = true;
|
||||
L["Total Memory:"] = true;
|
||||
L["Total: "] = true;
|
||||
L["Unhittable:"] = true;
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = true;
|
||||
L["No locals to dump"] = true;
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = true;
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = true;
|
||||
L["Data From: %s"] = true;
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = true;
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = true;
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = true;
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = true;
|
||||
L["Profile request sent. Waiting for response from player."] = true;
|
||||
L["Request was denied by user."] = true;
|
||||
L["Your profile was successfully recieved by the player."] = true;
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = true;
|
||||
L["Auras Set"] = true;
|
||||
L["Auras"] = true;
|
||||
L["Caster DPS"] = true;
|
||||
L["Chat Set"] = true;
|
||||
L["Chat"] = true;
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = true;
|
||||
L["Classic"] = true;
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = true;
|
||||
L["Config Mode:"] = true;
|
||||
L["CVars Set"] = true;
|
||||
L["CVars"] = true;
|
||||
L["Dark"] = true;
|
||||
L["Disable"] = true;
|
||||
L["ElvUI Installation"] = true;
|
||||
L["Finished"] = true;
|
||||
L["Grid Size:"] = true;
|
||||
L["Healer"] = true;
|
||||
L["High Resolution"] = true;
|
||||
L["high"] = true;
|
||||
L["Icons Only"] = true; --Also used in Bags
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = true;
|
||||
L["Importance: |cff07D400High|r"] = true;
|
||||
L["Importance: |cffD3CF00Medium|r"] = true;
|
||||
L["Importance: |cffFF0000Low|r"] = true;
|
||||
L["Installation Complete"] = true;
|
||||
L["Layout Set"] = true;
|
||||
L["Layout"] = true;
|
||||
L["Lock"] = true;
|
||||
L["Low Resolution"] = true;
|
||||
L["low"] = true;
|
||||
L["Nudge"] = true;
|
||||
L["Physical DPS"] = true;
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = true;
|
||||
L["Please click the button below to setup your CVars."] = true;
|
||||
L["Please press the continue button to go onto the next step."] = true;
|
||||
L["Resolution Style Set"] = true;
|
||||
L["Resolution"] = true;
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = true;
|
||||
L["Setup Chat"] = true;
|
||||
L["Setup CVars"] = true;
|
||||
L["Skip Process"] = true;
|
||||
L["Sticky Frames"] = true;
|
||||
L["Tank"] = true;
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = true;
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = true;
|
||||
L["Theme Set"] = true;
|
||||
L["Theme Setup"] = true;
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = true;
|
||||
L["This is completely optional."] = true;
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = true;
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = true;
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = true;
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = true;
|
||||
L["This will change the layout of your unitframes and actionbars."] = true;
|
||||
L["Trade"] = true;
|
||||
L["Welcome to ElvUI version %s!"] = true;
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = true;
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = true;
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = true;
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = true;
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = true;
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = true; --Also used in UnitFrames
|
||||
L["Calendar"] = true;
|
||||
L["Can't Roll"] = true;
|
||||
L["Disband Group"] = true;
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = true; --Doesn't fit a section since it's used a lot of places
|
||||
L["Experience"] = true;
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = true;
|
||||
L["Left Click:"] = true; --layout\layout.lua
|
||||
L["Raid Menu"] = true;
|
||||
L["Remaining:"] = true;
|
||||
L["Rested:"] = true;
|
||||
L["Right Click:"] = true; --layout\layout.lua
|
||||
L["Show BG Texts"] = true; --layout\layout.lua
|
||||
L["Toggle Chat Frame"] = true; --layout\layout.lua
|
||||
L["Toggle Configuration"] = true; --layout\layout.lua
|
||||
L["XP:"] = true;
|
||||
L["You don't have permission to mark targets."] = true;
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = true; --Also used in UnitFrames
|
||||
L["Bag Mover (Grow Down)"] = true;
|
||||
L["Bag Mover (Grow Up)"] = true;
|
||||
L["Bag Mover"] = true;
|
||||
L["Bags"] = true; --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = true;
|
||||
L["Bank Mover (Grow Up)"] = true;
|
||||
L["Bar "] = true; --Also in ActionBars
|
||||
L["BNet Frame"] = true;
|
||||
L["Boss Frames"] = true; --Also used in UnitFrames
|
||||
L["Classbar"] = true; --Also used in UnitFrames
|
||||
L["Experience Bar"] = true;
|
||||
L["Focus Castbar"] = true;
|
||||
L["Focus Frame"] = true; --Also used in UnitFrames
|
||||
L["FocusTarget Frame"] = true; --Also used in UnitFrames
|
||||
L["GM Ticket Frame"] = true;
|
||||
L["Left Chat"] = true;
|
||||
L["Loot / Alert Frames"] = true;
|
||||
L["Loot Frame"] = true;
|
||||
L["MA Frames"] = true;
|
||||
L["Micro Bar"] = true; --Also in ActionBars
|
||||
L["Minimap"] = true;
|
||||
L["MirrorTimer"] = true;
|
||||
L["MT Frames"] = true;
|
||||
L["Party Frames"] = true; --Also used in UnitFrames
|
||||
L["Pet Bar"] = true; --Also in ActionBars
|
||||
L["Pet Castbar"] = true;
|
||||
L["Pet Frame"] = true; --Also used in UnitFrames
|
||||
L["PetTarget Frame"] = true; --Also used in UnitFrames
|
||||
L["Player Buffs"] = true;
|
||||
L["Player Castbar"] = true;
|
||||
L["Player Debuffs"] = true;
|
||||
L["Player Frame"] = true; --Also used in UnitFrames
|
||||
L["Player Powerbar"] = true;
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = true;
|
||||
L["Raid Pet Frames"] = true;
|
||||
L["Raid-40 Frames"] = true;
|
||||
L["Reputation Bar"] = true;
|
||||
L["Right Chat"] = true;
|
||||
L["Stance Bar"] = true; --Also in ActionBars
|
||||
L["Target Castbar"] = true;
|
||||
L["Target Frame"] = true; --Also used in UnitFrames
|
||||
L["Target Powerbar"] = true;
|
||||
L["TargetTarget Frame"] = true; --Also used in UnitFrames
|
||||
L["TargetTargetTarget Frame"] = true; --Also used in UnitFrames
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = true;
|
||||
L["Vehicle Seat Frame"] = true;
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = true;
|
||||
L["In Progress"] = true;
|
||||
L["List of installations in queue:"] = true;
|
||||
L["Pending"] = true;
|
||||
L["Steps"] = true;
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = true;
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = true;
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = true;
|
||||
L["Already Running.. Bailing Out!"] = true;
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = true;
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = true;
|
||||
L["Binds Discarded"] = true;
|
||||
L["Binds Saved"] = true;
|
||||
L["Confused.. Try Again!"] = true;
|
||||
L["No gray items to delete."] = true;
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = true;
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = true;
|
||||
L["Vendored gray items for:"] = true;
|
||||
L["You don't have enough money to repair."] = true;
|
||||
L["You must be at a vendor."] = true;
|
||||
L["Your items have been repaired for: "] = true;
|
||||
L["Your items have been repaired using guild bank funds for: "] = true;
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = true;
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = true;
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = true;
|
||||
L["Are you sure you want to delete all your gray items?"] = true;
|
||||
L["Are you sure you want to disband the group?"] = true;
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = true;
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = true;
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = true;
|
||||
L["Can't buy anymore slots!"] = true;
|
||||
L["Disable Warning"] = true;
|
||||
L["Discard"] = true;
|
||||
L["Do you enjoy the new ElvUI?"] = true;
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = true;
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = true;
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = true;
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = true;
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = true;
|
||||
L["I Swear"] = true;
|
||||
L["No, Revert Changes!"] = true;
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = true;
|
||||
L["One or more of the changes you have made require a ReloadUI."] = true;
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = true;
|
||||
L["Save"] = true;
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = true;
|
||||
L["Type /hellokitty to revert to old settings."] = true;
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = true;
|
||||
L["Yes, Keep Changes!"] = true;
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = true;
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = true;
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = true;
|
||||
L["You must purchase a bank slot first!"] = true;
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = true;
|
||||
L["Item Level:"] = true;
|
||||
L["Talent Specialization:"] = true;
|
||||
L["Targeted By:"] = true;
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = true;
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = true;
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = true;
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = true;
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = true;
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = true;
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = true;
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = true;
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = true;
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = true;
|
||||
L["You can set your keybinds quickly by typing /kb."] = true;
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = true;
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = true;
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = true;
|
||||
L["Ghost"] = true;
|
||||
L["Offline"] = true;
|
||||
@@ -0,0 +1,346 @@
|
||||
-- French localization file for frFR.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0");
|
||||
local L = AceLocale:NewLocale("ElvUI", "frFR");
|
||||
if not L then return; end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "L'addon %s n'est pas compatible avec le module %s d'ElvUI. Merci de sélectionner soit l'addon ou le module d'ElvUI pour le désactiver."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Bienvenue sur %sElvUI|r version %s%s|r, tapez /ec afin d'accéder au menu de configuration en jeu. Si vous avez besoin d'un support technique, vous pouvez nous rejoindre sur https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "Raccourcis"
|
||||
L["Key"] = "Touche"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Suppr"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "Aucune assignation"
|
||||
L["Remove Bar %d Action Page"] = "Retirer la pagination de la barre d'action"
|
||||
L["Trigger"] = "Déclencheur"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "Banque"
|
||||
L["Hold Control + Right Click:"] = "Contrôle enfoncé + Clique droit"
|
||||
L["Hold Shift + Drag:"] = "Majuscule enfoncée + Déplacer"
|
||||
L["Purchase Bags"] = "Acheter des sacs"
|
||||
L["Reset Position"] = "Réinitialiser la position"
|
||||
L["Sort Bags"] = "Trier les sacs"
|
||||
L["Temporary Move"] = "Déplacer temporairement"
|
||||
L["Toggle Bags"] = "Afficher les sacs"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "Vendre les objets gris"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "ABS" --Also used in datatexts and tooltip
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "NPD" --Also used in datatexts and tooltip
|
||||
L["G"] = "G"
|
||||
L["Invalid Target"] = "Cible incorrecte"
|
||||
L["O"] = "O"
|
||||
L["P"] = "Gr"
|
||||
L["PL"] = "CdG"
|
||||
L["R"] = "R"
|
||||
L["RL"] = "RL"
|
||||
L["RW"] = "RW"
|
||||
L["says"] = "dit"
|
||||
L["whispers"] = "chuchote"
|
||||
L["yells"] = "crie"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(Maintenir MAJ) Utilisation de la Mémoire."
|
||||
L["Avoidance Breakdown"] = "Répartition de l'évitement"
|
||||
L["Character: "] = "Personnage: "
|
||||
L["Chest"] = "Torse"
|
||||
L["Combat"] = "Combat"
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55fc|r" --Also used in Bags
|
||||
L["Deficit:"] = "Déficit:"
|
||||
L["DPS"] = "DPS"
|
||||
L["Earned:"] = "Gagné:"
|
||||
L["Friends List"] = "Liste d'amis"
|
||||
L["Friends"] = "Amis" --Also in Skins
|
||||
L["Gold"] = true;
|
||||
L["goldabbrev"] = "|cffffd700g|r" --Also used in Bags
|
||||
L["Hit"] = "Toucher"
|
||||
L["Hold Shift + Right Click:"] = "Maintenir Majuscule + Clic droit"
|
||||
L["Home Latency:"] = "Latence du Domicile:"
|
||||
L["HP"] = "PdS"
|
||||
L["HPS"] = "HPS"
|
||||
L["lvl"] = "niveau"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "Réduction par niveau: "
|
||||
L["No Guild"] = "Pas de Guilde"
|
||||
L["Profit:"] = "Profit:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "RAZ des données: MAJ + Clic droit"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "Raid(s) Sauvegardé(s)"
|
||||
L["Server: "] = "Serveur: "
|
||||
L["Session:"] = "Session:"
|
||||
L["silverabbrev"] = "|cffc7c7cfs|r" --Also used in Bags
|
||||
L["SP"] = "PdS"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "Dépensé: "
|
||||
L["Stats For:"] = "Stats pour:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "Charge du CPU:"
|
||||
L["Total Memory:"] = "Mémoire totale:"
|
||||
L["Total: "] = "Total: "
|
||||
L["Unhittable:"] = "Intouchable:"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s a essayé d'appeler la fonction protégée '%s'."
|
||||
L["No locals to dump"] = "Aucunes données à vider"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s tente de partager ses filtres avec vous. Voulez-vous accepter la demande?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s tente de partager le profil %s avec vous. Voulez-vous accepter la demande?"
|
||||
L["Data From: %s"] = "Donnée de: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "Téléchargement du filtre de %s complet, voulez-vous appliquer les changements maintenant ?" --Need review
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "Seigneur ! C'est un miracle ! Le téléchargement s'est envolé et a disparu comme un pet dans le vent! Essayez encore !"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "Téléchargement du profil de %s complet, mais le profil de % existe déjà. Changez le nom ou il écrasera le profil existant."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "Téléchargement du profil de %s complet, voulez-vous charger le profil %s maintenant?"
|
||||
L["Profile request sent. Waiting for response from player."] = "Requête du profil envoyé. En attente de la réponse du joueur."
|
||||
L["Request was denied by user."] = "La requête a été refusée par l'utilisateur."
|
||||
L["Your profile was successfully recieved by the player."] = "Votre profil a été reçu avec succès par le joueur."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "Barres d'Auras & Icônes"
|
||||
L["Auras Set"] = "Configuration des Auras"
|
||||
L["Auras"] = "Auras"
|
||||
L["Caster DPS"] = "DPS Distance"
|
||||
L["Chat Set"] = "Chat configuré"
|
||||
L["Chat"] = "Discussion"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "Choisissez un modèle de thème que vous souhaitez utiliser pour votre configuration initiale."
|
||||
L["Classic"] = "Classique"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "Cliquez sur le bouton ci-dessous pour redimensionner vos fenêtres de chat, vos cadres d'unités et repositionner vos barres d'actions."
|
||||
L["Config Mode:"] = "Mode Configuration:"
|
||||
L["CVars Set"] = "CVars configurés"
|
||||
L["CVars"] = "CVars"
|
||||
L["Dark"] = "Sombre"
|
||||
L["Disable"] = "Désactiver"
|
||||
L["ElvUI Installation"] = "Installation d'ElvUI"
|
||||
L["Finished"] = "Terminé"
|
||||
L["Grid Size:"] = "Taille de la Grille:"
|
||||
L["Healer"] = "Soigneur"
|
||||
L["High Resolution"] = "Haute Résolution"
|
||||
L["high"] = "Haute"
|
||||
L["Icons Only"] = "Icônes seulement" --Also used in Bags
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "Si vous avez une icône ou une barre d'aura que vous ne souhaitez pas afficher il suffit de maintenir la touche MAJ enfoncée et d'effectuer un clic droit sur l'icône correspondante pour la faire disparaitre."
|
||||
L["Importance: |cff07D400High|r"] = "Importance: |cff07D400Haute|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "Importance: |cffD3CF00Moyenne|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "Importance: |cffFF0000Faible|r"
|
||||
L["Installation Complete"] = "Installation terminée"
|
||||
L["Layout Set"] = "Disposition configurée"
|
||||
L["Layout"] = "Disposition"
|
||||
L["Lock"] = "Verrouiller"
|
||||
L["Low Resolution"] = "Basse résolution"
|
||||
L["low"] = "Faible"
|
||||
L["Nudge"] = "Pousser"
|
||||
L["Physical DPS"] = "DPS Physique"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "Pour configurer les variables et recharger l'interface, cliquez sur le bouton ci-dessous."
|
||||
L["Please click the button below to setup your CVars."] = "Pour configurer les CVars, cliquez sur le bouton ci-dessous."
|
||||
L["Please press the continue button to go onto the next step."] = "Pour passer à l'étape suivante, cliquez sur le bouton Continuer."
|
||||
L["Resolution Style Set"] = "Paramètre de résolution configuré"
|
||||
L["Resolution"] = "Résolution"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "Sélectionnez le système d`auras que vous voulez utiliser avec les cadres d`unités ElvUI. Sélectionnez Barres d'Auras & Icônes pour utiliser à la fois les barres et les icônes, choisissez Icônes pour voir seulement les icônes."
|
||||
L["Setup Chat"] = "Configurer le Chat."
|
||||
L["Setup CVars"] = "Configurer les CVars"
|
||||
L["Skip Process"] = "Passer cette étape"
|
||||
L["Sticky Frames"] = "Cadres aimantés"
|
||||
L["Tank"] = "Tank"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "La fenêtre de chat ElvUI utilise les même fonctions que celle de Blizzard, vous pouvez faire un clique droit sur un onglet pour le déplacer, le renommer, etc."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "Le menu de configuration est accessible en tapant la commande /ec ou en cliquant sur le bouton 'C' sur la Mini-carte. Cliquez sur le bouton ci-dessous si vous voulez passer le processus d'installation."
|
||||
L["Theme Set"] = "Thème configuré"
|
||||
L["Theme Setup"] = "Configuration du thème"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "Ce programme d'installation vous aidera à découvrir quelques fonctionnalités qu'ElvUI offre et préparera également votre interface à son utilisation."
|
||||
L["This is completely optional."] = "Ceci est totalement optionnel."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "Cette partie du processus d'installation configure les noms, positions et couleurs de vos fenêtres de chat."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "Cette partie du processus d'installation paramètrera vos options par défaut de World of Warcraft. Il est recommandé d'effectuer cette étape afin que tout fonctionne correctement."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "Cette résolution ne nécessite pas que vous modifiez les paramètres de l'interface utilisateur pour s'adapter à votre écran."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "Cette résolution nécessite que vous modifiez les paramètres de l'interface utilisateur pour s'adapter à votre écran."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "Ceci changera la disposition des cadres d'unités et des barres d'actions."
|
||||
L["Trade"] = "Échanger"
|
||||
L["Welcome to ElvUI version %s!"] = "Bienvenue sur la version %s d'ElvUI!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Vous avez maintenant terminé le processus d'installation. Si vous avez besoin d'un support technique, merci de vous rendre sur https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "Vous pouvez toujours modifier les polices et les couleurs de n'importe quel élément d'Elvui dans la configuration du jeu."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "Vous pouvez maintenant choisir quelle disposition vous souhaitez utiliser en fonction de votre rôle en combat."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "Vous devrez peut-être encore modifier ces paramètres en fonction d'un changement de résolution."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "Votre résolution actuelle est %s, elle est donc considérée comme une %s Résolution."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% excès |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "Barres" --Also used in UnitFrames
|
||||
L["Calendar"] = "Calendrier"
|
||||
L["Can't Roll"] = "Ne peut pas jeter les dés"
|
||||
L["Disband Group"] = "Dissoudre le groupe"
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = "Activer" --Doesn't fit a section since it's used a lot of places
|
||||
L["Experience"] = "Expérience"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "Butin de pêche"
|
||||
L["Left Click:"] = "Clique Gauche:" --layout\layout.lua
|
||||
L["Raid Menu"] = "Menu Raid"
|
||||
L["Remaining:"] = "Restant:"
|
||||
L["Rested:"] = "Reposé:"
|
||||
L["Right Click:"] = "Clique Droit:" --layout\layout.lua
|
||||
L["Show BG Texts"] = "Voir les textes de BG" --layout\layout.lua
|
||||
L["Toggle Chat Frame"] = "Activer la fenêtre de discussion" --layout\layout.lua
|
||||
L["Toggle Configuration"] = "Afficher la Configuration" --layout\layout.lua
|
||||
L["XP:"] = "XP:"
|
||||
L["You don't have permission to mark targets."] = "Vous n'avez pas la permission de marquer les cibles."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "Cadre d'arène" --Also used in UnitFrames
|
||||
L["Bag Mover (Grow Down)"] = true;
|
||||
L["Bag Mover (Grow Up)"] = true;
|
||||
L["Bag Mover"] = true;
|
||||
L["Bags"] = "Sacs" --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = true;
|
||||
L["Bank Mover (Grow Up)"] = true;
|
||||
L["Bar "] = "Barre " --Also in ActionBars
|
||||
L["BNet Frame"] = "Cadre BNet"
|
||||
L["Boss Frames"] = "Cadre du Boss" --Also used in UnitFrames
|
||||
L["Classbar"] = "Barre de Classe"
|
||||
L["Experience Bar"] = "Barre d'expérience"
|
||||
L["Focus Castbar"] = "Barre d'incantation du Focus"
|
||||
L["Focus Frame"] = "Cadre Focus" --Also used in UnitFrames
|
||||
L["FocusTarget Frame"] = "Cadre de la cible de votre Focus" --Also used in UnitFrames
|
||||
L["GM Ticket Frame"] = "Cadre du ticket MJ"
|
||||
L["Left Chat"] = "Chat gauche"
|
||||
L["Loot / Alert Frames"] = "Cadres de butin / Alerte"
|
||||
L["Loot Frame"] = "Cadre de butin"
|
||||
L["MA Frames"] = "Cadres de l`assistant principal"
|
||||
L["Micro Bar"] = "Micro Barre" --Also in ActionBars
|
||||
L["Minimap"] = "Mini-carte"
|
||||
L["MirrorTimer"] = "Timer mirroir"
|
||||
L["MT Frames"] = "Cadres du Tank principal"
|
||||
L["Party Frames"] = "Cadres de groupe" --Also used in UnitFrames
|
||||
L["Pet Bar"] = "Barre du familier" --Also in ActionBars
|
||||
L["Pet Castbar"] = "Barre d'incantation du familier"
|
||||
L["Pet Frame"] = "Cadre du familier" --Also used in UnitFrames
|
||||
L["PetTarget Frame"] = "Cadre de la cible du familier" --Also used in UnitFrames
|
||||
L["Player Buffs"] = "Améliorations du joueur"
|
||||
L["Player Castbar"] = "Barre d'incantation du joueur"
|
||||
L["Player Debuffs"] = "Affaiblissements du joueur"
|
||||
L["Player Frame"] = "Cadre du joueur" --Also used in UnitFrames
|
||||
L["Player Powerbar"] = "Barre de pouvoir du joueur" -- need review.
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "Cadres de Raid"
|
||||
L["Raid Pet Frames"] = "Cadres de Raid des Familiers"
|
||||
L["Raid-40 Frames"] = "Cadres de Raid 40"
|
||||
L["Reputation Bar"] = "Barre de réputation"
|
||||
L["Right Chat"] = "Chat de droite"
|
||||
L["Stance Bar"] = "Barre de posture" --Also in ActionBars
|
||||
L["Target Castbar"] = "Barre d'incantation de la cible"
|
||||
L["Target Frame"] = "Cadre de la cible" --Also used in UnitFrames
|
||||
L["Target Powerbar"] = "Barre de pouvoir de la cible" -- need review.
|
||||
L["TargetTarget Frame"] = "Cadre de la cible de votre cible" --Also used in UnitFrames
|
||||
L["TargetTargetTarget Frame"] = "Cadre de la cible de la cible de la cible"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "Infobulle"
|
||||
L["Vehicle Seat Frame"] = "Cadre de siège du véhicule"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = true;
|
||||
L["In Progress"] = true;
|
||||
L["List of installations in queue:"] = true;
|
||||
L["Pending"] = true;
|
||||
L["Steps"] = true;
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = "|cff00ff00assigné à |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "% du (des) cadre(s) à un point d'ancrage contradictoire(s), merci de changer le point d'ancrage des améliorations ou des affaiblissements de sorte qu'ils ne soient pas attachés les uns aux autres. Forcer les affaiblissements à être attachés au cadre d'unité principale jusqu'à ce qu'ils soient fixés."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "Tous les raccourcis ont été effacés pour |cff00ff00%s|r."
|
||||
L["Already Running.. Bailing Out!"] = "Déjà en cours d'exécution, arrêt du processus..."
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "Textes d'informations du champ de bataille temporairement masqués, pour les afficher tapez /bgstats ou cliquez droit sur le 'C' près de la mini-carte."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "Les textes d'informations du champ de bataille seront à nouveau affichés si vous êtes dans un champ de bataille."
|
||||
L["Binds Discarded"] = "Raccourcis annulés"
|
||||
L["Binds Saved"] = "Raccourcis sauvegardés"
|
||||
L["Confused.. Try Again!"] = "Confus...Essayez à nouveau!"
|
||||
L["No gray items to delete."] = "Aucun objet gris à détruire."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "Le sort '%s' a bien été ajouté à la liste noire des filtres des cadres d'unités."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = true;
|
||||
L["Vendored gray items for:"] = "Objets gris vendus pour:"
|
||||
L["You don't have enough money to repair."] = "Vous n'avez pas assez d'argent pour réparer votre équipement."
|
||||
L["You must be at a vendor."] = "Vous devez être chez un marchand."
|
||||
L["Your items have been repaired for: "] = "Votre équipement a été réparé pour: "
|
||||
L["Your items have been repaired using guild bank funds for: "] = "Votre équipement a été réparé avec l'argent de la banque de guilde pour: "
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000Erreur Lua reçue. Vous pouvez voir ce message d'erreur quand vous sortirez de combat."
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "Un réglage que vous avez modifié ne s'appliquera que pour ce personnage. La modification de ce réglage ne sera pas affecté par un changement de profil. Changer ce réglage requiert de relancer l'interface."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = "En acceptant, votre liste de priorités des filtres sera réinitialisée pour les auras des cadres d'unités. Êtes-vous sûr ?"
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = true;
|
||||
L["Are you sure you want to delete all your gray items?"] = "Êtes-vous sûr de vouloir détruire tous vos Objets Gris ?"
|
||||
L["Are you sure you want to disband the group?"] = "Êtes-vous sûr de vouloir dissoudre le groupe ? "
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "Êtes-vous sûr de vouloir réinitialiser tous les réglages sur ce profile?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "Êtes-vous sûr de vouloir réinitialiser tous les cadres à leur position par défaut ?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "En raison de la confusion générale provoquée par le nouveau système d'aura, j'ai mis en place une nouvelle étape dans le processus d'installation. Cette option est facultative. Si vous aimez la façon dont vos auras sont configurés allez à la dernière étape et cliquez sur Terminé pour ne pas être averti à nouveau. Si, pour une raison quelconque, vous êtes averti de nouveau, relancez complètement le jeu."
|
||||
L["Can't buy anymore slots!"] = "Impossible d'acheter plus emplacements !"
|
||||
L["Disable Warning"] = "Désactiver l'alerte"
|
||||
L["Discard"] = "Annuler"
|
||||
L["Do you enjoy the new ElvUI?"] = "Aimez-vous le nouveau ElvUI?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "Jurez-vous de ne pas poster sur le support technique du forum sur quelque chose qui ne fonctionne pas sans avoir désactivé en premier la combinaison Addon/Module?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI est périmé d'au moins 5 versions. Vous pouvez télécharger la nouvelle version sur https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI est périmé. Vous pouvez télécharger la nouvelle version sur https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI a besoin d'effectuer des optimisations de la base de données, merci de patienter."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "Passez votre souris sur n'importe quel bouton d'action ou bouton du grimoire pour lui attribuer un raccourcis. Appuyez sur la touche Échap ou le clique droit pour effacer le raccourci en cours."
|
||||
L["I Swear"] = "Je le jure"
|
||||
L["No, Revert Changes!"] = "Non, annuler les changements!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "Oh seigneur, vous avez ElvUI et Tukui d'activé en même temps. Sélectionnez un addon à désactiver."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "Une ou plusieurs modifications que vous avez effectuées nécessitent un rechargement de l'interface."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "Un ou plusieurs changement(s) que vous avez effectué a une incidence sur tous les personnages qui utilisent cet Addon. Vous devriez recharger l'interface utilisateur pour voir le(s) changement(s) apporté(s)."
|
||||
L["Save"] = "Sauvegarder"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "Le profil que vous essayez d'importer existe déjà. Choisissez un nouveau nom ou acceptez d'écraser le profil existant."
|
||||
L["Type /hellokitty to revert to old settings."] = "Tapez /hellokitty pour recharger les anciennes configurations"
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "Si vous utilisez l'agencement Soigneur, il est hautement recommandé de télécharger l'Addon Clique si vous souhaitez avoir la fonction cliquer-pour-soigner."
|
||||
L["Yes, Keep Changes!"] = "Oui, garder les changements!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = true;
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "Vous venez de changer l'échelle de votre interface, alors que votre option d'échelle automatique est encore activée dans ElvUI. Cliquer sur accepter si vous voulez désactiver l'option d'échelle automatique."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "Vous avez importé des paramètes qui requierent un rechargement de l'interface. Recharger maintenant ?"
|
||||
L["You must purchase a bank slot first!"] = "Vous devez d'abord acheter un emplacement de banque!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "Nombre:"
|
||||
L["Item Level:"] = "Niveau d'équipement"
|
||||
L["Talent Specialization:"] = "Spécialisation des talents"
|
||||
L["Targeted By:"] = "Ciblé par:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "Une fonction marqueur de raid est disponible en appuyant sur Échap -> Raccourcis, défilez en bas d'ElvUI et paramétrez le raccourcis pour le marqueur de raid."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "ElvUI dispose d'une fonction double spécialisation qui vous permet de charger à la volée des profils différents en fonction de votre spécialisation actuelle."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Pour tout support technique, merci de nous visiter à https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "Si vous supprimez accidentellement un cadre de discussion, vous pouvez toujours aller dans le menu de configuration d'ElvUI. Cliquez ensuite sur Installation puis passez à l'étape concernant les fenêtres de discussion pour remettre à zéro les paramètres."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "Si vous rencontrez des problèmes avec ElvUI, essayez de désactiver tous vos addons sauf ElvUI. Rappelez-vous que'ElvUi est une interface utilisateur complète et que vous ne pouvez pas exécuter deux addons qui font la même chose."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "Le cadre de focus peut être défini en tapant /focus quand vous êtes en train de cibler une unité que vous voulez focus. Il est recommandé de faire une macro pour cela."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "Pour déplacer par défaut les capacités des barres d'actions, maintenez MAJ + déplacer. Vous pouvez modifier la touche de modification dans le menu des barres d'actions."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "Pour configurer quels canaux de discussions doivent apparaitre dans les fenêtres de Chat, faites un clic droit sur l'onglet de Chat et allez dans les paramètres."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "Vous pouvez accéder à une copie du Chat et des fonctions du Chat en survolant avec votre souris le coin haut droit de la fenêtre de discussion. Cliquez ensuite sur le bouton."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "Vous pouvez voir le niveau d'objet moyen de n'importe qui en maintenant la touche MAJ enfoncée puis en passant votre souris sur un joueur. Le score apparaitra dans la bulle d'information."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "Vous pouvez assignez rapidement vos raccourcis en tapant /kb."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "Vous pouvez afficher la microbarre en utilisant le bouton central de votre souris sur la minicarte. Vous pouvez aussi l'afficher via les réglages des Barres d'actions"
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "Vous pouvez utiliser la commande /resetui pour réinitialiser l'ensemble de vos cadres. Vous pouvez aussi utiliser la commande /resetui <nom du cadre> pour réinitialiser un cadre spécifique.\nExemple: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = "Mort"
|
||||
L["Ghost"] = "Fantôme"
|
||||
L["Offline"] = "Déconnecté"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- German localization file for deDE.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "deDE")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "Das Addon %s ist nicht mit dem ElvUI %s Modul kompatibel. Bitte deaktiviere entweder das Addon oder deaktiviere das ElvUI Modul."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Willkommen zu %sElvUI|r Version %s%s|r, Tippe /ec um das Konfigurationsmenü aufzurufen. Für technische Hilfe, besuche das Supportforum unter https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "Belegung"
|
||||
L["Key"] = "Taste"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "Keine Belegungen gesetzt."
|
||||
L["Remove Bar %d Action Page"] = "Entferne Leiste %d Aktion Seite"
|
||||
L["Trigger"] = "Auslöser"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = true;
|
||||
L["Hold Control + Right Click:"] = "Halte Steuerung + Rechtsklick:"
|
||||
L["Hold Shift + Drag:"] = "Halte Shift + Ziehen:"
|
||||
L["Purchase Bags"] = "Taschen kaufen"
|
||||
L["Reset Position"] = "Position zurücksetzen"
|
||||
L["Sort Bags"] = "Taschen sortieren"
|
||||
L["Temporary Move"] = "Temporäres Bewegen"
|
||||
L["Toggle Bags"] = "Taschen umschalten"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "Graue Gegenstände verkaufen"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "AFK" --Also used in datatexts and tooltip
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "DND" --Also used in datatexts and tooltip
|
||||
L["G"] = "G"
|
||||
L["Invalid Target"] = "Ungültiges Ziel"
|
||||
L["O"] = "O"
|
||||
L["P"] = "P"
|
||||
L["PL"] = "PL"
|
||||
L["R"] = "R"
|
||||
L["RL"] = "RL"
|
||||
L["RW"] = "RW"
|
||||
L["says"] = "sagen"
|
||||
L["whispers"] = "flüstern"
|
||||
L["yells"] = "schreien"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(Shift gedrückt) Speichernutzung"
|
||||
L["Avoidance Breakdown"] = "Vermeidung Aufgliederung"
|
||||
L["Character: "] = "Charakter: "
|
||||
L["Chest"] = "Brust"
|
||||
L["Combat"] = "Kampf"
|
||||
L["Combat Time"] = "Kampf Zeit"
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55fc|r" --Also used in Bags
|
||||
L["Deficit:"] = "Defizit:"
|
||||
L["DPS"] = "DPS"
|
||||
L["Earned:"] = "Verdient:"
|
||||
L["Friends List"] = "Freundesliste"
|
||||
L["Friends"] = "Freunde" --Also in Skins
|
||||
L["Gold"] = true;
|
||||
L["goldabbrev"] = "|cffffd700g|r" --Also used in gold datatext
|
||||
L["Hit"] = "Hit"
|
||||
L["Hold Shift + Right Click:"] = "Halte Umschalt + Rechts Klick:"
|
||||
L["Home Latency:"] = "Standort Latenz"
|
||||
L["HP"] = "HP"
|
||||
L["HPS"] = "HPS"
|
||||
L["lvl"] = "lvl"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "Milderung durch Stufe:"
|
||||
L["No Guild"] = "Keine Gilde"
|
||||
L["Profit:"] = "Gewinn:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "Daten zurücksetzen: Halte Shift + Rechtsklick"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "Gespeicherte Schlachtzüge"
|
||||
L["Server: "] = "Server: "
|
||||
L["Session:"] = "Sitzung:"
|
||||
L["silverabbrev"] = "|cffc7c7cfs|r" --Also used in Bags
|
||||
L["SP"] = "SP"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "Ausgegeben:"
|
||||
L["Stats For:"] = "Stats Für:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "Gesamt CPU:"
|
||||
L["Total Memory:"] = "Gesamte Speichernutzung:"
|
||||
L["Total: "] = "Gesamt: "
|
||||
L["Unhittable:"] = "Unhittable:"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s versucht die geschützte Funktion aufrufen '%s'."
|
||||
L["No locals to dump"] = "Keine Lokalisierung zum verwerfen"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s möchte seine Filter Einstellungen mit dir teilen. Möchtest du die Anfrage annehmen?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s versucht das Profil %s mit dir zu teilen. Möchtest du die Anfrage annehmen?"
|
||||
L["Data From: %s"] = "Datei von: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "Filter komplett heruntergeladen von %s, möchtest du die Änderungen nun vornehmen?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "Herr! Es ist ein Wunder! Der Download verschwand wie ein Furz im Wind! Versuche es nochmal!"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "Profil komplett heruntergeladen von %s, allerdings ist das Profil %s bereits vorhanden. Ändere den Namen oder das bereits existierende Profil wird überschrieben."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "Profil komplett heruntergeladen von %s, möchtest du das Profil %s nun laden?"
|
||||
L["Profile request sent. Waiting for response from player."] = "Profil Anfrage gesendet. Warte auf die Antwort des Spielers."
|
||||
L["Request was denied by user."] = "Die Anfrage wurde vom Benutzer abgelehnt."
|
||||
L["Your profile was successfully recieved by the player."] = "Dein Profil wurde erfolgreich von dem Spieler empfangen."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "Aurenleiste & Symbole"
|
||||
L["Auras Set"] = "Auren gesetzt"
|
||||
L["Auras"] = "Auren"
|
||||
L["Caster DPS"] = "Fernkampf DD"
|
||||
L["Chat Set"] = "Chat gesetzt"
|
||||
L["Chat"] = "Chat"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "Wähle ein Layout, welches du bei deinem ersten Setup verwenden möchtest."
|
||||
L["Classic"] = "Klassisch"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "Klicke auf die Taste unten um die Größe deiner Chatfenster, Einheitenfenster und die Umpositionierung deiner Aktionsleisten durchzuführen."
|
||||
L["Config Mode:"] = "Konfigurationsmodus:"
|
||||
L["CVars Set"] = "CVars gesetzt"
|
||||
L["CVars"] = "CVars"
|
||||
L["Dark"] = "Dunkel"
|
||||
L["Disable"] = "Deaktivieren"
|
||||
L["ElvUI Installation"] = "ElvUI Installation"
|
||||
L["Finished"] = "Beendet"
|
||||
L["Grid Size:"] = "Rastergröße:"
|
||||
L["Healer"] = "Heiler"
|
||||
L["High Resolution"] = "Hohe Auflösung"
|
||||
L["high"] = "hoch"
|
||||
L["Icons Only"] = "Nur Symbole" --Also used in Bags
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "Wenn du ein Symbol oder eine Aurenleiste nicht angezeigt haben möchtest, dann halte Shift gedrückt und klicke mit Rechtsklick auf das Symbol um es auszublenden."
|
||||
L["Importance: |cff07D400High|r"] = "Bedeutung: |cff07D400Hoch|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "Bedeutung: |cffD3CF00Mittel|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "Bedeutung: |cffD3CF00Niedrig|r"
|
||||
L["Installation Complete"] = "Installation komplett"
|
||||
L["Layout Set"] = "Layout gesetzt"
|
||||
L["Layout"] = "Layout"
|
||||
L["Lock"] = "Sperren"
|
||||
L["Low Resolution"] = "Niedrige Auflösung"
|
||||
L["low"] = "niedrig"
|
||||
L["Nudge"] = "Stoß"
|
||||
L["Physical DPS"] = "Physische DPS"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "Bitte klicke die Taste unten um den Installationsprozess abzuschließen und das Benutzerinterface neu zu laden."
|
||||
L["Please click the button below to setup your CVars."] = "Klicke 'Installiere CVars' um die CVars einzurichten."
|
||||
L["Please press the continue button to go onto the next step."] = "Bitte drücke die Weiter-Taste um zum nächsten Schritt zu gelangen."
|
||||
L["Resolution Style Set"] = "Auflösungsart gesetzt"
|
||||
L["Resolution"] = "Auflösung"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "Wähle für die ElvUI Einheitenfenster ob das Auren-System Aurenleisten und Symbole, oder nur Symbole anzeigt."
|
||||
L["Setup Chat"] = "Chateinstellungen"
|
||||
L["Setup CVars"] = "Installiere CVars"
|
||||
L["Skip Process"] = "Schritt überspringen"
|
||||
L["Sticky Frames"] = "Anheftende Fenster"
|
||||
L["Tank"] = "Tank"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "Die Chatfensterfunktionen sind die gleichen, wie die Chatfenster von Blizzard. Du kannst auf die Tabs rechtsklicken und sie z.B. neu zu positionieren, umzubenennen, etc. Bitte klicke den Button unten um das Chatfenster einzurichten."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "Das ElvUI-Konfigurationsmenü kannst du entweder mit /ec oder durch das Anklicken der 'C' Taste an der Minimap aufrufen. Drücke 'Schritt überspringen' um zum nächsten Schritt zu gelangen."
|
||||
L["Theme Set"] = "Thema gesetzt"
|
||||
L["Theme Setup"] = "Thema Setup"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "Dieser Installationsprozess wird dir helfen, die Funktionen von ElvUI für deine Benutzeroberfläche besser kennenzulernen."
|
||||
L["This is completely optional."] = "Das ist komplett Optional."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "Dieser Abschnitt der Installation stellt die Chat Fenster Namen, Positionen und Farben ein."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "Dieser Installationsprozess richtet alle wichtigen Cvars deines World of Warcrafts ein, um eine problemlose Nutzung zu ermöglichen."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "Diese Auflösung benötigt keine Änderungen um mit der Benutzeroberfläche zu funktionieren."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "Diese Auflösung benötigt Änderungen um mit der Benutzeroberfläche zu funktionieren."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "Dies wird das Layout der Einheitenfenster und Aktionsleisten ändern."
|
||||
L["Trade"] = "Handel"
|
||||
L["Welcome to ElvUI version %s!"] = "Willkommen bei ElvUI Version %s!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Du hast den Installationsprozess abgeschlossen. Solltest du technische Hilfe benötigen, besuche uns auf https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "Du kannst jederzeit in der Ingame-Konfiguration Schriften und Farben von jedem Element des Interfaces ändern."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "Du kannst nun auf Basis deiner Rolle im Kampf ein Layout wählen."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "Unter Umständen musst du, je nachdem wie niedrig deine Auflösung ist, diese Einstellungen ändern."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "Deine Aktuelle Auflösung ist %s, diese wird als eine %s Auflösung angesehen."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "Leisten" --Also used in UnitFrames
|
||||
L["Calendar"] = "Kalender"
|
||||
L["Can't Roll"] = "Es kann nicht gewürfelt werden."
|
||||
L["Disband Group"] = "Gruppe auflösen"
|
||||
L["Empty Slot"] = "Leerer Platz"
|
||||
L["Enable"] = "Eingeschaltet" --Doesn't fit a section since it's used a lot of places
|
||||
L["Experience"] = "Erfahrung"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "Faule Beute"
|
||||
L["Left Click:"] = "Linksklick:" --layout\layout.lua
|
||||
L["Raid Menu"] = "Schlachtzugsmenü"
|
||||
L["Remaining:"] = "Verbleibend:"
|
||||
L["Rested:"] = "Ausgeruht:"
|
||||
L["Right Click:"] = "Rechtsklick:" --layout\layout.lua
|
||||
L["Show BG Texts"] = "Zeige Schlachtfeldtexte" --layout\layout.lua
|
||||
L["Toggle Chat Frame"] = "Chatfenster an-/ausschalten" --layout\layout.lua
|
||||
L["Toggle Configuration"] = "Konfiguration umschalten" --layout\layout.lua
|
||||
L["XP:"] = "EP:"
|
||||
L["You don't have permission to mark targets."] = "Du hast keine Rechte um ein Ziel zu markieren."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "Arena Fenster" --Also used in UnitFrames
|
||||
L["Bag Mover (Grow Down)"] = "Taschen Anker (Nach unten wachsen)"
|
||||
L["Bag Mover (Grow Up)"] = "Taschen Anker (Nach oben wachsen)"
|
||||
L["Bag Mover"] = "Taschen Anker"
|
||||
L["Bags"] = "Taschen" --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = "Bank Anker (Nach unten wachsen)"
|
||||
L["Bank Mover (Grow Up)"] = "Bank Anker (Nach oben wachsen)"
|
||||
L["Bar "] = "Leiste " --Also in ActionBars
|
||||
L["BNet Frame"] = "BNet-Fenster"
|
||||
L["Boss Frames"] = "Boss Fenster" --Also used in UnitFrames
|
||||
L["Classbar"] = "Klassenleiste"
|
||||
L["Experience Bar"] = "Erfahrungsleiste"
|
||||
L["Focus Castbar"] = "Fokus Zauberbalken"
|
||||
L["Focus Frame"] = "Fokusfenster" --Also used in UnitFrames
|
||||
L["FocusTarget Frame"] = "Fokus-Ziel Fenster" --Also used in UnitFrames
|
||||
L["GM Ticket Frame"] = "GM-Ticket-Fenster"
|
||||
L["Left Chat"] = "Linker Chat"
|
||||
L["Loot / Alert Frames"] = "Beute-/Alarmfenster"
|
||||
L["Loot Frame"] = "Beute-Fenster"
|
||||
L["MA Frames"] = "MA-Fenster"
|
||||
L["Micro Bar"] = "Mikroleiste" --Also in ActionBars
|
||||
L["Minimap"] = "Minimap"
|
||||
L["MirrorTimer"] = "Spiegel Zeitgeber"
|
||||
L["MT Frames"] = "MT-Fenster"
|
||||
L["Party Frames"] = "Gruppenfenster" --Also used in UnitFrames
|
||||
L["Pet Bar"] = "Begleisterleiste" --Also in ActionBars
|
||||
L["Pet Castbar"] = "Begleiter Zauberleiste"
|
||||
L["Pet Frame"] = "Begleiterfenster" --Also used in UnitFrames
|
||||
L["PetTarget Frame"] = "Begleiter-Ziel Fenster" --Also used in UnitFrames
|
||||
L["Player Buffs"] = "Spieler Buffs"
|
||||
L["Player Castbar"] = "Spieler Zauberbalken"
|
||||
L["Player Debuffs"] = "Spieler Debuffs"
|
||||
L["Player Frame"] = "Spielerfenster" --Also used in UnitFrames
|
||||
L["Player Powerbar"] = "Spieler Kraftleiste"
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "Schlachtzugsfenster" --Also used in UnitFrames
|
||||
L["Raid Pet Frames"] = "Schlachtzugspets-Fenster"
|
||||
L["Raid-40 Frames"] = "40er Schlachtzugsfenster" --Also used in UnitFrames
|
||||
L["Reputation Bar"] = "Rufleiste"
|
||||
L["Right Chat"] = "Rechter Chat"
|
||||
L["Stance Bar"] = "Haltungsleiste" --Also in ActionBars
|
||||
L["Target Castbar"] = "Ziel Zauberbalken"
|
||||
L["Target Frame"] = "Zielfenster" --Also used in UnitFrames
|
||||
L["Target Powerbar"] = "Ziel Kraftleiste"
|
||||
L["TargetTarget Frame"] = "Ziel des Ziels Fenster" --Also used in UnitFrames
|
||||
L["TargetTargetTarget Frame"] = "Ziel des Ziels des Ziels Fenster"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "Tooltip"
|
||||
L["Vehicle Seat Frame"] = "Fahrzeugfenster"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = true;
|
||||
L["In Progress"] = "In Bearbeitung"
|
||||
L["List of installations in queue:"] = "Liste von Installationen in Warteschlange:"
|
||||
L["Pending"] = "Ausstehend"
|
||||
L["Steps"] = "Schritte"
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00gebunden zu |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "Es liegt ein Konflikt bei den Ankerpunkten des Rahmens %s vor. Bitte ändere entweder den Ankerpunkt des Stärkungs- oder Schwächungszaubers, damit diese nicht länger mit einander verbunden sind. Verbinde die Schwächungszauber mit dem Hauptrahmen, damit dieses Problem behoben wird."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "Alle Tastaturbelegungen gelöscht für |cff00ff00%s|r."
|
||||
L["Already Running.. Bailing Out!"] = "Bereits ausgeführt.. Warte ab!"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "Schlachtfeld-Infotexte sind kurzzeitig versteckt, um sie wieder anzuzeigen tippe /bgstats oder rechtsklicke auf das 'C' Symbol nahe der Minimap."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "Schlachtfeld-Infotexte werden wieder angezeigt, solange du dich in einem Schlachtfeld befindest."
|
||||
L["Binds Discarded"] = "Tastaturbelegungen verworfen"
|
||||
L["Binds Saved"] = "Tastaturbelegungen gespeichert"
|
||||
L["Confused.. Try Again!"] = "Verwirrt.. Versuche es erneut!"
|
||||
L["No gray items to delete."] = "Es sind keine grauen Gegenstände zum Löschen vorhanden."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "Der Zauber '%s' wurde zur schwarzen Liste der Einheitenfenster hinzugefügt."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = "Diese Einstellungen haben einen Konflikt mit einem Ankerpunkt, wo '%s' an sich selbst angehaftet sein soll. Bitte kontrolliere deine Ankerpunkte. Einstellung '%s' angehaftet an '%s'."
|
||||
L["Vendored gray items for:"] = "Graue Gegenstände verkauft für:"
|
||||
L["You don't have enough money to repair."] = "Du hast nicht genügend Gold für die Reparatur."
|
||||
L["You must be at a vendor."] = "Du musst bei einem Händler sein."
|
||||
L["Your items have been repaired for: "] = "Deine Gegenstände wurden repariert für: "
|
||||
L["Your items have been repaired using guild bank funds for: "] = "Deine Gegenstände wurden repariert. Die Gildenbank kostete das: "
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000Lua Fehler erhalten. Du kannst die Fehlermeldung ansehen, wenn du den Kampf verlässt."
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "Eine Einstellung, die du geändert hast, betrifft nur einen Charakter. Diese Einstellung, die du verändert hast, wird die Benutzerprofile unbeeinflusst lassen. Eine Änderung dieser Einstellung erfordert, dass du dein Interface neu laden musst."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = "Wenn du aktzeptierst wird die Filter Priorität für alle Einheitenfenster auf Standard zurückgesetzt. Bist du sicher?"
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = "Bist du sicher, dass du diese Schrifart auf alle ElvUI Elemente anwenden möchtest?"
|
||||
L["Are you sure you want to delete all your gray items?"] = "Bist du sicher, dass du alle grauen Gegenstände löschen willst?"
|
||||
L["Are you sure you want to disband the group?"] = "Bist du dir sicher, dass du die Gruppe auflösen willst?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "Bist du dir sicher dass du alle Einstellungen dieses Profils zurücksetzen willst?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "Bist du dir sicher, dass du jeden Beweger an die Standard-Position zurücksetzen möchtest?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "Aufgrund der großen Verwirrung, die durch das neue Auren-System verursacht wurde, habe ich einen neuen Schritt zum Installationsprozess hinzugefügt. Dieser ist optional. Wenn du deine Auren so eingestellt lassen willst, wie sie sind, gehe einfach zum letzten Schritt und klicke auf fertig um nicht erneut aufgefordert zu werden. Wirst du, aus welchen Grund auch immer, öfter aufgefordert, starte bitte dein Spiel neu"
|
||||
L["Can't buy anymore slots!"] = "Kann keine Slots mehr kaufen"
|
||||
L["Disable Warning"] = "Deaktiviere Warnung"
|
||||
L["Discard"] = "Verwerfen"
|
||||
L["Do you enjoy the new ElvUI?"] = "Gefällt dir das neue ElvUI?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "Schwörst du, dass du keinen Beitrag im Supportforum posten wirst, ohne vorher alle anderen Addons/Module zu deaktivieren?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI ist seit fünf oder mehr Revisionen nicht aktuell. Du kannst die neuste Version bei https://github.com/ElvUI-WotLK/ElvUI/ herunterladen."
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI ist nicht aktuell. Du kannst die neuste Version bei https://github.com/ElvUI-WotLK/ElvUI/ herunterladen."
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI muss eine Datenbank Optimierung durchführen. Bitte warte eine Moment."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "Bewege deine Maus über einen Aktionsbutton oder dein Zauberbuch um ihn mit einem Hotkey zu belegen. Drücke Escape oder rechte Maustaste um die aktuelle Tastenbelegung des Buttons zu löschen."
|
||||
L["I Swear"] = "Ich schwöre"
|
||||
L["No, Revert Changes!"] = "Nein, Änderungen verwerfen!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "Oh Gott, du hast ElvUI und Tukui zur gleichen Zeit aktiviert. Wähle ein Addon um es zu deaktivieren."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "Eine oder mehrere Einstellungen, die du vorgenommen hast, benötigen ein Neuladen des Benutzerinterfaces um in Effekt zu treten."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "Eine oder mehrere Änderungen, die du getroffen hast, betrifft alle Charaktere die dieses Addon benutzen. Du musst das Benutzerinterface neu laden um die Änderungen, die du durchgeführt hast, zu sehen."
|
||||
L["Save"] = "Speichern"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "Das Profil, dass du versuchst zu importieren existiert bereits. Wähle einen neuen Namen oder aktzeptiere dass das vorhandene Profile überschrieben wird."
|
||||
L["Type /hellokitty to revert to old settings."] = "Tippe /hellokitty um die alten Einstellungen zu verwenden."
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "Wenn du das Heiler Layout benutzt ist es sehr empfohlen das Addon Clique zu downloaden wenn du die Klick-zum-Heilen Funktion haben willst."
|
||||
L["Yes, Keep Changes!"] = "Ja, Änderungen behalten!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "Du hast die Dünnen Rahmen Einstellungen geändert. Du musst die Installation komplett abschließen um grafische Fehler zu vermeiden."
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "Du hast die Skalierung des benutzerinterfaces geändert, während du die automatische Skalierung in ElvUI aktiv hast. Drücke Annehmen um die automatische Skalierung zu deaktivieren."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "Du hast Einstellungen importiert die wahrscheinlich ein Neuladen des UI erfordern. Jetzt neu laden?"
|
||||
L["You must purchase a bank slot first!"] = "Du musst erst ein Bankfach kaufen!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "Zähler"
|
||||
L["Item Level:"] = "Itemlevel"
|
||||
L["Talent Specialization:"] = "Talentspezialisierung"
|
||||
L["Targeted By:"] = "Ziel von:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "Ein Feature für Schlachtzugsmarkierung ist verfügbar, wenn du Escape drückst und Tastaturbelegung wählst, scrolle anschließend bis unter die Kategorie ElvUI und wähle eine Tastenbelegung für die Schlachtzugsmarkierung."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "ElvUI hat ein Feature für Dualspezialisierungen, welches dich abhängig von deiner momentanen Spezialisierung verschiedene Profile laden lässt. Dieses Feature kannst du im Abschnitt Profil aktivieren."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Für technische Hilfe besuche uns unter https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "Wenn du ausversehen das Chatfenster entfernen solltest, kannst du ganz einfach in die Ingame-Konfiguration gehen und den Installationsprozess erneut aufrufen. Drücke Installieren und gehe zu den Chateinstellungen und setze diese zurück."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "Wenn du Probleme mit ElvUI hast, deaktiviere alle Addons außer ElvUI. Denke auch daran, dass ElvUI die komplette Benutzeroberfläche ersetzt, d.h. du kannst kein Addon verwenden, welches die gleichen Funktionen wie ElvUI nutzt."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "Du kannst, während du ein Ziel hast, das Fokusfenster durch die Eingabe von /fokus setzen. Es wird empfohlen ein Makro dafür zu nutzen."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "Um Fähigkeiten auf der Aktionsleiste zu verschieben nutze Shift und bewege zeitgleich die Maus. Du kannst die Modifier-Taste im Aktionsleistenmenü umstellen."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "Um einzustellen welcher Kanal im welchem Chatfenster angezeigt werden soll, klicke rechts auf das Chattab und gehe auf Einstellungen."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "Du kannst die Funktionen Chat Kopieren und Chatmenü aufrufen, wenn du die Maus in die obere rechte Ecke des Chatfensters bewegst und links-/rechtsklickst."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "Du kannst die durchschnittliche Gegenstandsstufe von jemanden sehen, wenn du bei gedrückter Shift-Taste mit der Maus über ihn fährst. Die Gegenstandsstufe wird dann im Tooltip angezeigt."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "Du kannst deine Tastaturbelegung schnell ändern, wenn du /kb eintippst."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "Du kannst die Mikroleiste durch mittleren Mausklick auf der Minimap aufrufen oder auch die tatsächliche Mikroleiste in den Aktionsleisten Optionen aktivieren."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "Du kannst durch benutzen von /resetui alle Ankerpunkte zurücksetzen. Du kannst das Kommando auch benutzen um spezielle Anker zurückzusetzen, /resetui <Anker Name>.\nBeispiel: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = "Tot"
|
||||
L["Ghost"] = "Geist"
|
||||
L["Offline"] = "Offline"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- Korean localization file for koKR.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "koKR")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "%s 애드온의 기능이 ElvUI의 %s 모듈과 상충됩니다. 그 애드온을 쓰지 않거나 ElvUI의 기능을 사용해제하세요."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "%sElvUI|r 버전 %s%s|r 을 사용해 주셔서 감사합니다. /ec 를 입력하면 설정창을 열 수 있습니다. 궁금한 점이나 기술지원은 https://github.com/ElvUI-WotLK/ElvUI 에서 해결하세요"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = " "
|
||||
L["Key"] = "단축키"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "W▼"
|
||||
L["KEY_MOUSEWHEELUP"] = "W▲"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "P▼"
|
||||
L["KEY_PAGEUP"] = "P▲"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "Spc"
|
||||
L["No bindings set."] = "설정한 단축키가 없습니다."
|
||||
L["Remove Bar %d Action Page"] = "Blizzard %d번 행동단축바 숨기기"
|
||||
L["Trigger"] = "묶음을 펼치고 각 주문에 지정하세요."
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "은행"
|
||||
L["Hold Control + Right Click:"] = "Shift 우클릭:"
|
||||
L["Hold Shift + Drag:"] = "Shift 드래그:"
|
||||
L["Purchase Bags"] = "가방 슬롯 구입"
|
||||
L["Reset Position"] = "위치 초기화"
|
||||
L["Sort Bags"] = "가방 정렬"
|
||||
L["Temporary Move"] = "임시 이동"
|
||||
L["Toggle Bags"] = "가방슬롯 보기"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "잡동사니 자동판매"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "자리비움"
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "다른 용무중"
|
||||
L["G"] = "길드"
|
||||
L["Invalid Target"] = "잘못된 대상"
|
||||
L["O"] = "관리자"
|
||||
L["P"] = "파티"
|
||||
L["PL"] = "파장"
|
||||
L["R"] = "공대"
|
||||
L["RL"] = "공장"
|
||||
L["RW"] = "경보"
|
||||
L["says"] = "일반"
|
||||
L["whispers"] = "귓"
|
||||
L["yells"] = "외침"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "Shift: 메모리 사용량"
|
||||
L["Avoidance Breakdown"] = "방어율 목록"
|
||||
L["Character: "] = "캐릭터:"
|
||||
L["Chest"] = "가슴"
|
||||
L["Combat"] = "전투"
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|TInterface\\MoneyFrame\\UI-MoneyIcons:0:0:1:0:64:16:33:48:1:16|t" --"|cffeda55f●|r"
|
||||
L["Deficit:"] = "손해:"
|
||||
L["DPS"] = "DPS"
|
||||
L["Earned:"] = "수입:"
|
||||
L["Friends List"] = "친구 목록"
|
||||
L["Friends"] = "친구"
|
||||
L["Gold"] = true;
|
||||
L["goldabbrev"] = "|TInterface\\MoneyFrame\\UI-MoneyIcons:0:0:1:0:64:16:1:16:1:16|t" --"|cffffd700●|r"
|
||||
L["Hit"] = "적중도"
|
||||
L["Hold Shift + Right Click:"] = true;
|
||||
L["Home Latency:"] = "지연 시간:"
|
||||
L["HP"] = "주문력"
|
||||
L["HPS"] = "HPS"
|
||||
L["lvl"] = "레벨"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "레벨별 데미지 경감률"
|
||||
L["No Guild"] = "길드 없음"
|
||||
L["Profit:"] = "이익:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "기록 리셋: Shift + 우클릭"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "귀속된 던전"
|
||||
L["Server: "] = "서버:"
|
||||
L["Session:"] = "현재 접속:"
|
||||
L["silverabbrev"] = "|TInterface\\MoneyFrame\\UI-MoneyIcons:0:0:1:0:64:16:17:32:1:16|t" --"|cffc7c7cf●|r"
|
||||
L["SP"] = "주문력"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "지출:"
|
||||
L["Stats For:"] = "점수:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "전체 CPU 사용량:"
|
||||
L["Total Memory:"] = "전체 메모리:"
|
||||
L["Total: "] = "합계:"
|
||||
L["Unhittable:"] = "100% 방어행동까지"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s 기능이 사용할 수 없는 %s 함수를 사용하려 합니다."
|
||||
L["No locals to dump"] = true; --Currently not used
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s 유저가 필터설정을 전송하려 합니다. 받으시겠습니까?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s 유저가 ElvUI 설정을 전송하려 합니다. 받으시겠습니까?"
|
||||
L["Data From: %s"] = "%s 유저에게서 데이터 받는중..."
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "%s 유저에게서 필터 설정 다운로드가 완료되었습니다. 변경사항을 적용할까요?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "데이터를 받는 중 혼선이 생겼습니다. 다시 시도해주세요."
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "%s 유저에게서 ElvUI 설정 다운로드가 완료되었습니다. 하지만 건네받은 프로필 이름이 이미 존재합니다. 프로필이름을 바꾸지 않으면 기존의 것에 덮어씌웁니다."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "%s 유저에게서 ElvUI 설정 다운로드가 완료되었습니다. 건네받은 설정을 지금 불러올까요?"
|
||||
L["Profile request sent. Waiting for response from player."] = "상대에게서 전송여부를 확인받고 있습니다."
|
||||
L["Request was denied by user."] = "상대방이 전송을 거절했습니다."
|
||||
L["Your profile was successfully recieved by the player."] = "상대에게 데이터를 성공적으로 전송했습니다."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "바 & 아이콘 표시"
|
||||
L["Auras Set"] = "오라설정 적용"
|
||||
L["Auras"] = "오라 설정"
|
||||
L["Caster DPS"] = "원거리 딜러"
|
||||
L["Chat Set"] = "대화창 설정"
|
||||
L["Chat"] = "대화창"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "UI의 전체적인 분위기를 선택하세요."
|
||||
L["Classic"] = "클래식"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "원하는 해상도로 설정을 강제 적용하고자 한다면 아래에서 원하는 해상도를 선택하세요."
|
||||
L["Config Mode:"] = "표시할 프레임 계열:"
|
||||
L["CVars Set"] = "CVars 설정"
|
||||
L["CVars"] = "게임 인터페이스 설정(CVars)"
|
||||
L["Dark"] = "어두운 느낌"
|
||||
L["Disable"] = "비활성화"
|
||||
L["ElvUI Installation"] = "ElvUI 설치"
|
||||
L["Finished"] = "마침"
|
||||
L["Grid Size:"] = "격자 크기 :"
|
||||
L["Healer"] = "힐러"
|
||||
L["High Resolution"] = "고해상도 세팅"
|
||||
L["high"] = "고"
|
||||
L["Icons Only"] = "아이콘만 표시"
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "표시하고 싶지 않은 버프/디버프가 보이면 아이콘을 Shift 우클릭하세요. 차단 목록에 등록되어 보이지 않게 됩니다."
|
||||
L["Importance: |cff07D400High|r"] = "중요도: |cff07D400높음|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "중요도: |cffD3CF00보통|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "중요도 : |cffFF0000낮음|r"
|
||||
L["Installation Complete"] = "설치 완료"
|
||||
L["Layout Set"] = "레이아웃 설정"
|
||||
L["Layout"] = "레이아웃"
|
||||
L["Lock"] = "잠금"
|
||||
L["Low Resolution"] = "저해상도 세팅"
|
||||
L["low"] = "저"
|
||||
L["Nudge"] = "미세조정"
|
||||
L["Physical DPS"] = "근접 딜러"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "아래 버튼을 누르면 설치를 마무리하고 UI를 재시작합니다."
|
||||
L["Please click the button below to setup your CVars."] = "ElvUI의 게임 인터페이스 설정을 적용하려면 아래 버튼을 클릭하세요."
|
||||
L["Please press the continue button to go onto the next step."] = "|cff2eb7e4[계속]|r 버튼으로 설치를 진행하세요."
|
||||
L["Resolution Style Set"] = "해상도 스타일 설정"
|
||||
L["Resolution"] = "해상도"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "ElvUI 유닛프레임에서 표시할 오라(버프,디버프)의 형태를 선택하세요."
|
||||
L["Setup Chat"] = "대화창 설치"
|
||||
L["Setup CVars"] = "인터페이스 설정 적용"
|
||||
L["Skip Process"] = "건너뛰기"
|
||||
L["Sticky Frames"] = "자석"
|
||||
L["Tank"] = "탱커"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "보편적인 설정을 적용할 뿐이므로, 마음대로 채널표시나 색상을 변경할 수 있습니다.|n아래 버튼을 클릭하면 채팅창 설정을 적용합니다."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "게임 내 설정창은 채팅창에 /ec를 입력하시거나 미니맵 옆의 C버튼을 클릭하면 열립니다. 그냥 사용하고자 한다면 아래의 |cff2eb7e4[건너뛰기]|r 버튼을 누르세요."
|
||||
L["Theme Set"] = "테마 적용"
|
||||
L["Theme Setup"] = "테마 설정"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "이 설치과정을 통해 ElvUI를 좀 더 자신에게 맞게 설정하고|n몇가지 기능에 대해 알 수 있습니다."
|
||||
L["This is completely optional."] = "이것은 선택 사항입니다."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "채팅창 설정을 변경합니다. 간단한 채널설정, 색상설정 등이 포함되어 있습니다.|n자신만의 채널 설정, 색상 등을 유지하고 싶으면 설치하지 마세요."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "WoW의 기본 인터페이스 설정을 ElvUI에 적합하게 변경합니다. 애드온 사용에 있어 유용하니 적용할 것을 추천합니다."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "현재 해상도에 알맞게 UI가 배치될 것이니 설정을 변경할 필요는 없습니다."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "해상도에 알맞는 UI 배치를 적용하려면 몇가지 설정을 변경할 필요가 있습니다."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "역할에 따라서 유닛프레임과 행동단축바의 레이아웃이 알맞게 바뀝니다."
|
||||
L["Trade"] = "거래"
|
||||
L["Welcome to ElvUI version %s!"] = "ElvUI 버전 %s에 오신 것을 환영합니다!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "설치 과정이 끝났습니다.|n궁금한 점 해결이나 기술지원이 필요하면 |cff2eb7e4https://github.com/ElvUI-WotLK/ElvUI|r 를 방문하세요."
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "ElvUI에서 표시하는 폰트나 색상은 설정에서 언제든지 바꿀 수 있습니다."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "게임 안에서 주로 플레이하는 전문화 역할을 선택하세요."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "당신의 해상도가 얼마나 낮은지에 따라 설정을 더 조절해야할 수도 있습니다."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "현재 사용중인 해상도는 |cff2eb7e4%s|r 이며, |cff2eb7e4%s해상도|r 입니다."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% 정도 |cff%02x%02x%02x%s|r보다 많음]"
|
||||
L["Bars"] = "바"
|
||||
L["Calendar"] = "달력"
|
||||
L["Can't Roll"] = "주사위를 굴릴 수 없습니다."
|
||||
L["Disband Group"] = "그룹 해산"
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = "사용"
|
||||
L["Experience"] = "경험치"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "낚시 전리품"
|
||||
L["Left Click:"] = "왼 클릭 :"
|
||||
L["Raid Menu"] = "공대 도구"
|
||||
L["Remaining:"] = "다음 레벨까지: "
|
||||
L["Rested:"] = "휴식 경험치:"
|
||||
L["Right Click:"] = "우클릭:"
|
||||
L["Show BG Texts"] = "전장전용 정보문자 표시"
|
||||
L["Toggle Chat Frame"] = "패널 표시 전환"
|
||||
L["Toggle Configuration"] = "ElvUI 설정창 열기"
|
||||
L["XP:"] = "경험치:"
|
||||
L["You don't have permission to mark targets."] = "레이드 아이콘을 지정할 권한이 없습니다."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "투기장 프레임"
|
||||
L["Bag Mover (Grow Down)"] = true;
|
||||
L["Bag Mover (Grow Up)"] = true;
|
||||
L["Bag Mover"] = true;
|
||||
L["Bags"] = "가방"
|
||||
L["Bank Mover (Grow Down)"] = true;
|
||||
L["Bank Mover (Grow Up)"] = true;
|
||||
L["Bar "] = "바 "
|
||||
L["BNet Frame"] = "배틀넷 알림"
|
||||
L["Boss Frames"] = "보스 프레임"
|
||||
L["Classbar"] = "직업바"
|
||||
L["Experience Bar"] = "경험치 바"
|
||||
L["Focus Castbar"] = "주시대상 시전바"
|
||||
L["Focus Frame"] = "주시대상 프레임"
|
||||
L["FocusTarget Frame"] = "주시대상의 대상 프레임"
|
||||
L["GM Ticket Frame"] = "GM요청 번호표"
|
||||
L["Left Chat"] = "좌측 패널"
|
||||
L["Loot / Alert Frames"] = "획득/알림 창"
|
||||
L["Loot Frame"] = "전리품 프레임"
|
||||
L["MA Frames"] = "지원공격 전담 프레임"
|
||||
L["Micro Bar"] = "메뉴모음 바"
|
||||
L["Minimap"] = "미니맵"
|
||||
L["MirrorTimer"] = true;
|
||||
L["MT Frames"] = "방어전담 프레임"
|
||||
L["Party Frames"] = "파티 프레임"
|
||||
L["Pet Bar"] = "소환수 바"
|
||||
L["Pet Castbar"] = "소환수 시전바"
|
||||
L["Pet Frame"] = "소환수 프레임"
|
||||
L["PetTarget Frame"] = "소환수 대상 프레임"
|
||||
L["Player Buffs"] = "플레이어 버프"
|
||||
L["Player Castbar"] = "플레이어 시전바"
|
||||
L["Player Debuffs"] = "플레이어 디버프"
|
||||
L["Player Frame"] = "플레이어 프레임"
|
||||
L["Player Powerbar"] = true;
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "레이드 프레임"
|
||||
L["Raid Pet Frames"] = "레이드 소환수 프레임"
|
||||
L["Raid-40 Frames"] = "레이드 프레임(40인)"
|
||||
L["Reputation Bar"] = "평판 바"
|
||||
L["Right Chat"] = "우측 패널"
|
||||
L["Stance Bar"] = "태세 바"
|
||||
L["Target Castbar"] = "대상 시전바"
|
||||
L["Target Frame"] = "대상 프레임"
|
||||
L["Target Powerbar"] = true;
|
||||
L["TargetTarget Frame"] = "대상의대상 프레임"
|
||||
L["TargetTargetTarget Frame"] = "대상의대상의대상 프레임"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "툴팁"
|
||||
L["Vehicle Seat Frame"] = "차량 좌석 프레임"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = true;
|
||||
L["In Progress"] = true;
|
||||
L["List of installations in queue:"] = true;
|
||||
L["Pending"] = true;
|
||||
L["Steps"] = true;
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " 키로 다음의 행동을 실행합니다: |cff2eb7e4"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "%s 의 위치 기준 프레임이 상충되고 있습니다. 서로가 서로의 위치를 참조하지 않게 버프나 디버프 중 하나의 위치를 바꿔주세요. 수정되기 전까지 강제로 유닛프레임이 기준으로 됩니다. "
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "|cff00ff00%s|r 버튼에 설정된 모든 단축키 설정이 해제되었습니다."
|
||||
L["Already Running.. Bailing Out!"] = "이미 실행중입니다. 잠시만 기다려 주세요."
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "전장전용 정보문자를 일시적으로 표시하지 않습니다. 다시 보고 싶으면 |cffceff00/bgstats|r 나 미니맵에 있는 C 버튼을 우클릭하세요."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "전장전용 정보문자를 다시 표시합니다."
|
||||
L["Binds Discarded"] = "방금 한 단축키 지정 작업을 저장하지 않고 취소했습니다."
|
||||
L["Binds Saved"] = "단축키가 저장되었습니다."
|
||||
L["Confused.. Try Again!"] = "작업에 혼선이 있었습니다. 다시 시도해 주세요."
|
||||
L["No gray items to delete."] = "잡동사니가 없습니다."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "%s 주문이 차단 목록에 등록되었습니다."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = true;
|
||||
L["Vendored gray items for:"] = "모든 잡동사니를 팔았습니다:"
|
||||
L["You don't have enough money to repair."] = "수리 비용이 부족합니다."
|
||||
L["You must be at a vendor."] = "상인을 만나야 가능합니다."
|
||||
L["Your items have been repaired for: "] = "자동으로 수리하고 비용을 지불했습니다:"
|
||||
L["Your items have been repaired using guild bank funds for: "] = "길드자금으로 수리하고 비용을 지불했습니다:"
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "Lua 에러가 발생하였습니다. 전투가 끝난 후에 내역을 표시하겠습니다."
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "이 설정은 캐릭터별로 따로 저장되므로|n프로필에 영향을 주지도, 받지도 않습니다.|n|n설정 적용을 위해 리로드 하시겠습니까?"
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = true;
|
||||
L["Are you sure you want to delete all your gray items?"] = "모든 잡동사니를 버리겠습니까?"
|
||||
L["Are you sure you want to disband the group?"] = "현재 그룹을 해산하시겠습니까?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "현재 사용중인 프로필을 초기화 하시겠습니까?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "모든 프레임을 기본 위치로 초기화 하시겠습니까?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "새로운 오라시스템을 혼란스러워 하는 분들이 많아 설치과정에 관련 페이지를 추가했습니다. 해도 되고 안해도 됩니다. 이미 스스로 오라시스템을 구축했으면 그냥 설치를 마지막까지 넘겨 종료하세요."
|
||||
L["Can't buy anymore slots!"] = "더 이상 가방 칸을 늘릴 수 없습니다."
|
||||
L["Disable Warning"] = "비활성화 경고"
|
||||
L["Discard"] = "작업 취소"
|
||||
L["Do you enjoy the new ElvUI?"] = "만우절 기능이었습니다! 이대로 쓰실래요?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "두 애드온을 병행하여 생기는 문제를 스스로 감수하며 관련 질문글을 올리지 마세요."
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "현재 사용하는 ElvUI가 5버전 이상 뒤쳐진 버전입니다. https://github.com/ElvUI-WotLK/ElvUI/ 에서 새 버전을 다운로드 받으세요."
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI가 오래된 버전입니다. https://github.com/ElvUI-WotLK/ElvUI/ 에서 새 버전을 다운로드 받으세요."
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI의 데이터베이스를 조정할 필요가 있습니다. 잠시 기다려주세요."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "행동단축바나 주문책의 스킬에 마우스오버 후 키를 누르면 단축키로 지정합니다. 단축키를 지정한 곳을 우클릭 하거나 ESC를 누르면 해제합니다."
|
||||
L["I Swear"] = "알겠습니다."
|
||||
L["No, Revert Changes!"] = "예전으로 돌려주세요"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "ElvUI 와 TukUI 를 동시에 사용하려 하고 있습니다. 하나만 선택해 주세요."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "변경 사항을 적용하려면 애드온을 리로드 해야합니다."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "이 설정은 모든 캐릭터에게 동일하게 적용됩니다.|n|n설정 적용을 위해 리로드 하시겠습니까?"
|
||||
L["Save"] = "저장"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = true;
|
||||
L["Type /hellokitty to revert to old settings."] = "/hellokitty 를 입력해서 예전 세팅으로 돌릴 수 있습니다."
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "힐러 레이아웃을 사용할 거라면 Clique 애드온을 같이 써 클릭캐스팅 기능을 이용할 것을 강력히 추천합니다."
|
||||
L["Yes, Keep Changes!"] = "네! 이대로 할래요!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "Thin Border Theme 선택을 바꾸었습니다. 설치과정을 끝까지 밟아 그래픽 관련 버그를 미연에 방지하는 걸 추천합니다."
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "UI 배율이 변경되었지만 ElvUI의 UI크기 자동조절 기능이 켜져있습니다. UI크기 자동조절 기능을 끄고 싶다면 '수락'을 누르세요."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = true;
|
||||
L["You must purchase a bank slot first!"] = "우선 은행가방 칸을 구입해야됩니다!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "갯수"
|
||||
L["Item Level:"] = "템렙:"
|
||||
L["Talent Specialization:"] = "특성:"
|
||||
L["Targeted By:"] = "선택됨:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "단축키 설정의 맨 아래에 있는 ElvUI 부분에서 |cff2eb7e4[Raid Marker]|r 기능을 사용하면 대상에게 징표를 간단히 찍을 수 있습니다."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "각 전문화별로 ElvUI 설정을 따로 지정할 수 있습니다. 설정의 프로필 항목에 |cff2eb7e4[이중 프로필 사용]|r 기능을 확인하세요."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "궁금한 사항이나 기술지원은 |cff2eb7e4https://github.com/ElvUI-WotLK/ElvUI|r에서 해결하세요."
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "ElvUI 에서 지원하는 대부분의 기능은 |cff2eb7e4/ec|r 에서 조정이 가능합니다. 하고 싶은 조절 기능이 없다면 직접 lua수정으로 고쳐야 합니다."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "ElvUI에서 지원하는 기능과 겹치는 다른 애드온을 쓰고 싶으면 ElvUI 설정에서 해당 기능을 사용 체크해제 해야합니다. (예: Bartender, Dominos)"
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "ElvUI의 특정 기능만 따로 독립애드온으로 분리하는 것은 불가능합니다."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "기본적으로 단축바에서 스킬을 뺄려면 |cff2eb7e4Shift 키를 누른 상태에서 드래그|r해야 합니다. 수정키는 /ec -> 행동단축바 항목에서 바꿀 수 있습니다."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "채팅창에 표시할 채널은 채팅탭을 우클릭하면 뜨는 메뉴의 설정에서 변경할 수 있습니다."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "채팅창 우측상단의 문서 아이콘을 클릭하면 대화 내역을 복사할 수 있습니다. 우클릭하면 채팅에 관련된 메뉴가 나옵니다."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "/ec -> 툴팁 항목에서 |cff2eb7e4[특성/아이템레벨 표시]|r 기능을 체크하고 Shift를 누른 상태로 마우스를 대면 그 유저의 템렙과 특성을 툴팁에 표시합니다."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "|cff2eb7e4/kb|r 를 입력하면 간편하게 단축키를 설정할 수 있는 기능이 실행됩니다."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "미니맵을 휠버튼클릭 하거나 행동단축바 설정으로 각종 메뉴버튼을 볼 수 있습니다."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "|cff2eb7e4/resetui|r 입력으로 움직였던 모든 프레임의 위치를 초기화할 수 있습니다. |cff2eb7e4 /resetui 프레임이름|r 으로 특정 프레임만 초기화도 가능합니다."
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = true;
|
||||
L["Ghost"] = "유령"
|
||||
L["Offline"] = "오프라인"
|
||||
@@ -0,0 +1,11 @@
|
||||
<UI xmlns="http://www.blizzard.com/wow/UI/">
|
||||
<Script file="English_UI.lua"/>
|
||||
<Script file="French_UI.lua"/>
|
||||
<Script file="Russian_UI.lua"/>
|
||||
<Script file="German_UI.lua"/>
|
||||
<Script file="Taiwanese_UI.lua"/>
|
||||
<Script file="Spanish_UI.lua"/>
|
||||
<Script file="Korean_UI.lua"/>
|
||||
<Script file="Chinese_UI.lua"/>
|
||||
<Script file="Portuguese_UI.lua"/>
|
||||
</UI>
|
||||
@@ -0,0 +1,346 @@
|
||||
-- Portuguese localization file for ptBR.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "ptBR")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "The addon %s is not compatible with ElvUI's %s module. Please select either the addon or the ElvUI module to disable."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Bem vindo à versão %s%s|r da %sElvUI|r, escreva /ec para acessar o menu de configuração em jogo. Se precisar de suporte técnico visite-nos no site https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "Ligações"
|
||||
L["Key"] = "Tecla"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "Sem atalhos definidos"
|
||||
L["Remove Bar %d Action Page"] = "Remover paginação de ação da barra %d."
|
||||
L["Trigger"] = "Gatilho"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = true;
|
||||
L["Hold Control + Right Click:"] = "Segurar Control + Clique Direito:"
|
||||
L["Hold Shift + Drag:"] = "Segurar Shift + Arrastar:"
|
||||
L["Purchase Bags"] = true;
|
||||
L["Reset Position"] = "Redefinir Posição"
|
||||
L["Sort Bags"] = "Organizar Bolsas"
|
||||
L["Temporary Move"] = "Mover Temporariamente"
|
||||
L["Toggle Bags"] = "Mostrar/Ocultar Bolsas"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "Vender Itens Cinzentos"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "LDT"
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "NP"
|
||||
L["G"] = "G"
|
||||
L["Invalid Target"] = "Alvo inválido"
|
||||
L["O"] = "O"
|
||||
L["P"] = "P"
|
||||
L["PL"] = "PL"
|
||||
L["R"] = "R"
|
||||
L["RL"] = "RL"
|
||||
L["RW"] = "AR"
|
||||
L["says"] = "diz"
|
||||
L["whispers"] = "sussurra"
|
||||
L["yells"] = "grita"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(Segurar Shift) Memória em Uso"
|
||||
L["Avoidance Breakdown"] = "Separação de Anulação"
|
||||
L["Character: "] = "Personagem: "
|
||||
L["Chest"] = "Torso"
|
||||
L["Combat"] = true;
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55fc|r"
|
||||
L["Deficit:"] = "Défice:"
|
||||
L["DPS"] = "DPS"
|
||||
L["Earned:"] = "Ganho:"
|
||||
L["Friends List"] = "Lista de Amigos"
|
||||
L["Friends"] = "Amigos"
|
||||
L["Gold"] = true;
|
||||
L["goldabbrev"] = "|cffffd700g|r"
|
||||
L["Hit"] = "Acerto"
|
||||
L["Hold Shift + Right Click:"] = true;
|
||||
L["Home Latency:"] = "Latência de Casa:"
|
||||
L["HP"] = "PV"
|
||||
L["HPS"] = "PVS"
|
||||
L["lvl"] = "nível"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "Mitigação por nível"
|
||||
L["No Guild"] = "Sem Guilda"
|
||||
L["Profit:"] = "Lucro:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "Redefinir Dados: Segurar Shifr + Clique Direito"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "Raide(s) Salva(s)"
|
||||
L["Server: "] = "Servidor: "
|
||||
L["Session:"] = "Sessão:"
|
||||
L["silverabbrev"] = "|cffc7c7cfs|r"
|
||||
L["SP"] = "PM"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "Gasto:"
|
||||
L["Stats For:"] = "Estatísticas para:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "CPU Total:"
|
||||
L["Total Memory:"] = "Memória Total:"
|
||||
L["Total: "] = "Total: "
|
||||
L["Unhittable:"] = "Inacertável"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s tentou chamar a função protegida '%s'."
|
||||
L["No locals to dump"] = "Sem locais para despejar"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s está tentando compartilhar os filtros dele com você. Gostaria de aceitar o pedido?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s está tentando compartilhar o perfil %s com você. Gostaria de aceitar o pedido?"
|
||||
L["Data From: %s"] = "Dados De: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "Baixa de filtros de %s completada, gostaria de aplicar as alterações agora?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "Senhor! É um milagre! O Download sumiu como um peido no vento! Tente novamente!"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "Baixa de perfil completada de %s, mas o perfil %s já existe. Altere o nome ou ele irá sobrescrever o perfil existente."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "Baixa de perfil completada de %s, gostaria de carregar o perfil %s agora?"
|
||||
L["Profile request sent. Waiting for response from player."] = "Pedido de perfil enviado. Aguardando a resposta do jogador."
|
||||
L["Request was denied by user."] = "Pedido negado pelo usuário."
|
||||
L["Your profile was successfully recieved by the player."] = "Seu perfil foi recebido com sucesso pelo jogador."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = true;
|
||||
L["Auras Set"] = "Auras configuradas"
|
||||
L["Auras"] = true;
|
||||
L["Caster DPS"] = "DPS Lançador"
|
||||
L["Chat Set"] = "Bate-Papo configurado"
|
||||
L["Chat"] = "Bate-papo"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "Escolha o tema de layout que deseje usar inicialmente."
|
||||
L["Classic"] = "Clássico"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "Clique no botão abaixo para redimensionar os seus quadros de bate-papo, quadros de unidades, e reposicionar as suas barras de ações."
|
||||
L["Config Mode:"] = "Modo de configuração"
|
||||
L["CVars Set"] = "CVars configuradas"
|
||||
L["CVars"] = "CVars"
|
||||
L["Dark"] = "Escuro"
|
||||
L["Disable"] = "Desativar"
|
||||
L["ElvUI Installation"] = "Instalação do ElvUI"
|
||||
L["Finished"] = "Terminado"
|
||||
L["Grid Size:"] = "Tamanho da Grade"
|
||||
L["Healer"] = "Curandeiro"
|
||||
L["High Resolution"] = "Alta Resolução"
|
||||
L["high"] = "alto"
|
||||
L["Icons Only"] = "Apenas Ícones"
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "Se existir um ícone ou uma barra de aura que você não queira ver exibida simplesmente mantenha pressionada a tecla Shift e clique no ícone com o botão direito para que o ícone/barra de aura desapareça."
|
||||
L["Importance: |cff07D400High|r"] = "Importância: |cff07D400Alta|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "Importância: |cffD3CF00Média|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "Importância: |cffFF0000Baixa|r"
|
||||
L["Installation Complete"] = "Instalação Completa"
|
||||
L["Layout Set"] = "Definições do Layout"
|
||||
L["Layout"] = "Layout"
|
||||
L["Lock"] = "Travar"
|
||||
L["Low Resolution"] = "Baixa Resolução"
|
||||
L["low"] = "baixo"
|
||||
L["Nudge"] = "Ajuste fino"
|
||||
L["Physical DPS"] = "DPS Físico"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "Por favor, clique no botão abaixo para que possa configurar as variáveis e Recarregar a IU."
|
||||
L["Please click the button below to setup your CVars."] = "Por favor, clique no botão abaixo para configurar as suas Cvars."
|
||||
L["Please press the continue button to go onto the next step."] = "Por favor, pressione o botão Continuar para passar à próxima etapa."
|
||||
L["Resolution Style Set"] = "Estilo de Resolução defenido"
|
||||
L["Resolution"] = "Resolução"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = true;
|
||||
L["Setup Chat"] = "Configurar Bate-papo"
|
||||
L["Setup CVars"] = "Configurar CVars"
|
||||
L["Skip Process"] = "Pular Processo"
|
||||
L["Sticky Frames"] = "Quadros Pegadiços"
|
||||
L["Tank"] = "Tanque"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "As janelas de bate-papo funcionam da mesma forma das da Blizzard, você pode usar o botão direito nas guias para os arrastar, mudar o nome, etc. Por favor clique no botão abaixo para configurar as suas janelas de bate-papo"
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "O modo configuração em jogo pode ser acessado escrevendo o comando /ec ou clicando no botão 'C' no minimapa. Pressione o botão abaixo se desejar pular o processo de instalação"
|
||||
L["Theme Set"] = "Tema configurado"
|
||||
L["Theme Setup"] = "Configuração do Tema"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "Este processo de instalação vai mostrar-lhe algumas das opções que a ElvUI tem para oferecer e também vai preparar a sua interface para ser usada."
|
||||
L["This is completely optional."] = "Isto é completamente opcional."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "Esta parte da instalação é para definir os nomes, posições e cores das suas janelas de bate-papo."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "Esta parte da instalação serve para definir as suas opcões padrão do WoW, é recomendado fazer isto para que tudo funcione corretamente."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "Esta resolução não exige que altere as definições para que a interface caiba no seu ecrã (monitor)."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "Esta resolução requer que altere algumas definições para que tudo caiba no seu ecrã (monitor)."
|
||||
L["This will change the layout of your unitframes and actionbars."] = true;
|
||||
L["Trade"] = "Comércio"
|
||||
L["Welcome to ElvUI version %s!"] = "Bem-vindo à versão %s da ElvUI!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "O processo de instalação está agora terminado. Se precisar de suporte técnico por favor visite-nos no site https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "As cores e fontes da ElvUI podem ser mudadas em qualquer momento no modo de configuração demtro do jogo."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "Pode agora escolher o layout que pretende usar baseado no seu papel."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "Poderá ter de alterar estas definições dependendo de quão baixa for a sua resolução."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "A sua resolução actual é %s, esta é considerada uma resolução %s."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "Barras"
|
||||
L["Calendar"] = "Calendário"
|
||||
L["Can't Roll"] = "Não pode rolar"
|
||||
L["Disband Group"] = "Dissolver Grupo"
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = "Ativar"
|
||||
L["Experience"] = "Experiência"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "Saque de Peixes"
|
||||
L["Left Click:"] = "Clique Esquerdo:"
|
||||
L["Raid Menu"] = "Menu de Raide"
|
||||
L["Remaining:"] = "Restante:"
|
||||
L["Rested:"] = "Descansado:"
|
||||
L["Right Click:"] = "Clique Direito:"
|
||||
L["Show BG Texts"] = "Mostrar Textos do CB"
|
||||
L["Toggle Chat Frame"] = "Mostrar/Ocultar Bat-papo"
|
||||
L["Toggle Configuration"] = "Mostrar/Ocultar Modo de Configuração"
|
||||
L["XP:"] = "XP:"
|
||||
L["You don't have permission to mark targets."] = "Você não tem permissão para marcar alvos."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "Quadros de Arenas"
|
||||
L["Bag Mover (Grow Down)"] = true;
|
||||
L["Bag Mover (Grow Up)"] = true;
|
||||
L["Bag Mover"] = true;
|
||||
L["Bags"] = "Bolsas"
|
||||
L["Bank Mover (Grow Down)"] = true;
|
||||
L["Bank Mover (Grow Up)"] = true;
|
||||
L["Bar "] = "Barra "
|
||||
L["BNet Frame"] = "Quadro do Bnet"
|
||||
L["Boss Frames"] = "Quadros dos Chefes"
|
||||
L["Classbar"] = "Barra da Classe"
|
||||
L["Experience Bar"] = "Barra de Experiência"
|
||||
L["Focus Castbar"] = "Barra de Lançamento do Foco"
|
||||
L["Focus Frame"] = "Quadro do Foco"
|
||||
L["FocusTarget Frame"] = "Quadro do Alvo do Foco"
|
||||
L["GM Ticket Frame"] = "Quadro de Consulta com GM"
|
||||
L["Left Chat"] = "Bate-papo esquerdo"
|
||||
L["Loot / Alert Frames"] = "Quadro de Saque / Alerta"
|
||||
L["Loot Frame"] = true;
|
||||
L["MA Frames"] = "Quadro do Assistente Principal"
|
||||
L["Micro Bar"] = "Micro Barra"
|
||||
L["Minimap"] = "Minimapa"
|
||||
L["MirrorTimer"] = true;
|
||||
L["MT Frames"] = "Quadro do Tank Principal"
|
||||
L["Party Frames"] = "Quadros de Grupo"
|
||||
L["Pet Bar"] = "Barra do Ajudante"
|
||||
L["Pet Castbar"] = true;
|
||||
L["Pet Frame"] = "Quadro do Ajudante"
|
||||
L["PetTarget Frame"] = "Quadro do Alvo do Ajudante"
|
||||
L["Player Buffs"] = true;
|
||||
L["Player Castbar"] = "Barra de lançamento do Jogador"
|
||||
L["Player Debuffs"] = true;
|
||||
L["Player Frame"] = "Quadro do Jogador"
|
||||
L["Player Powerbar"] = true;
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = true;
|
||||
L["Raid Pet Frames"] = true;
|
||||
L["Raid-40 Frames"] = true;
|
||||
L["Reputation Bar"] = "Barra de Reputação"
|
||||
L["Right Chat"] = "Bate-papo direito"
|
||||
L["Stance Bar"] = "Barra de Postura"
|
||||
L["Target Castbar"] = "Barra de lançamento do Alvo"
|
||||
L["Target Frame"] = "Quadro do Alvo"
|
||||
L["Target Powerbar"] = true;
|
||||
L["TargetTarget Frame"] = "Quadro do Alvo do Alvo"
|
||||
L["TargetTargetTarget Frame"] = true;
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "Tooltip"
|
||||
L["Vehicle Seat Frame"] = "Quadro de Assento de Veículo"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = true;
|
||||
L["In Progress"] = true;
|
||||
L["List of installations in queue:"] = true;
|
||||
L["Pending"] = true;
|
||||
L["Steps"] = true;
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00Ligado a |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "%s quadro(s) tem um ponto de fixação em conflito, por favor mude o ponto de fixação do quadro de bônus ou de penalidades para que eles não fiquem ligados uns aos outros. Forçando as penalidades a ficarem anexadas ao quadro principal até que sejam consertados."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "Todos os atalhos livres para"
|
||||
L["Already Running.. Bailing Out!"] = "Já está executando... Cancelando a ordenação!"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "Os textos Informativos dos Campos de Batalha estão temporáriamente ocultos, para serem mostrados digite /bgstats ou clique direito no ícone 'C' perto do minimapa."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "Os textos Informativos irão agora ser mostrados se estiver dentro de um Campo de Batalha."
|
||||
L["Binds Discarded"] = "Ligações Descartadas"
|
||||
L["Binds Saved"] = "Ligações Salvas"
|
||||
L["Confused.. Try Again!"] = "Confuso... Tente novamente!"
|
||||
L["No gray items to delete."] = "Nenhum item cinzento para destruir."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "O feitiço '%s' foi adicionado à Lista Negra dos filtros das auras de unidades."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = true;
|
||||
L["Vendored gray items for:"] = "Vendeu os itens cinzentos por:"
|
||||
L["You don't have enough money to repair."] = "Você não tem dinheiro suficiente para reparar."
|
||||
L["You must be at a vendor."] = "Tem de estar num vendedor."
|
||||
L["Your items have been repaired for: "] = "Seus itens foram reparadas por: "
|
||||
L["Your items have been repaired using guild bank funds for: "] = "Seus itens foram reparados usando fundos do banco da guilda por: "
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000Erro Lua recebido. Pode ver a mensagem de erro quando sair de combate"
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "A definição que você alterou afetará apenas este personagem. Esta definição que você alterou não será afetada por mudanças de perfil. Alterar esta difinição requer que você recarregue a sua interface."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = true;
|
||||
L["Are you sure you want to delete all your gray items?"] = "Tem a certeza de que deseja destruir todos os seus itens cinzentos?"
|
||||
L["Are you sure you want to disband the group?"] = "Tem a certeza de que quer dissolver o grupo?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "Tem certeza que quer redefinir todas as configurações desse perfil?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "Tem a certeza de que deseja restaurar todos os movedores de volta para a sua posição padrão?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "Devido à grande confusão causada pelo novo sistema de auras foi implementado um novo passo no processo de instalação. Este passo é opcional, se você gosta da maneira que as suas auras estão configuradas vá para o último passo e clique em Terminado para não ser solicitado a configurar este passo novamente. Se por algum motivo for repetidamente solicitado a fazê-lo, por favor reinicie o seu jogo."
|
||||
L["Can't buy anymore slots!"] = "Não é possível comprar mais espaços!"
|
||||
L["Disable Warning"] = "Desativar Aviso"
|
||||
L["Discard"] = "Descartar"
|
||||
L["Do you enjoy the new ElvUI?"] = true;
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "Você jura não postar no suporte técnico sobre alguma coisa não funcionando sem antes desabilitar a combinação addon/módulo?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = true;
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = true;
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = true;
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "Paire com o seu rato (mouse) sobre qualquer botão de ação ou botão do grimório para fazer uma Ligação. Pressione a tecla Escape ou clique com o botão direito para limpar o atalho atual."
|
||||
L["I Swear"] = "Eu Juro"
|
||||
L["No, Revert Changes!"] = true;
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "Oh senhor, você está com os addons ElvUI e Tuki ativos ao mesmo tempo. Selecione um para desativar."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "Uma ou mais das alterações que fez requerem que recarregue a IU."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "Uma ou mais das alterações que fez afetará todos os personagens que usam este addon. Você terá que recarregar a interface para ver as alterações que fez."
|
||||
L["Save"] = "Salvar"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = true;
|
||||
L["Type /hellokitty to revert to old settings."] = true;
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "Ao usar o leioute de curandeiro é altamente recomendado que você baixe o addon Clique se quiser ter a função de clicar-para-curar."
|
||||
L["Yes, Keep Changes!"] = true;
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = true;
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "Você mudou a Escala da sua IU, no entanto ainda tem a opção de dimensionamento automático ativa na ElvUI. Pressione Aceitar se gostaria de desativar a opção de dimensionamento automático."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = true;
|
||||
L["You must purchase a bank slot first!"] = "Você deve comprar um espaço no banco primeiro!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "Contar"
|
||||
L["Item Level:"] = true;
|
||||
L["Talent Specialization:"] = true;
|
||||
L["Targeted By:"] = "Sendo Alvo de:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "A opção Marcas de Raide está disponivel pressionando Escape -> Teclas de Atalho, rolando tudo para o fundo debaixo de ElvUI e definindo uma tecla de atalho para o Raid Marker."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "A ElvUI contém o modo de duas especializações, que permite que carregue perfis diferentes baseado na sua especialização atual rapidamente. Você pode ativar esta opção na guia Perfis."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Para suporte técnico visite-nos no site https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "Se acidentalmente remover um quadro de conversação você pode sempre ir ao menu de configuração em jogo, pressionar instalar, ir até a etapa de bate-papo e os restaurar."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "Se estiver a ter problemas com a ElvUI tente desativar todos os addons exceto a ElvUI, lembre-se que a ElvUI é um addon de substituição de interface completo, e não se consegue executar dois addons que fazem a mesma coisa."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "A unidade de Foco pode ser definida escrevendo /focus quando voce tem no alvo a unidade que quer tal. É recomendado que faça uma macro para este efeito."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "Para mover habilidades nas barras de ação (modo padrão) mantenha pressionado Shift enquanto arrasta. Você pode mudar a tecla no menu de opções das barras de ações."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "Para configurar que canais aparecem em cada quadro de conversação, clique com o botão direito no guia do bate-papo e vá a configurações."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "Você pode acessar ao 'copiar bate-papo' e ao menu de funções do bate-papo passando com o rato (mouse) no canto superior direito do painel e clicando botão esquerdo/direito no botão que irá aparecer."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "Você pode ver o nivel médio de itens que outra pessoa tem mantendo shift pressionado e passando com o rato (mouse) por cima deles. Deverá aparecer na tooltip."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "Você pode definir os seus atalhos rapidamente escrevendo /kb."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "Você pode ativar a micro barra clicando no minimapa com o seu botão do meio do rato (mouse), pode também conseguir isto ativando a verdadeira micro barra nas definições das barras de ações."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "Você pode usar o comando /resetui para restaurar todos os movedores. Pode usar este comando também para restaurar um movedor especifico escrevendo /resetui <nome do movedor> \nExemplo: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = true;
|
||||
L["Ghost"] = "Fantasma"
|
||||
L["Offline"] = "Desconectado"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- Russian localization file for ruRU.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "ruRU")
|
||||
if not L then return; end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "Аддон %s не совместим с модулем %s ElvUI. Пожалуйста, выберите отключить ли несовместимый аддон или модуль."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Добро пожаловать в %sElvUI|r версии %s%s|r, наберите /ec для доступа в меню настроек. Если Вам нужна техническая поддержка, посетите https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "Назначение"
|
||||
L["Key"] = "Клавиша"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "Нет назначений"
|
||||
L["Remove Bar %d Action Page"] = "Удалить панель %d из списка переключаемых"
|
||||
L["Trigger"] = "Триггер"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "Банк"
|
||||
L["Hold Control + Right Click:"] = "Зажать Control + ПКМ:"
|
||||
L["Hold Shift + Drag:"] = "Зажать shift и перетаскивать:"
|
||||
L["Purchase Bags"] = "Приобрести слот"
|
||||
L["Reset Position"] = "Сбросить позицию"
|
||||
L["Sort Bags"] = "Сортировать"
|
||||
L["Temporary Move"] = "Временное перемещение"
|
||||
L["Toggle Bags"] = "Показать сумки"
|
||||
L["Toggle Key"] = "Показать ключи"
|
||||
L["Vendor Grays"] = "Продавать серые предметы"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "АФК" --Also used in datatexts and tooltip
|
||||
L["BG"] = "ПБ"
|
||||
L["BGL"] = "Лидер ПБ"
|
||||
L["DND"] = "ДНД" --Also used in datatexts and tooltip
|
||||
L["G"] = "Г"
|
||||
L["Invalid Target"] = "Неверная цель"
|
||||
L["O"] = "Оф"
|
||||
L["P"] = "Гр"
|
||||
L["PL"] = "Лидер гр."
|
||||
L["R"] = "Р"
|
||||
L["RL"] = "РЛ"
|
||||
L["RW"] = "Объявление"
|
||||
L["says"] = "говорит"
|
||||
L["whispers"] = "шепчет"
|
||||
L["yells"] = "кричит"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(Зажать Shift) Использование памяти"
|
||||
L["Avoidance Breakdown"] = "Распределение защиты"
|
||||
L["Character: "] = "Персонаж: "
|
||||
L["Chest"] = "Грудь"
|
||||
L["Combat"] = "Бой"
|
||||
L["Combat Time"] = "В бою"
|
||||
L["Coords"] = "Коорд."
|
||||
L["copperabbrev"] = "|cffeda55fм|r" --Also used in Bags
|
||||
L["Deficit:"] = "Убыток:"
|
||||
L["DPS"] = "УВС"
|
||||
L["Earned:"] = "Заработано"
|
||||
L["Friends List"] = "Список друзей"
|
||||
L["Friends"] = "Друзья" --Also in Skins
|
||||
L["Gold"] = "Золото"
|
||||
L["goldabbrev"] = "|cffffd700з|r" --Also used in Bags
|
||||
L["Hit"] = "Метк."
|
||||
L["Hold Shift + Right Click:"] = "Shift + ПКМ:"
|
||||
L["Home Latency:"] = "Локальная задержка: "
|
||||
L["HP"] = "+ Исцел."
|
||||
L["HPS"] = "ИВС"
|
||||
L["lvl"] = "ур."
|
||||
L["Miss Chance"] = "Вероятность промаха"
|
||||
L["Mitigation By Level: "] = "Снижение на уровне: "
|
||||
L["No Guild"] = "Нет гильдии"
|
||||
L["Profit:"] = "Прибыль:"
|
||||
L["Reload UI"] = "Перезагрузка"
|
||||
L["Reset Data: Hold Shift + Right Click"] = "Сбросить данные: Shift + ПКМ"
|
||||
L["Right Click: Reset CPU Usage"] = "ПКМ: Сбросить использование процессора"
|
||||
L["Saved Raid(s)"] = "Сохраненные рейды"
|
||||
L["Server: "] = "На сервере:"
|
||||
L["Session:"] = "За сеанс:"
|
||||
L["silverabbrev"] = "|cffc7c7cfс|r" --Also used in Bags
|
||||
L["SP"] = "+ Закл."
|
||||
L["Spell/Heal Power"] = "Сила заклинаний"
|
||||
L["Spent:"] = "Потрачено:"
|
||||
L["Stats For:"] = "Статистика для:"
|
||||
L["System"] = "Система"
|
||||
L["Total CPU:"] = "Использование процессора:"
|
||||
L["Total Memory:"] = "Всего памяти:"
|
||||
L["Total: "] = "Всего: "
|
||||
L["Unhittable:"] = "Полная защита от ударов"
|
||||
L["Wintergrasp"] = "Озеро Ледяных Оков"
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s tried to call the protected function '%s'."
|
||||
L["No locals to dump"] = "No locals to dump"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s хочет передать Вам свои фильтры. Желаете ли Вы принять их?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s хочет передать Вам профиль %s. Желаете ли Вы принять его?"
|
||||
L["Data From: %s"] = "Данные от: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "Завершена загрузка фильтров от %s. Желаете применить изменения сейчас?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "Чтоб его! Загрузка была... да всплыла. Попробуйте еще раз!"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "Загрузка профиля от %s завершена, но профиль %s уже существует. Измените его название или он перезапишет уже существующий профиль."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "Загрузка профиля от %s завершена, хотите загрузить профиль %s сейчас?"
|
||||
L["Profile request sent. Waiting for response from player."] = "Запрос на передачу профиля отправлен. Ждите, пожалуйста, ответа."
|
||||
L["Request was denied by user."] = "Запрос отклонен пользователем."
|
||||
L["Your profile was successfully recieved by the player."] = "Ваш профиль успешно получен целью. Ура, товарищи!"
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "Полосы аур и иконки"
|
||||
L["Auras Set"] = "Ауры установлены"
|
||||
L["Auras"] = "Ауры"
|
||||
L["Caster DPS"] = "Заклинатель"
|
||||
L["Chat Set"] = "Чат настроен"
|
||||
L["Chat"] = "Чат"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "Выберите тему, которую Вы хотите использовать."
|
||||
L["Classic"] = "Классическая"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "Нажмите кнопку ниже для изменения размеров вашего чата, рамок юнитов и перемещения ваших панелей действий."
|
||||
L["Config Mode:"] = "Режим настройки:"
|
||||
L["CVars Set"] = "Настройки сброшены"
|
||||
L["CVars"] = "Настройки игры"
|
||||
L["Dark"] = "Темная"
|
||||
L["Disable"] = "Выключить"
|
||||
L["ElvUI Installation"] = "Установка ElvUI"
|
||||
L["Finished"] = "Завершить"
|
||||
L["Grid Size:"] = "Размер сетки"
|
||||
L["Healer"] = "Лекарь"
|
||||
L["High Resolution"] = "Высокое разрешение"
|
||||
L["high"] = "высоким"
|
||||
L["Icons Only"] = "Только иконки" --Also used in Bags
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "Если Вы видите иконку или полосу аур, которую Вы не хотите отображать, просто зажмите shift и кликните на иконке правой кнопкой, чтобы она исчезла."
|
||||
L["Importance: |cff07D400High|r"] = "Важность: |cff07D400Высокая|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "Важность: |cffD3CF00Средняя|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "Важность: |cffFF0000Низкая|r"
|
||||
L["Installation Complete"] = "Установка завершена"
|
||||
L["Layout Set"] = "Расположение установлено"
|
||||
L["Layout"] = "Расположение"
|
||||
L["Lock"] = "Закрепить"
|
||||
L["Low Resolution"] = "Низкое разрешение"
|
||||
L["low"] = "низким"
|
||||
L["Nudge"] = "Сдвиг"
|
||||
L["Physical DPS"] = "Физический урон"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "Пожалуйста, нажмите кнопку ниже для установки переменных и перезагрузки интерфейса."
|
||||
L["Please click the button below to setup your CVars."] = "Пожалуйста, нажмите кнопку ниже для сброса настроек."
|
||||
L["Please press the continue button to go onto the next step."] = "Пожалуйста, нажмите кнопку 'Продолжить' для перехода к следующему шагу"
|
||||
L["Resolution Style Set"] = "Разрешение установлено"
|
||||
L["Resolution"] = "Разрешение"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "Выберите тип системы аур, который Вы хотите использовать на рамках юнитов ElvUI. 'Полосы аур и иконки' включит и полосы и иконки, выберите 'Только иконки', чтобы видеть только их."
|
||||
L["Setup Chat"] = "Настроить чат"
|
||||
L["Setup CVars"] = "Сбросить настройки"
|
||||
L["Skip Process"] = "Пропустить установку"
|
||||
L["Sticky Frames"] = "Клейкие фреймы"
|
||||
L["Tank"] = "Танк"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "Окна чата работают так же, как и в стандартном чате Blizzard. Вы можете нажать правую кнопку мыши на вкладках для перемещения, переименования и тд. Пожалуйста, нажмите кнопку ниже для настройки чата."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "Меню настроек можно вызвать командой /ес или кнопкой 'С' на миникарте. Нажмите кнопку ниже, если Вы хотите прервать процесс установки."
|
||||
L["Theme Set"] = "Тема установлена"
|
||||
L["Theme Setup"] = "Тема"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "Этот процесс установки поможет Вам узнать о некоторых функциях ElvUI и подготовить Ваш интерфейс к использованию."
|
||||
L["This is completely optional."] = "Это действие абсолютно не обязательно."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "Эта часть установки настроит названия, позиции и цвета вкладок чата."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "Эта часть установки сбросит настройки World of Warcraft на конфигурацию по умолчанию. Рекомендуется выполнить этот шаг для надлежащей работы интерфейса."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "Для соответствия интерфейса вашему экрану не требуется изменения настроек."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "Для соответствия интерфейса вашему экрану требуется изменение некоторых настроек."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "Это изменит расположение ваших рамок юнитов, рейда и панелей команд."
|
||||
L["Trade"] = "Торговля"
|
||||
L["Welcome to ElvUI version %s!"] = "Добро пожаловать в ElvUI версии %s!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Вы завершили процесс установки. Если Вам требуется техническая поддержка, посетите https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "Вы всегда можете изменить шрифты и цвета любого элемента ElvUI из меню конфигурации. Классическая и пиксельная темы не отличаются для русского клиента."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "Вы можете выбрать используемое расположение, основываясь на Вашей роли."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "Вам может понадобиться дальнейшее изменение этих настроек в зависимости от того, насколько низким является ваше разрешение."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "Ваше текущее разрешение - %s, это считается %s разрешением."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [на %.0f%% опережаем |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "Полосы" --Also used in UnitFrames
|
||||
L["Calendar"] = "Календарь"
|
||||
L["Can't Roll"] = "Не могу бросить кости"
|
||||
L["Disband Group"] = "Распустить группу"
|
||||
L["Empty Slot"] = "Пустой слот"
|
||||
L["Enable"] = "Включить" --Doesn't fit a section since it's used a lot of places
|
||||
L["Experience"] = "Опыт"
|
||||
L["Farm Mode"] = "Режим фарма"
|
||||
L["Fishy Loot"] = "Улов"
|
||||
L["Left Click:"] = "ЛКМ:" --layout\layout.lua
|
||||
L["Raid Menu"] = "Рейдовое меню"
|
||||
L["Remaining:"] = "Осталось:"
|
||||
L["Rested:"] = "Бодрость:"
|
||||
L["Right Click:"] = "ПКМ:" --layout\layout.lua
|
||||
L["Show BG Texts"] = "Показать текст ПБ" --layout\layout.lua
|
||||
L["Toggle Chat Frame"] = "Показать/скрыть чат" --layout\layout.lua
|
||||
L["Toggle Configuration"] = "Конфигурация" --layout\layout.lua
|
||||
L["XP:"] = "Опыт:"
|
||||
L["You don't have permission to mark targets."] = "У вас нет разрешения на установку меток"
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "Арена" --Also used in UnitFrames
|
||||
L["Bag Mover (Grow Down)"] = "Сумки (Рост вниз)"
|
||||
L["Bag Mover (Grow Up)"] = "Сумки (Рост вверх)"
|
||||
L["Bag Mover"] = "Фиксатор сумок"
|
||||
L["Bags"] = "Сумки" --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = "Банк (Рост вниз)"
|
||||
L["Bank Mover (Grow Up)"] = "Банк (Рост вверх)"
|
||||
L["Bar "] = "Панель " --Also in ActionBars
|
||||
L["BNet Frame"] = "Оповещения BNet"
|
||||
L["Boss Frames"] = "Боссы" --Also used in UnitFrames
|
||||
L["Classbar"] = "Полоса класса"
|
||||
L["Experience Bar"] = "Полоса опыта"
|
||||
L["Focus Castbar"] = "Полоса заклинаний фокуса"
|
||||
L["Focus Frame"] = "Фокус" --Also used in UnitFrames
|
||||
L["FocusTarget Frame"] = "Цель фокуса" --Also used in UnitFrames
|
||||
L["GM Ticket Frame"] = "Запрос ГМу"
|
||||
L["Left Chat"] = "Левый чат"
|
||||
L["Loot / Alert Frames"] = "Розыгрыш/оповещения"
|
||||
L["Loot Frame"] = "Окно добычи"
|
||||
L["MA Frames"] = "Помощники"
|
||||
L["Micro Bar"] = "Микроменю" --Also in ActionBars
|
||||
L["Minimap"] = "Миникарта"
|
||||
L["MirrorTimer"] = "Таймер"
|
||||
L["MT Frames"] = "Танки"
|
||||
L["Party Frames"] = "Группа" --Also used in UnitFrames
|
||||
L["Pet Bar"] = "Панель питомца" --Also in ActionBars
|
||||
L["Pet Castbar"] = "Полоса заклинаний питомца"
|
||||
L["Pet Frame"] = "Питомец" --Also used in UnitFrames
|
||||
L["PetTarget Frame"] = "Цель питомца" --Also used in UnitFrames
|
||||
L["Player Buffs"] = "Баффы игрока"
|
||||
L["Player Castbar"] = "Полоса заклинаний игрока"
|
||||
L["Player Debuffs"] = "Дебаффы игрока"
|
||||
L["Player Frame"] = "Игрок" --Also used in UnitFrames
|
||||
L["Player Powerbar"] = "Полоса ресурса игрока"
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "Рейд"
|
||||
L["Raid Pet Frames"] = "Питомцы рейда"
|
||||
L["Raid-40 Frames"] = "Рейд 40"
|
||||
L["Reputation Bar"] = "Полоса репутации"
|
||||
L["Right Chat"] = "Правый чат"
|
||||
L["Stance Bar"] = "Панель стоек" --Also in ActionBars
|
||||
L["Target Castbar"] = "Полоса заклинаний цели"
|
||||
L["Target Frame"] = "Цель" --Also used in UnitFrames
|
||||
L["Target Powerbar"] = "Полоса ресурса цели"
|
||||
L["TargetTarget Frame"] = "Цель цели" --Also used in UnitFrames
|
||||
L["TargetTargetTarget Frame"] = "Цель цели цели"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "Подсказка"
|
||||
L["Vehicle Seat Frame"] = "Техника"
|
||||
L["Watch Frame"] = "Задания"
|
||||
L["Weapons"] = "Оружие"
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = "Установка плагина ElvUI"
|
||||
L["In Progress"] = "В процессе"
|
||||
L["List of installations in queue:"] = "Очередь установки:"
|
||||
L["Pending"] = "Ожидает"
|
||||
L["Steps"] = "Шаги"
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00назначено для |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "Обнаружен конфликт точек фиксирования во фрейме(ах) %s. Пожалуйста, переназначьте фиксирование баффов и дебаффов так, чтобы они не крепились друг к другу. Установлено принудительное крепление дебаффов к фрейму."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "Сброшены все назначения для |cff00ff00%s|r."
|
||||
L["Already Running.. Bailing Out!"] = "Уже выполняется.. Бобер, выдыхай!"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "Информация поля боя временно скрыта. Для отображения введите /bgstat или ПКМ на иконке 'С' у миникарты."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "Информация поля боя снова будет отображаться, если Вы находитесь на них."
|
||||
L["Binds Discarded"] = "Назначения отменены"
|
||||
L["Binds Saved"] = "Назначения сохранены"
|
||||
L["Confused.. Try Again!"] = "Что за?.. Попробуйте еще раз!"
|
||||
L["No gray items to delete."] = "Нет предметов серого качества для удаления."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "Заклинание '%s' было добавлено в фильтр 'Blacklist' аур рамок юнитов."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = "Эта опция вызвала конфликт точек фиксации, в результате которого \"%s\" крепится к самому себе. Пожалуйста, проверье настройки точек фиксации. \"%s\" будет прикреплено к \"%s\"."
|
||||
L["Vendored gray items for:"] = "Проданы серые предметы на сумму:"
|
||||
L["You don't have enough money to repair."] = "У вас недостаточно денег для ремонта."
|
||||
L["You must be at a vendor."] = "Вы должны находиться у торговца"
|
||||
L["Your items have been repaired for: "] = "Ремонт обошелся в "
|
||||
L["Your items have been repaired using guild bank funds for: "] = "Ремонт обошелся гильдии в "
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000Обнаружена ошибка lua. Вы получите отчет о ней после завершения боя."
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "Настройка, которую Вы только что изменили, будет влиять только на этого персонажа. Она не будет изменяться при смене профиля. Также это изменение требует перезагрузки интерфейса для вступления в силу."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = "Приняв это вы сбросите ваши списки приоритетов для всех аур на индикаторах здоровья. Вы уверены?"
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = "Приняв это вы сбросите ваши списки приоритетов для всех аур на рамках юнитов. Вы уверены?"
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = "Вы уверены, что хоттите применить этот шрифт ко всем элементам ElvUI?"
|
||||
L["Are you sure you want to delete all your gray items?"] = "Вы уверены, что хотите удалить все предметы серого качества?"
|
||||
L["Are you sure you want to disband the group?"] = "Вы уверены, что хотите распустить группу?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "Вы уверены, что хотите сбросить все настройки для этого профиля?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "Вы уверены, что хотите сбросить все фиксаторы на позиции по умолчанию?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "Из-за массового непонимания новой системы аур, я добавил новый шаг в установку. Он опционален. Если Вам нравится, как сейчас настроены Ваши ауры, перейдите до последнюю страницу установки и нажмите \"Завершить\", чтобы это сообщение больше не появлялось. Если же оно появится снова, пожалуйста, перезапустите игру."
|
||||
L["Can't buy anymore slots!"] = "Невозможно приобрести больше слотов!"
|
||||
L["Disable Warning"] = "Отключить предупреждение"
|
||||
L["Discard"] = "Отменить"
|
||||
L["Do you enjoy the new ElvUI?"] = "Вам нравится ElvUI?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "Клянетесь ли Вы не постить на форуме технической поддержки, что что-то не работает, до того, как отключите другие аддоны/модули?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "Ваш ElvUI устарел более, чем на 5 версий. Вы можете скачать последнюю версию с https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI устарел. Вы можете скачать последнюю версию с https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI нужно провести оптимизацию базы данных. Подождите, пожалуйста."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "Наведите курсор на любую кнопку на панели или в книге заклинаний, чтобы назначит ей клавишу. Нажмите правую кнопку мыши или 'Escape', чтобы сбросить назначение для этой кнопки."
|
||||
L["I Swear"] = "Я клянусь!"
|
||||
L["No, Revert Changes!"] = "Нет, обратить изменения!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "Японский городовой... у Вас одновременно включены ElvUi и Tukui. Выберите аддон для отключения."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "Одно или несколько изменений требуют перезагрузки интерфейса"
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "Одно или несколько изменений повлияют на всех персонажей, использующих этот аддон. Вы должны перезагрузить интерфейс для отображения этих изменений."
|
||||
L["Save"] = "Сохранить"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "Профиль, который вы хотите импортировать, уже существует. Задайте новой имя или примите для перезаписи существующего профиля."
|
||||
L["Type /hellokitty to revert to old settings."] = "Напишите /hellokitty для возврата к предыдущим настройкам."
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "Для использования расположения для лекаря крайне рекомендуется установить аддон Clique, если вы хотите иметь возможность лечить по клику мышью."
|
||||
L["Yes, Keep Changes!"] = "Да, сохранить изменения!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "Вы переключились в режим тонких границ. Вы должны завершить установку для исправления графических багов."
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "Вы изменили масштаб интерфейса, однако у вас все еще активирована опция автоматического масштабирования в настройках ElvUI. Нажмите 'Принять', если Вы хотите отключить эту опцию."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "Вы импортировали настройки, которые могут потребовать перезагрузки для вступления в силу. Перезагрузить?"
|
||||
L["You must purchase a bank slot first!"] = "Сперва Вы должны приобрести дополнительный слот в банке!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "Кол-во"
|
||||
L["Item Level:"] = "Уровень предметов:"
|
||||
L["Talent Specialization:"] = "Специализация:"
|
||||
L["Targeted By:"] = "Является целью:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "Функция рейдовых меток доступна в Escape -> Назначение клавиш. Прокрутите вниз до раздела ElvUI и назначьте клавишу для рейдовых меток."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "В ElvUI присутствует функция двойной специализации, которая позволит Вам использовать разные профили для разных наборов талантов. Вы можете включить эту функцию в разделе профилей."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "За технической поддержкой обращайтесь на https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "Если Вы случайно удалили вкладку чата, всегда можно сделать следующее: зайти в конфигурацию, запустить установку, дойти до шага настроек чата и сбросить их."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "Если Вы испытываете проблемы с ElvUI, попробуйте отключить все аддоны, кроме самого ElvUI. Помните, ElvUI это аддон, полностью заменяющий интерфейс, Вы не можете одновременно использовать два аддона, выполняющих одинаковые функции."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "Запомненную цель (фокус) можно установить командой /focus при взятии нужного врага в цель. Для этого рекомендуется сделать макрос."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "Для перемещения способностей по панелям команд нужно перемещать их с зажатой клавишей shift. Вы можете поменять модификатор в опциях панелей команд."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "Для настройки отображения каналов в чате кликните правой кнопкой мыши на закладке нужного чата и выберите пункт 'параметры'."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "Вы можете получить доступ к функциям копирования чата и меню чата, наведя курсор на верхний правый угол панели чата и кликнув левой/правой кнопкой мыши на появившейся кнопке."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "Вы можете узнать средний уровень предметов игрока, зажав shift и наведя на них курсор. Информация будет отражена в подсказке."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "Вы можете быстро назначать клавиши, введя команду /kb."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "Вы можете получить доступ к микроменю, кликнув средней кнопкой мыши на миникарте. Также Вы можете включить обычное микроменю в настройках панелей команд"
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "Вы можете использовать команду /resetui чтобы сбросить положения всех фиксаторов. Вы также можете использовать команду /resetui <имя фиксатора> для сброса определенного фиксатора.\nПример: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = "Труп"
|
||||
L["Ghost"] = "Призрак"
|
||||
L["Offline"] = "Не в сети"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- Spanish localization file for esES and esMX.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "esES") or AceLocale:NewLocale("ElvUI", "esMX")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "The addon %s is not compatible with ElvUI's %s module. Please select either the addon or the ElvUI module to disable."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "Bienvenido a %sElvUI|r versión %s%s|r, escribe /ec para acceder al menú de configuración. Si necesitas ayuda o soporte técnico puedes visitarnos en https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "Controles"
|
||||
L["Key"] = "Tecla"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "No hay teclas establecidas."
|
||||
L["Remove Bar %d Action Page"] = "Quitar Barra %d de la paginación"
|
||||
L["Trigger"] = "Disparador"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "Banco"
|
||||
L["Hold Control + Right Click:"] = "Mantén Control y Haz Clic Derecho:"
|
||||
L["Hold Shift + Drag:"] = "Mantén Shift y Arrastra:"
|
||||
L["Purchase Bags"] = "Comprar Bolsas"
|
||||
L["Reset Position"] = "Reestablecer Posición"
|
||||
L["Sort Bags"] = "Ordenar Bolsas"
|
||||
L["Temporary Move"] = "Movimiento Temporal"
|
||||
L["Toggle Bags"] = "Mostrar/Ocultar Bolsas"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "Vender Objetos Grises"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "Ausente"
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "Oc"
|
||||
L["G"] = "H"
|
||||
L["Invalid Target"] = "Objetivo Inválido"
|
||||
L["O"] = "O"
|
||||
L["P"] = "G"
|
||||
L["PL"] = "LG"
|
||||
L["R"] = "B"
|
||||
L["RL"] = "LB"
|
||||
L["RW"] = "AB"
|
||||
L["says"] = "dice"
|
||||
L["whispers"] = "susurra"
|
||||
L["yells"] = "grita"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(Mantén Shift) Uso de Memoria"
|
||||
L["Avoidance Breakdown"] = "Desglose de Evasión"
|
||||
L["Character: "] = "Personaje: "
|
||||
L["Chest"] = "Pecho"
|
||||
L["Combat"] = "Combate"
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55fc|r"
|
||||
L["Deficit:"] = "Déficit:"
|
||||
L["DPS"] = "DPS"
|
||||
L["Earned:"] = "Ganada:"
|
||||
L["Friends List"] = "Lista de Amigos"
|
||||
L["Friends"] = "Amigos"
|
||||
L["Gold"] = "Oro"
|
||||
L["goldabbrev"] = "|cffffd700g|r"
|
||||
L["Hit"] = "Golpe"
|
||||
L["Hold Shift + Right Click:"] = true;
|
||||
L["Home Latency:"] = "Latencia Local:"
|
||||
L["HP"] = "Salud"
|
||||
L["HPS"] = "VPS"
|
||||
L["lvl"] = "Niv"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "Mitigación Por Nivel: "
|
||||
L["No Guild"] = "Sin Hermandad"
|
||||
L["Profit:"] = "Ganancia:"
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "Restablecer Datos: Mantén Shift + Clic Derecho"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "Banda(s) Guardada(s)"
|
||||
L["Server: "] = "Servidor: "
|
||||
L["Session:"] = "Sesión:"
|
||||
L["silverabbrev"] = "|cffc7c7cfs|r"
|
||||
L["SP"] = "PH"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "Gastada:"
|
||||
L["Stats For:"] = "Estadísticas para:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "CPU Total:"
|
||||
L["Total Memory:"] = "Memoria Total:"
|
||||
L["Total: "] = "Total: "
|
||||
L["Unhittable:"] = "Imbatible:"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s intentó llamar a la función protegida '%s'."
|
||||
L["No locals to dump"] = "No hay locales para volcar"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s quiere compartir sus filtros contigo. ¿Aceptas la petición?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s quiere compartir el perfil %s contigo. ¿Aceptas la petición?"
|
||||
L["Data From: %s"] = "Datos De: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "Se completó la descarga de los filtros de %s. ¿Quieres aplicar los cambios ahora?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "¡Milagro! ¡La descarga se desvaneció como pedo! Intenta de nuevo"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "Descarga de perfil de %s completa, pero el perfil %s ya existe. Cámbiale el nombre o se reemplazará el perfil existente."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "Descarga de perfil de %s completa ¿Quieres cargar el perfil %s ahora?"
|
||||
L["Profile request sent. Waiting for response from player."] = "Petición de perfil enviada. Esperando respuesta del jugador."
|
||||
L["Request was denied by user."] = "Petición denegada por el jugador."
|
||||
L["Your profile was successfully recieved by the player."] = "Tu perfil ha sido recibido exitosamente por el jugador."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "Barras de Auras e Iconos"
|
||||
L["Auras Set"] = "Auras Configuradas"
|
||||
L["Auras"] = true;
|
||||
L["Caster DPS"] = "DPS Hechizos"
|
||||
L["Chat Set"] = "Chat Configurado"
|
||||
L["Chat"] = "Chat"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "Elige un tema de distribución para usar en tu configuración inicial."
|
||||
L["Classic"] = "Clásico"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "Haz clic en el botón de abajo para cambiar el tamaño de los marcos de chat y de unidad, y reubicar tus barras de acción."
|
||||
L["Config Mode:"] = "Modo de Configuración"
|
||||
L["CVars Set"] = "CVars Configuradas"
|
||||
L["CVars"] = "CVars"
|
||||
L["Dark"] = "Oscuro"
|
||||
L["Disable"] = "Desactivar"
|
||||
L["ElvUI Installation"] = "Instalación de ElvUI"
|
||||
L["Finished"] = "Terminado"
|
||||
L["Grid Size:"] = "Tamaño de la Rejilla:"
|
||||
L["Healer"] = "Sanador"
|
||||
L["High Resolution"] = "Alta Resolución"
|
||||
L["high"] = "alta"
|
||||
L["Icons Only"] = "Sólo Iconos"
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "Si tienes un icono o una barra de aura que no quieres ver simplemente mantén pulsado la tecla Shift y haz clic con el botón izquierdo del ratón en el icono para que desaparezca."
|
||||
L["Importance: |cff07D400High|r"] = "Importancia: |cff07D400Alta|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "Importancia: |cffD3CF00Media|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "Importancia: |cffFF0000Baja|r"
|
||||
L["Installation Complete"] = "Instalación Completa"
|
||||
L["Layout Set"] = "Distribución Establecida"
|
||||
L["Layout"] = "Distribución"
|
||||
L["Lock"] = "Bloquear"
|
||||
L["Low Resolution"] = "Baja Resolución"
|
||||
L["low"] = "baja"
|
||||
L["Nudge"] = "Ajuste Fino"
|
||||
L["Physical DPS"] = "DPS Físico"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "Haz clic en el botón de abajo para configurar variables y recargar la interfaz."
|
||||
L["Please click the button below to setup your CVars."] = "Haz clic en el botón de abajo para configurar las CVars"
|
||||
L["Please press the continue button to go onto the next step."] = "Presiona el botón de continuar para ir al siguiente paso"
|
||||
L["Resolution Style Set"] = "Estilo de Resolución Establecido"
|
||||
L["Resolution"] = "Resolución"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "Selecciona el tipo de sistema de de auras que deseas utilizar con los marcos de unidad de ElvUI. Establécelo a Barras de Auras e Iconos para usar a la vez la barra de auras y los iconos, establécelo en Sólo Iconos para ver solo los iconos."
|
||||
L["Setup Chat"] = "Configurar Chat"
|
||||
L["Setup CVars"] = "Configurar CVars"
|
||||
L["Skip Process"] = "Saltar Proceso"
|
||||
L["Sticky Frames"] = "Marcos Adhesivos"
|
||||
L["Tank"] = "Tanque"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "Las ventanas de chat funcionan igual que sus contrapartes estándar de Blizzard. Puedes hacer clic derecho en las pestañas y arrastrarlas, cambiarles el nombre, etc. Haz clic en el botón de abajo para configurar las ventanas de chat."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "El menú de configuración puede ser accedido mediante el comando /ec o haciendo clic en el botón 'C' del minimapa. Presiona el botón de abajo si deseas saltarte la instalación."
|
||||
L["Theme Set"] = "Establecer Tema"
|
||||
L["Theme Setup"] = "Configurar Tema"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "El proceso de instalación te ayudará a aprender algunas de las características de ElvUI y preparará la interfaz para su uso."
|
||||
L["This is completely optional."] = "Esto es completamente opcional."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "Esta parte de la instalación configura los nombres, posiciones y colores de las ventanas de chat."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "Esta parte de la instalación configura las opciones predeterminadas de World of Warcraft. Se recomienda hacer este paso para que todo funcione apropiadamente."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "Esta resolución no necesita que cambies los ajustes para que quepa la interfaz en tu pantalla."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "Esta resolución requiere que cambies algunos ajustes para que todo quepa en tu pantalla."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "Ésto cambiará el diseño de los marcos de unidades y barras de acción."
|
||||
L["Trade"] = "Intercambio"
|
||||
L["Welcome to ElvUI version %s!"] = "Bienvenido(a) a ElvUI versión %s!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Ya has terminado con el proceso de instalación. Si necesitas ayuda o soporte técnico por favor visítanos en https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "Siempre puedes cambiar las fuentes y colores de cualquier elemento de ElvUI desde la configuración."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "Ahora puedes elegir qué distribución quieres basándote en tu rol de combate."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "Puede que necesites cambiar estos ajutes dependiendo de qué tan baja sea tu resolución."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "Tu resolución actual es %s, esto se considera una resolución %s."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% above |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "Barras"
|
||||
L["Calendar"] = "Calendario"
|
||||
L["Can't Roll"] = "No puede tirar dados"
|
||||
L["Disband Group"] = "Disolver Grupo"
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = "Habilitar"
|
||||
L["Experience"] = "Experiencia"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "Botín Sospechoso"
|
||||
L["Left Click:"] = "Click Izquierdo"
|
||||
L["Raid Menu"] = "Menú de Banda"
|
||||
L["Remaining:"] = "Restante"
|
||||
L["Rested:"] = "Descansado:"
|
||||
L["Right Click:"] = "Click Derecho"
|
||||
L["Show BG Texts"] = "Mostrar Textos de CB"
|
||||
L["Toggle Chat Frame"] = "Mostrar/Ocultar Marco de Chat"
|
||||
L["Toggle Configuration"] = "Mostrar/Ocultar Configuración"
|
||||
L["XP:"] = "XP:"
|
||||
L["You don't have permission to mark targets."] = "No tienes permiso para marcar objetivos."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "Marcos de Arena"
|
||||
L["Bag Mover (Grow Down)"] = "Fijador de Bolsa (Crecer hacia abajo)"
|
||||
L["Bag Mover (Grow Up)"] = "Fijador de Bolsa (Crecer hacia arriba)"
|
||||
L["Bag Mover"] = "Fijador de Bolsa"
|
||||
L["Bags"] = "Bolsas"
|
||||
L["Bank Mover (Grow Down)"] = "Fijador de Banco (Crecer hacia abajo)"
|
||||
L["Bank Mover (Grow Up)"] = "Fijador de Banco (Crecer hacia arriba)"
|
||||
L["Bar "] = "Barra "
|
||||
L["BNet Frame"] = "Marco BNet"
|
||||
L["Boss Frames"] = "Marco de Jefe"
|
||||
L["Classbar"] = "Barra de Clase"
|
||||
L["Experience Bar"] = "Barra de Experiencia"
|
||||
L["Focus Castbar"] = "Barra de Lanzamiento del Foco"
|
||||
L["Focus Frame"] = "Marco de Foco"
|
||||
L["FocusTarget Frame"] = "Marco de Objetivo del Foco"
|
||||
L["GM Ticket Frame"] = "Marco de Consultas para el MJ"
|
||||
L["Left Chat"] = "Chat Izquierdo"
|
||||
L["Loot / Alert Frames"] = "Marcos de Botín / Alerta"
|
||||
L["Loot Frame"] = "Marco de Botín"
|
||||
L["MA Frames"] = "Marcos de AP"
|
||||
L["Micro Bar"] = "Micro Barra"
|
||||
L["Minimap"] = "Minimapa"
|
||||
L["MirrorTimer"] = true;
|
||||
L["MT Frames"] = "Marcos de TP"
|
||||
L["Party Frames"] = "Marco de Grupo"
|
||||
L["Pet Bar"] = "Barra de Mascota"
|
||||
L["Pet Castbar"] = "Barra de Lanzamiento de Mascota"
|
||||
L["Pet Frame"] = "Marco de Mascota"
|
||||
L["PetTarget Frame"] = "Marco de Objetivo de Mascota"
|
||||
L["Player Buffs"] = "Ventajas de Jugador"
|
||||
L["Player Castbar"] = "Barra de Lanzamiento del Jugador"
|
||||
L["Player Debuffs"] = "Perjuicios de Jugador"
|
||||
L["Player Frame"] = "Marco de Jugador"
|
||||
L["Player Powerbar"] = "Barra de Poder del Jugador"
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "Marcos de Banda"
|
||||
L["Raid Pet Frames"] = "Marcos de Banda con Mascotas"
|
||||
L["Raid-40 Frames"] = "Marcos de Banda de 40"
|
||||
L["Reputation Bar"] = "Barra de Reputación"
|
||||
L["Right Chat"] = "Chat Derecho"
|
||||
L["Stance Bar"] = "Barra de Forma"
|
||||
L["Target Castbar"] = "Barra de Lanzamiento del Objetivo"
|
||||
L["Target Frame"] = "Marco de Objetivo"
|
||||
L["Target Powerbar"] = "Barra de Poder del Objetivo"
|
||||
L["TargetTarget Frame"] = "Marco de Objetivo de Objetivo"
|
||||
L["TargetTargetTarget Frame"] = "Marco del Objetivo del Objetivo del Objetivo"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "Descripción Emergente"
|
||||
L["Vehicle Seat Frame"] = "Marco del Asiento del Vehículo"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = "Instalación del plugin de ElvUI"
|
||||
L["In Progress"] = "En Progreso"
|
||||
L["List of installations in queue:"] = "Lista de Instalaciones en cola:"
|
||||
L["Pending"] = "Pendiente"
|
||||
L["Steps"] = "Pasos"
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00ligado(a) a |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = "El marco(s) %s tiene un punto de fijación en conflicto, por favor cambia el punto de fijación de los beneficios o los perjuicios para que no estén adjuntos entre ellos. Se forzará a los perjuicios para que se adjunten al marco de unidad principal hasta que se corrija."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "Todos los atajos borrados para |cff00ff00%s|r."
|
||||
L["Already Running.. Bailing Out!"] = "Ya está en ejecución... ¡Cancelando!"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "Textos de datos de los campos de batalla temporalmente ocultos, para mostrarlos escribe /bgstats o click derecho en 'C' donde el minimapa."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "Los textos de datos de los campos de batalla serán visibles de nuevo si estás en un campo de batalla."
|
||||
L["Binds Discarded"] = "Teclas Descartadas"
|
||||
L["Binds Saved"] = "Teclas Guardadas"
|
||||
L["Confused.. Try Again!"] = "Confundido... ¡Intenta de Nuevo!"
|
||||
L["No gray items to delete."] = "No hay objetos grises para eliminar."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "El hechizo '%s' ha sido añadido a la Lista Negra del filtro de auras del marco de unidad."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = "Esta opción causó un punto de fijación en conflicto, donde '%s' estaría adjunto a sí mismo. Por favor comprueba tus puntos de fijación. Opción '%s' a ser fijado a '%s'"
|
||||
L["Vendored gray items for:"] = "Objetos grises vendidos por:"
|
||||
L["You don't have enough money to repair."] = "No tienes suficiente dinero para reparaciones."
|
||||
L["You must be at a vendor."] = "Debes estar cerca de un vendedor."
|
||||
L["Your items have been repaired for: "] = "Tus objetos han sido reparados por:"
|
||||
L["Your items have been repaired using guild bank funds for: "] = "Tus objetos han sido reparados con fondos del banco de hermandad por:"
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000Error de Lua recibido. Podrás ver el error cuando salgas de combate."
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "La opción que has cambiado se aplicará sólo para este personaje. Esta opción no se verá alterada al cambiar el perfil de usuario. Cambiar esta opción requiere que recargues tu Interfaz de Usuario."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = true;
|
||||
L["Are you sure you want to delete all your gray items?"] = "¿Estás seguro que quieres eliminar todos tus objetos grises?"
|
||||
L["Are you sure you want to disband the group?"] = "¿Estás seguro que quieres deshacer el grupo?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "¿Estás seguro que deseas restablecer todos los ajustes de este perfil?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "¿Estás seguro que quieres resetear cada fijador a su posición por defecto?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "Debido a la gran confusión causada por el nuevo sistema de auras he implementado un nuevo paso en el proceso de instalación, esto es opcional. Si quieres conservar la configuración actual de tus auras ve al último paso de la instalación y haz clic en terminar para que este mensaje no vuelva a ser mostrado. Si por alguna razón se vuelve a mostrar por favor reinicia el juego."
|
||||
L["Can't buy anymore slots!"] = "¡No puedes comprar más huecos!"
|
||||
L["Disable Warning"] = "Deshabilitar Advertencia"
|
||||
L["Discard"] = "Descartar"
|
||||
L["Do you enjoy the new ElvUI?"] = "¿Disfrutas del nuevo ElvUI?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "¿Juras no escribir a Soporte Técnico acerca de algo que no funciona sin antes deshabilitar la combinación addon/módulo primero?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI está cinco o mas revisiones desactualizado. Puedes descargar la versión más nueva de https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI está desactualizado. Puedes descargar la versión más nueva de https://github.com/ElvUI-WotLK/ElvUI/"
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI necesita realizar optimizaciones de base de datos por favor se paciente."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "Pasa tu ratón por encima de un botón de acción o de un botón del libro de hechizos para ligarlo. Pulsa escape o botón derecho para limpiar la asignación actual del botón de acción."
|
||||
L["I Swear"] = "Lo Juro"
|
||||
L["No, Revert Changes!"] = "¡No, Revierte los Cambios!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "Oh cielos, tienes ElvUI y Tukui habilitados al mismo tiempo. Elige un addon a deshabilitar"
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "Uno o más de los cambios que has hecho requieren una recarga de la interfaz."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "Uno o más de los cambios que has hecho afectaran a todos los personajes que usen este addon. Tendrás que recargar la intefaz de usuario para ver el cambio que has realizado."
|
||||
L["Save"] = "Guardar"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "El perfil que has intentado importar ya existe. Elige un nuevo nombre o acepta sobreescribir el perfil existente."
|
||||
L["Type /hellokitty to revert to old settings."] = "Escribe /hellokitty para revertir a las opciones antiguas."
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "Utilizando el diseño de sanador es altamente recomendado bajar el addon Clique si deseas tener la función de hacer clic para curar."
|
||||
L["Yes, Keep Changes!"] = "¡Sí, Mantén los cambios!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "Has cambiado la opción de Tema de Border Ligero. Tendrás que completar el proceso de instalación para quitar cualquier bug gráfico."
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "Has cambiado la escala de tu interfaz, sin embargo aún tienes el AutoEscalado activado en ElvUI. Pulsa aceptar si te gustaría desactivar el AutoEscalado."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "Has importado opciones que pueden requerir una recarga de la interfaz para tomar efecto. ¿Recargar ahora?"
|
||||
L["You must purchase a bank slot first!"] = "¡Debes comprar un hueco del banco primero!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "Contador"
|
||||
L["Item Level:"] = "Nivel de Objeto:"
|
||||
L["Talent Specialization:"] = "Especialización de Talentos:"
|
||||
L["Targeted By:"] = "Objetivo De:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "La opción de marcador de banda está disponible pulsando Escape -> Asignar teclas -> Recorrer hacia abajo hasta ElvUI y establecer la tecla para el marcador de banda."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "ElvUI tiene la posibilidad de cargar diferentes perfiles automáticamente al cambiar de especialización de talentos. Puedes activar esta función en la pestaña de perfiles."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "Para soporte técnico visítanos en https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "Si eliminas un marco de chat accidentalmente, siempre puedes ir a la configuración, pulsar instalar, ir a la parte del chat, y restaurarlo."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "Si has experimentado errores con ElvUI prueba a desactivar todos tus addons excepto ElvUI, recuerda que ElvUI remplaza por completo la interfaz, no puede haber addons que hagan lo mismo."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "El foco puede establecerse escribiendo /enfoque cuando tienes seleccionado al objetivo al cual quieres hacer foco. Es recomendable que hagas una macro para esto."
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "Para mover habilidades a las barras de acción mantener shift + arrastrar. Puedes cambiar la tecla de modificación desde el menú de opciones de la barra de acción."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "Para configurar que canales aparecen en el chat, haz clic con el botón derecho en la pestaña del chat y elige opciones."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "Puedes acceder a copiar y a las opciones del chat pasando el ratón sobre la esquina superior derecha del panel del chat y haciendo click en el botón que aparece."
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "Puedes ver la media de nivel de objeto de un objetivo manteniendo pulsado shift mientras pasas el ratón por encima de él. El iNvl aparecerá en la descripción emergente."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "Puedes establecer tus atajos rapidamente escribiendo /kb."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "Puedes acceder a la microbarra usando tu botón central del ratón sobre el minimapa. También puedes activarla desde las opciones de las barras de acción."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "Puedes usar el commando /resetui para restablecer todos tus fijadores. También puedes usar el comando para restablecer alguno en específico, /resetui <fijador>. PE: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = true;
|
||||
L["Ghost"] = "Fantasma"
|
||||
L["Offline"] = "Fuera de Línea"
|
||||
@@ -0,0 +1,346 @@
|
||||
-- Taiwanese localization file for zhTW.
|
||||
local AceLocale = LibStub:GetLibrary("AceLocale-3.0")
|
||||
local L = AceLocale:NewLocale("ElvUI", "zhTW")
|
||||
if not L then return end
|
||||
|
||||
--*_ADDON locales
|
||||
L["INCOMPATIBLE_ADDON"] = "插件 %s 與 ElvUI 的 %s 模組不相容。請停用不相容的插件,或停用相關的模組."
|
||||
|
||||
--*_MSG locales
|
||||
L["LOGIN_MSG"] = "歡迎使用%sElvUI |r %s%s|r 版, 請輸入/ec 進入設定介面. 如需技術支援請至 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
|
||||
--ActionBars
|
||||
L["Binding"] = "綁定"
|
||||
L["Key"] = "鍵"
|
||||
L["KEY_ALT"] = "A"
|
||||
L["KEY_CTRL"] = "C"
|
||||
L["KEY_DELETE"] = "Del"
|
||||
L["KEY_HOME"] = "Hm"
|
||||
L["KEY_INSERT"] = "Ins"
|
||||
L["KEY_MOUSEBUTTON"] = "M"
|
||||
L["KEY_MOUSEWHEELDOWN"] = "MwD"
|
||||
L["KEY_MOUSEWHEELUP"] = "MwU"
|
||||
L["KEY_NUMPAD"] = "N"
|
||||
L["KEY_PAGEDOWN"] = "PD"
|
||||
L["KEY_PAGEUP"] = "PU"
|
||||
L["KEY_SHIFT"] = "S"
|
||||
L["KEY_SPACE"] = "SpB"
|
||||
L["No bindings set."] = "未設定快捷綁定."
|
||||
L["Remove Bar %d Action Page"] = "移除第 %d 快捷列"
|
||||
L["Trigger"] = "觸發器"
|
||||
|
||||
--Bags
|
||||
L["Bank"] = "銀行"
|
||||
L["Hold Control + Right Click:"] = "按住 Ctrl 並按滑鼠右鍵:"
|
||||
L["Hold Shift + Drag:"] = "按住 Shift 並拖曳:"
|
||||
L["Purchase Bags"] = "購買背包"
|
||||
L["Reset Position"] = "重設位置"
|
||||
L["Sort Bags"] = "整理背包"
|
||||
L["Temporary Move"] = "移動背包"
|
||||
L["Toggle Bags"] = "開啟/關閉背包"
|
||||
L["Toggle Key"] = true;
|
||||
L["Vendor Grays"] = "出售灰色物品"
|
||||
|
||||
--Chat
|
||||
L["AFK"] = "暫離" --Also used in datatexts and tooltip
|
||||
L["BG"] = true;
|
||||
L["BGL"] = true;
|
||||
L["DND"] = "忙碌" --Also used in datatexts and tooltip
|
||||
L["G"] = "公會"
|
||||
L["Invalid Target"] = "無效的目標"
|
||||
L["O"] = "幹部"
|
||||
L["P"] = "隊伍"
|
||||
L["PL"] = "隊長"
|
||||
L["R"] = "團隊"
|
||||
L["RL"] = "團隊隊長"
|
||||
L["RW"] = "團隊警告"
|
||||
L["says"] = "說"
|
||||
L["whispers"] = "密語"
|
||||
L["yells"] = "大喊"
|
||||
|
||||
--DataTexts
|
||||
L["(Hold Shift) Memory Usage"] = "(按住Shift) 記憶體使用量"
|
||||
L["Avoidance Breakdown"] = "免傷統計"
|
||||
L["Character: "] = "角色: "
|
||||
L["Chest"] = "胸部"
|
||||
L["Combat"] = "戰鬥"
|
||||
L["Combat Time"] = true;
|
||||
L["Coords"] = true;
|
||||
L["copperabbrev"] = "|cffeda55f銅|r" --Also used in Bags
|
||||
L["Deficit:"] = "赤字:"
|
||||
L["DPS"] = "傷害輸出"
|
||||
L["Earned:"] = "賺取:"
|
||||
L["Friends List"] = "好友列表"
|
||||
L["Friends"] = "好友" --Also in Skins
|
||||
L["Gold"] = "金錢"
|
||||
L["goldabbrev"] = "|cffffd700金|r" --Also used in Bags
|
||||
L["Hit"] = "命中"
|
||||
L["Hold Shift + Right Click:"] = "按住 Shift 並按滑鼠右鍵"
|
||||
L["Home Latency:"] = "本機延遲:"
|
||||
L["HP"] = "生命值"
|
||||
L["HPS"] = "治療輸出"
|
||||
L["lvl"] = "等級"
|
||||
L["Miss Chance"] = true;
|
||||
L["Mitigation By Level: "] = "等級減傷: "
|
||||
L["No Guild"] = "沒有公會"
|
||||
L["Profit:"] = "利潤: "
|
||||
L["Reload UI"] = true;
|
||||
L["Reset Data: Hold Shift + Right Click"] = "重置數據: 按住 Shift + 右鍵點擊"
|
||||
L["Right Click: Reset CPU Usage"] = true;
|
||||
L["Saved Raid(s)"] = "已有進度的副本"
|
||||
L["Server: "] = "伺服器: "
|
||||
L["Session:"] = "本次登入:"
|
||||
L["silverabbrev"] = "|cffc7c7cf銀|r" --Also used in Bags
|
||||
L["SP"] = "法術能量"
|
||||
L["Spell/Heal Power"] = true;
|
||||
L["Spent:"] = "花費:"
|
||||
L["Stats For:"] = "統計:"
|
||||
L["System"] = true;
|
||||
L["Total CPU:"] = "CPU佔用"
|
||||
L["Total Memory:"] = "總記憶體:"
|
||||
L["Total: "] = "合計: "
|
||||
L["Unhittable:"] = "未命中:"
|
||||
L["Wintergrasp"] = true;
|
||||
|
||||
--DebugTools
|
||||
L["%s: %s tried to call the protected function '%s'."] = "%s: %s 嘗試調用保護函數'%s'."
|
||||
L["No locals to dump"] = "沒有本地檔案"
|
||||
|
||||
--Distributor
|
||||
L["%s is attempting to share his filters with you. Would you like to accept the request?"] = "%s 試圖與你分享過濾器設定. 你是否接受?"
|
||||
L["%s is attempting to share the profile %s with you. Would you like to accept the request?"] = "%s 試圖與你分享設定檔 %s. 你是否接受?"
|
||||
L["Data From: %s"] = "數據來源: %s"
|
||||
L["Filter download complete from %s, would you like to apply changes now?"] = "過濾器設定下載於 %s, 你是否現在變更?"
|
||||
L["Lord! It's a miracle! The download up and vanished like a fart in the wind! Try Again!"] = "天啊! 太奇葩啦! 下載消失了! 就像是在風中放了個屁... 再試一次吧!"
|
||||
L["Profile download complete from %s, but the profile %s already exists. Change the name or else it will overwrite the existing profile."] = "設定文件從 %s 下載完成, 但是設定文件 %s 已存在. 請更改名稱, 否則它會覆蓋你的現有設定檔."
|
||||
L["Profile download complete from %s, would you like to load the profile %s now?"] = "設定檔從 %s 下載完成, 你是否要加載設定檔 %s?"
|
||||
L["Profile request sent. Waiting for response from player."] = "已發送設定檔請求. 等待對方回應"
|
||||
L["Request was denied by user."] = "請求被對方拒絕."
|
||||
L["Your profile was successfully recieved by the player."] = "你的設定檔已被其他玩家成功接收."
|
||||
|
||||
--Install
|
||||
L["Aura Bars & Icons"] = "光環條和圖示"
|
||||
L["Auras Set"] = "光環樣式設定"
|
||||
L["Auras"] = "光環"
|
||||
L["Caster DPS"] = "法系輸出"
|
||||
L["Chat Set"] = "對話设置"
|
||||
L["Chat"] = "對話"
|
||||
L["Choose a theme layout you wish to use for your initial setup."] = "為你的個人設定選擇一個你喜歡的皮膚主題."
|
||||
L["Classic"] = "經典"
|
||||
L["Click the button below to resize your chat frames, unitframes, and reposition your actionbars."] = "點選下面的按鈕調整對話框、單位框架的尺寸, 以及移動快捷列位置."
|
||||
L["Config Mode:"] = "設定模式:"
|
||||
L["CVars Set"] = "參數設定"
|
||||
L["CVars"] = "參數"
|
||||
L["Dark"] = "黑暗"
|
||||
L["Disable"] = "停用"
|
||||
L["ElvUI Installation"] = "安裝 ElvUI"
|
||||
L["Finished"] = "設定完畢"
|
||||
L["Grid Size:"] = "網格尺寸:"
|
||||
L["Healer"] = "補師"
|
||||
L["High Resolution"] = "高解析度"
|
||||
L["high"] = "高"
|
||||
L["Icons Only"] = "圖示" --Also used in Bags
|
||||
L["If you have an icon or aurabar that you don't want to display simply hold down shift and right click the icon for it to disapear."] = "如果你有不想顯示的圖示或光環條, 你可以簡單的通過按住Shift + 右鍵點擊使它隱藏."
|
||||
L["Importance: |cff07D400High|r"] = "重要性: |cff07D400高|r"
|
||||
L["Importance: |cffD3CF00Medium|r"] = "重要性: |cffD3CF00中|r"
|
||||
L["Importance: |cffFF0000Low|r"] = "重要性: |cffFF0000低|r"
|
||||
L["Installation Complete"] = "安裝完畢"
|
||||
L["Layout Set"] = "版面配置設定"
|
||||
L["Layout"] = "介面佈局"
|
||||
L["Lock"] = "鎖定"
|
||||
L["Low Resolution"] = "低解析度"
|
||||
L["low"] = "低"
|
||||
L["Nudge"] = "微調"
|
||||
L["Physical DPS"] = "物理輸出"
|
||||
L["Please click the button below so you can setup variables and ReloadUI."] = "請按下方按鈕設定變數並重載介面."
|
||||
L["Please click the button below to setup your CVars."] = "請按下方按鈕設定參數."
|
||||
L["Please press the continue button to go onto the next step."] = "請按「繼續」按鈕,執行下一個步驟."
|
||||
L["Resolution Style Set"] = "解析度樣式設定"
|
||||
L["Resolution"] = "解析度"
|
||||
L["Select the type of aura system you want to use with ElvUI's unitframes. Set to Aura Bar & Icons to use both aura bars and icons, set to icons only to only see icons."] = "選擇在 ElvUI 單位框架中要使用的光環系統. 選擇光環條和圖示來同時使用兩者, 選擇圖示來僅使用圖示"
|
||||
L["Setup Chat"] = "設定對話視窗"
|
||||
L["Setup CVars"] = "設定參數"
|
||||
L["Skip Process"] = "略過"
|
||||
L["Sticky Frames"] = "框架依附"
|
||||
L["Tank"] = "坦克"
|
||||
L["The chat windows function the same as Blizzard standard chat windows, you can right click the tabs and drag them around, rename, etc. Please click the button below to setup your chat windows."] = "對話視窗與WOW 原始對話視窗的操作方式相同, 你可以拖拉、移動分頁或重新命名分頁. 請按下方按鈕以設定對話視窗."
|
||||
L["The in-game configuration menu can be accessed by typing the /ec command or by clicking the 'C' button on the minimap. Press the button below if you wish to skip the installation process."] = "若要進入內建設定選單, 請輸入/ec, 或者按一下小地圖旁的「C」按鈕.若要略過安裝程序, 請按下方按鈕."
|
||||
L["Theme Set"] = "主題設定"
|
||||
L["Theme Setup"] = "主題安裝"
|
||||
L["This install process will help you learn some of the features in ElvUI has to offer and also prepare your user interface for usage."] = "此安裝程序有助你瞭解ElvUI 部份功能, 並可協助你預先設定UI."
|
||||
L["This is completely optional."] = "此為選擇性功能."
|
||||
L["This part of the installation process sets up your chat windows names, positions and colors."] = "此安裝步驟將會設定對話視窗的名稱、位置和顏色."
|
||||
L["This part of the installation process sets up your World of Warcraft default options it is recommended you should do this step for everything to behave properly."] = "此安裝步驟將會設定 WOW 預設選項, 建議你執行此步驟, 以確保功能均可正常運作."
|
||||
L["This resolution doesn't require that you change settings for the UI to fit on your screen."] = "這個解析度不需要你改動任何設定以適應你的螢幕."
|
||||
L["This resolution requires that you change some settings to get everything to fit on your screen."] = "這個解析度需要你改變一些設定才能適應你的螢幕."
|
||||
L["This will change the layout of your unitframes and actionbars."] = "這將會改變你的單位框架和動作條的佈局"
|
||||
L["Trade"] = "拾取/交易"
|
||||
L["Welcome to ElvUI version %s!"] = "歡迎使用 ElvUI %s 版!"
|
||||
L["You are now finished with the installation process. If you are in need of technical support please visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "已完成安裝程序. 小提示: 若想開啟微型選單, 請在小地圖按滑鼠中鍵. 如果沒有中鍵按鈕, 請按住Shift鍵, 並在小地圖按滑鼠右鍵. 如需技術支援請至 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["You can always change fonts and colors of any element of ElvUI from the in-game configuration."] = "你可以在遊戲內的設定選項內更改ElvUI的字體、顏色等設定."
|
||||
L["You can now choose what layout you wish to use based on your combat role."] = "你現在可以根據你的戰鬥角色選擇合適的佈局."
|
||||
L["You may need to further alter these settings depending how low you resolution is."] = "根據你的解析度你可能需要改動這些設定."
|
||||
L["Your current resolution is %s, this is considered a %s resolution."] = "你當前的解析度是%s, 這被認為是個%s 解析度."
|
||||
|
||||
--Misc
|
||||
L["ABOVE_THREAT_FORMAT"] = "%s: %.0f%% [%.0f%% 以上 |cff%02x%02x%02x%s|r]"
|
||||
L["Bars"] = "條" --Also used in UnitFrames
|
||||
L["Calendar"] = "日曆"
|
||||
L["Can't Roll"] = "無法需求此裝備"
|
||||
L["Disband Group"] = "解散隊伍"
|
||||
L["Empty Slot"] = true;
|
||||
L["Enable"] = "啟用" --Doesn't fit a section since it's used a lot of places
|
||||
L["Experience"] = "經驗/聲望條"
|
||||
L["Farm Mode"] = true;
|
||||
L["Fishy Loot"] = "貪婪"
|
||||
L["Left Click:"] = "滑鼠左鍵:" --layout\layout.lua
|
||||
L["Raid Menu"] = "團隊選單"
|
||||
L["Remaining:"] = "剩餘:"
|
||||
L["Rested:"] = "休息:"
|
||||
L["Right Click:"] = "滑鼠右鍵:" --layout\layout.lua
|
||||
L["Show BG Texts"] = "顯示戰場資訊文字" --layout\layout.lua
|
||||
L["Toggle Chat Frame"] = "開關對話框架" --layout\layout.lua
|
||||
L["Toggle Configuration"] = "開啟/關閉設定" --layout\layout.lua
|
||||
L["XP:"] = "經驗:"
|
||||
L["You don't have permission to mark targets."] = "你沒有標記目標的權限."
|
||||
|
||||
--Movers
|
||||
L["Arena Frames"] = "競技場框架" --Also used in UnitFrames
|
||||
L["Bag Mover (Grow Down)"] = "背包錨點 (向下增長)"
|
||||
L["Bag Mover (Grow Up)"] = "背包錨點 (向上增長)"
|
||||
L["Bag Mover"] = "背包錨點"
|
||||
L["Bags"] = "背包" --Also in DataTexts
|
||||
L["Bank Mover (Grow Down)"] = "銀行錨點 (向下增長)"
|
||||
L["Bank Mover (Grow Up)"] = "銀行錨點 (向上增長)"
|
||||
L["Bar "] = "快捷列 " --Also in ActionBars
|
||||
L["BNet Frame"] = "戰網提示資訊"
|
||||
L["Boss Frames"] = "首領框架" --Also used in UnitFrames
|
||||
L["Classbar"] = "職業特有條"
|
||||
L["Experience Bar"] = "經驗條"
|
||||
L["Focus Castbar"] = "焦點目標施法條"
|
||||
L["Focus Frame"] = "焦點目標框架" --Also used in UnitFrames
|
||||
L["FocusTarget Frame"] = "焦點目標的目標框架" --Also used in UnitFrames
|
||||
L["GM Ticket Frame"] = "GM 對話框"
|
||||
L["Left Chat"] = "左側對話框"
|
||||
L["Loot / Alert Frames"] = "拾取 / 提醒框架"
|
||||
L["Loot Frame"] = "拾取框架"
|
||||
L["MA Frames"] = "主助理框架"
|
||||
L["Micro Bar"] = "微型系統菜單" --Also in ActionBars
|
||||
L["Minimap"] = "小地圖"
|
||||
L["MirrorTimer"] = "鏡像計時器"
|
||||
L["MT Frames"] = "主坦克框架"
|
||||
L["Party Frames"] = "隊伍框架" --Also used in UnitFrames
|
||||
L["Pet Bar"] = "寵物快捷列" --Also in ActionBars
|
||||
L["Pet Castbar"] = "寵物施法條"
|
||||
L["Pet Frame"] = "寵物框架" --Also used in UnitFrames
|
||||
L["PetTarget Frame"] = "寵物目標框架" --Also used in UnitFrames
|
||||
L["Player Buffs"] = "玩家增益"
|
||||
L["Player Castbar"] = "玩家施法條"
|
||||
L["Player Debuffs"] = "玩家減益"
|
||||
L["Player Frame"] = "玩家框架" --Also used in UnitFrames
|
||||
L["Player Powerbar"] = "玩家能量條"
|
||||
L["PvP"] = true;
|
||||
L["Raid Frames"] = "團隊框架"
|
||||
L["Raid Pet Frames"] = "團隊寵物框架"
|
||||
L["Raid-40 Frames"] = "40人團隊框架"
|
||||
L["Reputation Bar"] = "聲望條"
|
||||
L["Right Chat"] = "右側對話框"
|
||||
L["Stance Bar"] = "姿態列" --Also in ActionBars
|
||||
L["Target Castbar"] = "目標施法條"
|
||||
L["Target Frame"] = "目標框架" --Also used in UnitFrames
|
||||
L["Target Powerbar"] = "目標能量條"
|
||||
L["TargetTarget Frame"] = "目標的目標框架" --Also used in UnitFrames
|
||||
L["TargetTargetTarget Frame"] = "目標的目標的目標框架"
|
||||
L["Time Manager Frame"] = true;
|
||||
L["Tooltip"] = "浮動提示"
|
||||
L["Vehicle Seat Frame"] = "載具座位框"
|
||||
L["Watch Frame"] = true;
|
||||
L["Weapons"] = true;
|
||||
L["DESC_MOVERCONFIG"] = "Movers unlocked. Move them now and click Lock when you are done./nOptions:/nShift + RightClick - Hides mover temporarily./nCtrl + RightClick - Resets mover position to default."
|
||||
|
||||
--Plugin Installer
|
||||
L["ElvUI Plugin Installation"] = "ElvUI 插件安裝"
|
||||
L["In Progress"] = "進行中"
|
||||
L["List of installations in queue:"] = "即將安裝的列表"
|
||||
L["Pending"] = "等待中"
|
||||
L["Steps"] = "步驟"
|
||||
|
||||
--Prints
|
||||
L[" |cff00ff00bound to |r"] = " |cff00ff00綁定到 |r"
|
||||
L["%s frame(s) has a conflicting anchor point, please change either the buff or debuff anchor point so they are not attached to each other. Forcing the debuffs to be attached to the main unitframe until fixed."] = " %s 個框架錨點衝突, 請移動buff或者debuff錨點讓他們彼此不依附. 暫時強制debuff依附到主框架."
|
||||
L["All keybindings cleared for |cff00ff00%s|r."] = "取消|cff00ff00%s|r 所有綁定的快捷鍵."
|
||||
L["Already Running.. Bailing Out!"] = "正在運行"
|
||||
L["Battleground datatexts temporarily hidden, to show type /bgstats or right click the 'C' icon near the minimap."] = "戰場資訊暫時隱藏, 你可以通過輸入/bgstats 或右鍵點擊小地圖旁「C」按鈕顯示."
|
||||
L["Battleground datatexts will now show again if you are inside a battleground."] = "當你處於戰場時戰場資訊將再次顯示."
|
||||
L["Binds Discarded"] = "取消綁定"
|
||||
L["Binds Saved"] = "儲存綁定"
|
||||
L["Confused.. Try Again!"] = "請再試一次!"
|
||||
L["No gray items to delete."] = "沒有可刪除的灰色物品."
|
||||
L["The spell '%s' has been added to the Blacklist unitframe aura filter."] = "法術'%s'已經被添加到單位框架的光環過濾器中."
|
||||
L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."] = "此設定造成了錨點衝突, '%s' 框架會依附於自己, 請檢查你的錨點. 將 '%s' 依附於 '%s'."
|
||||
L["Vendored gray items for:"] = "已售出灰色物品,共得:"
|
||||
L["You don't have enough money to repair."] = "沒有足夠的資金來修復."
|
||||
L["You must be at a vendor."] = "你必須與商人對話."
|
||||
L["Your items have been repaired for: "] = "裝備已修復,共支出:"
|
||||
L["Your items have been repaired using guild bank funds for: "] = "已使用公會資金修復裝備,共支出:"
|
||||
L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."] = "|cFFE30000LUA錯誤已接收, 你可以在脫離戰鬥後檢查.|r"
|
||||
|
||||
--Static Popups
|
||||
L["A setting you have changed will change an option for this character only. This setting that you have changed will be uneffected by changing user profiles. Changing this setting requires that you reload your User Interface."] = "你所做的改動只會影響到使用這個插件的本角色, 你需要重新加載介面才能使改動生效."
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on NamePlates. Are you sure?"] = true
|
||||
L["Accepting this will reset your Filter Priority lists for all auras on UnitFrames. Are you sure?"] = true
|
||||
L["Are you sure you want to apply this font to all ElvUI elements?"] = "你確定要將此字型應用到所有 ElvUI 元素嗎?"
|
||||
L["Are you sure you want to delete all your gray items?"] = "是否確定要刪除所有灰色物品?"
|
||||
L["Are you sure you want to disband the group?"] = "確定要解散隊伍?"
|
||||
L["Are you sure you want to reset all the settings on this profile?"] = "確定需要重置這個設定檔中的所有設定?"
|
||||
L["Are you sure you want to reset every mover back to it's default position?"] = "確定需要重置所有框架至預設位置?"
|
||||
L["Because of the mass confusion caused by the new aura system I've implemented a new step to the installation process. This is optional. If you like how your auras are setup go to the last step and click finished to not be prompted again. If for some reason you are prompted repeatedly please restart your game."] = "因為新的光環系統造成了大量的混亂因此我導入了一個新的步驟到安裝過程中. 這是可選的, 如果你喜歡你現在的設定請跳到最後一個步驟並點擊「完成」將不會再提示. 如果由於某些原因反復提示, 請重新開啟遊戲."
|
||||
L["Can't buy anymore slots!"] = "無法再購買更多銀行欄位!"
|
||||
L["Disable Warning"] = "停用警告"
|
||||
L["Discard"] = "取消"
|
||||
L["Do you enjoy the new ElvUI?"] = "你享受新版的 ElvUI嗎?"
|
||||
L["Do you swear not to post in technical support about something not working without first disabling the addon/module combination first?"] = "你發誓在你沒停用其他插件或是模組前不會到技術支援發文詢問某些功能失效嗎?"
|
||||
L["ElvUI is five or more revisions out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI 以過期超過5個版本. 你可以在 https://github.com/ElvUI-WotLK/ElvUI/ 下載到最新的版本."
|
||||
L["ElvUI is out of date. You can download the newest version from https://github.com/ElvUI-WotLK/ElvUI/"] = "ElvUI 以過期. 你可以在 https://github.com/ElvUI-WotLK/ElvUI/ 下載到最新的版本."
|
||||
L["ElvUI needs to perform database optimizations please be patient."] = "ElvUI 需要進行資料庫優化, 請稍待."
|
||||
L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the escape key or right click to clear the current actionbutton's keybinding."] = "移動滑鼠到快捷列或技能書按鈕上綁定快捷鍵.按ESC或滑鼠右鍵取消目前快捷鍵."
|
||||
L["I Swear"] = "我承諾"
|
||||
L["No, Revert Changes!"] = "不, 回復修改!"
|
||||
L["Oh lord, you have got ElvUI and Tukui both enabled at the same time. Select an addon to disable."] = "喔 拜託,你不能同時使用 Elvui 和 Tukui, 請選擇一個停用."
|
||||
L["One or more of the changes you have made require a ReloadUI."] = "已變更一或多個設定, 需重載介面."
|
||||
L["One or more of the changes you have made will effect all characters using this addon. You will have to reload the user interface to see the changes you have made."] = "你所做的改動可能會影響到使用這個插件的所有角色, 你需要重新加載介面才能使改動生效."
|
||||
L["Save"] = "儲存"
|
||||
L["The profile you tried to import already exists. Choose a new name or accept to overwrite the existing profile."] = "你嘗試導入的設定檔已存在. 選擇一個新名稱或是允許覆蓋原有設定檔"
|
||||
L["Type /hellokitty to revert to old settings."] = "輸入 /hellokitty 來回復舊設定"
|
||||
L["Using the healer layout it is highly recommended you download the addon Clique if you wish to have the click-to-heal function."] = "使用治療者佈局時建議你下載 Clique 插件, 以擁有點擊血條治療的功能"
|
||||
L["Yes, Keep Changes!"] = "是的, 保留變更!"
|
||||
L["You have changed the Thin Border Theme option. You will have to complete the installation process to remove any graphical bugs."] = "你選擇了細邊框主題選項. 你必須完成安裝程序來移除任何圖像錯誤"
|
||||
L["You have changed your UIScale, however you still have the AutoScale option enabled in ElvUI. Press accept if you would like to disable the Auto Scale option."] = "你改變了介面縮放比例, 然而ElvUI的自動縮放選項是開啟的. 點擊接受以關閉ElvUI的自動縮放."
|
||||
L["You have imported settings which may require a UI reload to take effect. Reload now?"] = "你導入的設定可能需要重新載入UI才能生效. 現在重新載入嗎?"
|
||||
L["You must purchase a bank slot first!"] = "你必需先購買一個銀行背包欄位!"
|
||||
|
||||
--Tooltip
|
||||
L["Count"] = "計數"
|
||||
L["Item Level:"] = "物品等級:"
|
||||
L["Talent Specialization:"] = "天賦專精:"
|
||||
L["Targeted By:"] = "同目標的有:"
|
||||
|
||||
--Tutorials
|
||||
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."] = "你可以通過按ESC鍵-> 按鍵設定, 滾動到ElvUI設定下方設定一個快速標記的快捷鍵."
|
||||
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."] = "ElvUI 可以根據你所使用的天賦自動套用不同的裝備組. 你可以在設定檔中啟用此功能."
|
||||
L["For technical support visit us at https://github.com/ElvUI-WotLK/ElvUI"] = "如需技術支援請至 https://github.com/ElvUI-WotLK/ElvUI"
|
||||
L["If you accidently remove a chat frame you can always go the in-game configuration menu, press install, go to the chat portion and reset them."] = "如果你不慎移除了對話框, 你可以重新安裝一次重置他們."
|
||||
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."] = "如果你使用 ElvUI 時遇到問題, 請嘗試停用除了ElvUI之外的插件. 請記住 ElvUI 是一套全套的 UI 替換插件, 你不能同時使用不同的插件來完成同一件事."
|
||||
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."] = "你可以使用 /focus 指令設定目前目標為焦點目標. 建議你可以寫一個聚集來做這件事"
|
||||
L["To move abilities on the actionbars by default hold shift + drag. You can change the modifier key from the actionbar options menu."] = "你可以通過按住Shift拖動技能條中的按鍵. 你可以在Blizzard的快捷列設定中更改按鍵."
|
||||
L["To setup which channels appear in which chat frame, right click the chat tab and go to settings."] = "你可以通過右鍵點擊對話框標籤欄設定你需要在對話框內顯示的頻道."
|
||||
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."] = "你可以將滑鼠滑到對話框右上角並且點擊左鍵或右鍵來開啟對話複製或是對話指令視窗"
|
||||
L["You can see someones average item level of their gear by holding shift and mousing over them. It should appear inside the tooltip."] = "你可以透過按住Shift並將滑鼠滑過目標來看到目標的平均裝等, 結果將顯示在你的滑鼠提示框內."
|
||||
L["You can set your keybinds quickly by typing /kb."] = "你可以通過輸入/kb 快速綁定按鍵."
|
||||
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."] = "你可以通過滑鼠中鍵點擊小地圖或在快捷列設定內選擇打開微型系統欄."
|
||||
L["You can use the /resetui command to reset all of your movers. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"] = "你可以使用 /resetui 命令來重置所有框架的位置. 你也可以通過命令 /resetui <框架名稱> 單獨重置某個框架.\n例如: /resetui Player Frame"
|
||||
|
||||
--UnitFrames
|
||||
L["Dead"] = "死亡"
|
||||
L["Ghost"] = "鬼魂"
|
||||
L["Offline"] = "離線"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user