init
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,169 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
||||
|
||||
-- Default settings
|
||||
local default = {
|
||||
controlledChildren = {},
|
||||
anchorPoint = "CENTER",
|
||||
anchorFrameType = "SCREEN",
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
frameStrata = 1,
|
||||
border = false,
|
||||
borderColor = { 0, 0, 0, 1 },
|
||||
backdropColor = { 1, 1, 1, 0.5 },
|
||||
borderEdge = "Square Full White",
|
||||
borderOffset = 4,
|
||||
borderInset = 1,
|
||||
borderSize = 2,
|
||||
borderBackdrop = "Blizzard Tooltip",
|
||||
scale = 1,
|
||||
};
|
||||
|
||||
-- Called when first creating a new region/display
|
||||
local function create(parent)
|
||||
-- Main region
|
||||
local region = CreateFrame("FRAME", nil, parent);
|
||||
region:SetMovable(true);
|
||||
region:SetWidth(2);
|
||||
region:SetHeight(2);
|
||||
|
||||
-- Border region
|
||||
local border = CreateFrame("frame", nil, region);
|
||||
region.border = border;
|
||||
|
||||
WeakAuras.regionPrototype.create(region);
|
||||
|
||||
return region;
|
||||
end
|
||||
|
||||
-- Calculate bounding box
|
||||
local function getRect(data, region)
|
||||
-- Temp variables
|
||||
local blx, bly, trx, try;
|
||||
blx, bly = data.xOffset or 0, data.yOffset or 0;
|
||||
|
||||
local width = data.width or (region and region.width)
|
||||
local height = data.height or (region and region.height)
|
||||
|
||||
if width == nil or height == nil then
|
||||
return blx, bly, blx, bly;
|
||||
end
|
||||
|
||||
-- Calc bounding box
|
||||
if(data.selfPoint:find("LEFT")) then
|
||||
trx = blx + width;
|
||||
elseif(data.selfPoint:find("RIGHT")) then
|
||||
trx = blx;
|
||||
blx = blx - width;
|
||||
else
|
||||
blx = blx - (width/2);
|
||||
trx = blx + width;
|
||||
end
|
||||
if(data.selfPoint:find("BOTTOM")) then
|
||||
try = bly + height;
|
||||
elseif(data.selfPoint:find("TOP")) then
|
||||
try = bly;
|
||||
bly = bly - height;
|
||||
else
|
||||
bly = bly - (height/2);
|
||||
try = bly + height;
|
||||
end
|
||||
|
||||
-- Return data
|
||||
return blx, bly, trx, try;
|
||||
end
|
||||
|
||||
-- Modify a given region/display
|
||||
local function modify(parent, region, data)
|
||||
data.selfPoint = "BOTTOMLEFT";
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
-- Localize
|
||||
local border = region.border;
|
||||
|
||||
-- Scale
|
||||
region:SetScale(data.scale and data.scale > 0 and data.scale or 1)
|
||||
|
||||
-- Get overall bounding box
|
||||
local leftest, rightest, lowest, highest = 0, 0, 0, 0;
|
||||
local minLevel
|
||||
for index, childId in ipairs(data.controlledChildren) do
|
||||
local childData = WeakAuras.GetData(childId);
|
||||
local childRegion = WeakAuras.GetRegion(childId)
|
||||
if(childData) then
|
||||
local blx, bly, trx, try = getRect(childData, childRegion);
|
||||
leftest = math.min(leftest, blx);
|
||||
rightest = math.max(rightest, trx);
|
||||
lowest = math.min(lowest, bly);
|
||||
highest = math.max(highest, try);
|
||||
local frameLevel = childRegion and childRegion:GetFrameLevel()
|
||||
if frameLevel then
|
||||
minLevel = minLevel and math.min(minLevel, frameLevel) or frameLevel
|
||||
end
|
||||
end
|
||||
end
|
||||
region.blx = leftest;
|
||||
region.bly = lowest;
|
||||
region.trx = rightest;
|
||||
region.try = highest;
|
||||
|
||||
-- Adjust frame-level sorting
|
||||
WeakAuras.FixGroupChildrenOrderForGroup(data);
|
||||
|
||||
-- Control children (does not happen with "group")
|
||||
function region:UpdateBorder(childRegion)
|
||||
local border = region.border;
|
||||
-- Apply border settings
|
||||
if data.border then
|
||||
-- Initial visibility (of child that originated UpdateBorder(...))
|
||||
local childVisible = childRegion and childRegion.toShow or false;
|
||||
|
||||
-- Scan children for visibility
|
||||
if not childVisible then
|
||||
for index, childId in ipairs(data.controlledChildren) do
|
||||
local childRegion = WeakAuras.regions[childId] and WeakAuras.regions[childId].region;
|
||||
if childRegion and childRegion.toShow then
|
||||
childVisible = true;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Show border if child is visible
|
||||
if childVisible then
|
||||
border:SetBackdrop({
|
||||
edgeFile = data.borderEdge ~= "None" and SharedMedia:Fetch("border", data.borderEdge) or "",
|
||||
edgeSize = data.borderSize,
|
||||
bgFile = data.borderBackdrop ~= "None" and SharedMedia:Fetch("background", data.borderBackdrop) or "",
|
||||
insets = {
|
||||
left = data.borderInset,
|
||||
right = data.borderInset,
|
||||
top = data.borderInset,
|
||||
bottom = data.borderInset,
|
||||
},
|
||||
});
|
||||
border:SetBackdropBorderColor(data.borderColor[1], data.borderColor[2], data.borderColor[3], data.borderColor[4]);
|
||||
border:SetBackdropColor(data.backdropColor[1], data.backdropColor[2], data.backdropColor[3], data.backdropColor[4]);
|
||||
|
||||
border:ClearAllPoints();
|
||||
border:SetPoint("bottomleft", region, "bottomleft", leftest-data.borderOffset, lowest-data.borderOffset);
|
||||
border:SetPoint("topright", region, "topright", rightest+data.borderOffset, highest+data.borderOffset);
|
||||
if minLevel then
|
||||
border:SetFrameLevel(minLevel - 1)
|
||||
end
|
||||
border:Show();
|
||||
else
|
||||
border:Hide();
|
||||
end
|
||||
else
|
||||
border:Hide();
|
||||
end
|
||||
end
|
||||
region:UpdateBorder()
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
end
|
||||
|
||||
-- Register new region type with WeakAuras
|
||||
WeakAuras.RegisterRegionType("group", create, modify, default);
|
||||
@@ -0,0 +1,538 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
||||
local L = WeakAuras.L
|
||||
local MSQ, MSQ_Version = LibStub("Masque", true);
|
||||
if MSQ then
|
||||
if MSQ_Version <= 80100 then
|
||||
MSQ = nil
|
||||
print(print(WeakAuras.printPrefix .. L["Please upgrade your Masque version"]))
|
||||
else
|
||||
MSQ:AddType("WA_Aura", {"Icon", "Cooldown"})
|
||||
end
|
||||
end
|
||||
|
||||
-- WoW API
|
||||
local _G = _G
|
||||
|
||||
local default = {
|
||||
icon = true,
|
||||
desaturate = false,
|
||||
auto = true,
|
||||
inverse = false,
|
||||
width = 64,
|
||||
height = 64,
|
||||
color = {1, 1, 1, 1},
|
||||
selfPoint = "CENTER",
|
||||
anchorPoint = "CENTER",
|
||||
anchorFrameType = "SCREEN",
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
zoom = 0,
|
||||
keepAspectRatio = false,
|
||||
frameStrata = 1,
|
||||
|
||||
cooldownEdge = false,
|
||||
subRegions = {}
|
||||
};
|
||||
|
||||
WeakAuras.regionPrototype.AddAlphaToDefault(default);
|
||||
|
||||
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
||||
|
||||
local properties = {
|
||||
desaturate = {
|
||||
display = L["Desaturate"],
|
||||
setter = "SetDesaturated",
|
||||
type = "bool",
|
||||
},
|
||||
width = {
|
||||
display = L["Width"],
|
||||
setter = "SetRegionWidth",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenWidth,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
height = {
|
||||
display = L["Height"],
|
||||
setter = "SetRegionHeight",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenHeight,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
color = {
|
||||
display = L["Color"],
|
||||
setter = "Color",
|
||||
type = "color"
|
||||
},
|
||||
inverse = {
|
||||
display = L["Inverse"],
|
||||
setter = "SetInverse",
|
||||
type = "bool"
|
||||
},
|
||||
cooldownEdge = {
|
||||
display = { L["Cooldown"], L["Edge"]},
|
||||
setter = "SetCooldownEdge",
|
||||
type = "bool",
|
||||
},
|
||||
zoom = {
|
||||
display = L["Zoom"],
|
||||
setter = "SetZoom",
|
||||
type = "number",
|
||||
min = 0,
|
||||
max = 1,
|
||||
step = 0.01,
|
||||
default = 0,
|
||||
isPercent = true
|
||||
},
|
||||
};
|
||||
|
||||
WeakAuras.regionPrototype.AddProperties(properties, default);
|
||||
|
||||
local function GetTexCoord(region, texWidth, aspectRatio)
|
||||
region.currentCoord = region.currentCoord or {}
|
||||
local usesMasque = false
|
||||
if region.MSQGroup then
|
||||
local db = region.MSQGroup.db
|
||||
if db and not db.Disabled then
|
||||
usesMasque = true
|
||||
region.currentCoord[1], region.currentCoord[2], region.currentCoord[3], region.currentCoord[4], region.currentCoord[5], region.currentCoord[6], region.currentCoord[7], region.currentCoord[8] = region.icon:GetTexCoord()
|
||||
end
|
||||
end
|
||||
if (not usesMasque) then
|
||||
region.currentCoord[1], region.currentCoord[2], region.currentCoord[3], region.currentCoord[4], region.currentCoord[5], region.currentCoord[6], region.currentCoord[7], region.currentCoord[8] = 0, 0, 0, 1, 1, 0, 1, 1;
|
||||
end
|
||||
|
||||
local xRatio = aspectRatio < 1 and aspectRatio or 1;
|
||||
local yRatio = aspectRatio > 1 and 1 / aspectRatio or 1;
|
||||
for i, coord in ipairs(region.currentCoord) do
|
||||
local aspectRatio = (i % 2 == 1) and xRatio or yRatio;
|
||||
region.currentCoord[i] = (coord - 0.5) * texWidth * aspectRatio + 0.5;
|
||||
end
|
||||
|
||||
return unpack(region.currentCoord)
|
||||
end
|
||||
|
||||
local function AnchorSubRegion(self, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset)
|
||||
if anchorType == "area" then
|
||||
WeakAuras.regionPrototype.AnchorSubRegion(selfPoint == "region" and self or self.icon, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset)
|
||||
else
|
||||
subRegion:ClearAllPoints()
|
||||
anchorPoint = anchorPoint or "CENTER"
|
||||
local anchorRegion = self.icon
|
||||
if anchorPoint:sub(1, 6) == "INNER_" then
|
||||
if not self.inner then
|
||||
self.inner = CreateFrame("FRAME", nil, self)
|
||||
self.inner:SetPoint("CENTER")
|
||||
self.UpdateInnerOuterSize()
|
||||
end
|
||||
anchorRegion = self.inner
|
||||
anchorPoint = anchorPoint:sub(7)
|
||||
elseif anchorPoint:sub(1, 6) == "OUTER_" then
|
||||
if not self.outer then
|
||||
self.outer = CreateFrame("FRAME", nil, self)
|
||||
self.outer:SetPoint("CENTER")
|
||||
self.UpdateInnerOuterSize()
|
||||
end
|
||||
anchorRegion = self.outer
|
||||
anchorPoint = anchorPoint:sub(7)
|
||||
end
|
||||
anchorXOffset = anchorXOffset or 0
|
||||
anchorYOffset = anchorYOffset or 0
|
||||
|
||||
if not WeakAuras.point_types[selfPoint] then
|
||||
selfPoint = "CENTER"
|
||||
end
|
||||
|
||||
if not WeakAuras.point_types[anchorPoint] then
|
||||
anchorPoint = "CENTER"
|
||||
end
|
||||
|
||||
subRegion:SetPoint(selfPoint, anchorRegion, anchorPoint, anchorXOffset, anchorYOffset)
|
||||
end
|
||||
end
|
||||
|
||||
local function create(parent, data)
|
||||
local font = "GameFontHighlight";
|
||||
|
||||
local region = CreateFrame("FRAME", nil, parent);
|
||||
region:SetMovable(true);
|
||||
region:SetResizable(true);
|
||||
region:SetMinResize(1, 1);
|
||||
|
||||
function region.UpdateInnerOuterSize()
|
||||
local width = region.width * math.abs(region.scalex);
|
||||
local height = region.height * math.abs(region.scaley);
|
||||
|
||||
local iconWidth
|
||||
local iconHeight
|
||||
|
||||
if MSQ then
|
||||
iconWidth = region.button:GetWidth()
|
||||
iconHeight = region.button:GetHeight()
|
||||
else
|
||||
iconWidth = region:GetWidth()
|
||||
iconHeight = region:GetHeight()
|
||||
end
|
||||
|
||||
if region.inner then
|
||||
region.inner:SetSize(iconWidth - 0.2 * width, iconHeight - 0.2 * height)
|
||||
end
|
||||
if region.outer then
|
||||
region.outer:SetSize(iconWidth + 0.1 * width, iconHeight + 0.1 * height)
|
||||
end
|
||||
end
|
||||
|
||||
local button
|
||||
if MSQ then
|
||||
button = CreateFrame("Button", nil, region)
|
||||
button.data = data
|
||||
region.button = button;
|
||||
button:EnableMouse(false);
|
||||
button:Disable();
|
||||
button:SetAllPoints();
|
||||
end
|
||||
|
||||
local icon = region:CreateTexture(nil, "BACKGROUND");
|
||||
if MSQ then
|
||||
icon:SetAllPoints(button);
|
||||
button:SetScript("OnSizeChanged", region.UpdateInnerOuterSize);
|
||||
else
|
||||
icon:SetAllPoints(region);
|
||||
region:SetScript("OnSizeChanged", region.UpdateInnerOuterSize);
|
||||
end
|
||||
region.icon = icon;
|
||||
icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark");
|
||||
|
||||
--This section creates a unique frame id for the cooldown frame so that it can be created with a global reference
|
||||
--The reason is so that WeakAuras cooldown frames can interact properly with OmniCC (i.e., put on its blacklist for timer overlays)
|
||||
local id = data.id;
|
||||
local frameId = id:lower():gsub(" ", "_");
|
||||
if(_G["WeakAurasCooldown"..frameId]) then
|
||||
local baseFrameId = frameId;
|
||||
local num = 2;
|
||||
while(_G["WeakAurasCooldown"..frameId]) do
|
||||
frameId = baseFrameId..num;
|
||||
num = num + 1;
|
||||
end
|
||||
end
|
||||
region.frameId = frameId;
|
||||
|
||||
local cooldown = CreateFrame("COOLDOWN", "WeakAurasCooldown"..frameId, region, "CooldownFrameTemplate");
|
||||
region.cooldown = cooldown;
|
||||
cooldown:SetAllPoints(icon);
|
||||
|
||||
region.values = {};
|
||||
|
||||
|
||||
local SetFrameLevel = region.SetFrameLevel;
|
||||
|
||||
function region.SetFrameLevel(self, level)
|
||||
SetFrameLevel(region, level);
|
||||
cooldown:SetFrameLevel(level);
|
||||
if button then
|
||||
button:SetFrameLevel(level);
|
||||
end
|
||||
end
|
||||
|
||||
WeakAuras.regionPrototype.create(region);
|
||||
|
||||
region.AnchorSubRegion = AnchorSubRegion
|
||||
|
||||
return region;
|
||||
end
|
||||
|
||||
local function modify(parent, region, data)
|
||||
-- Legacy members stacks and text2
|
||||
region.stacks = nil
|
||||
region.text2 = nil
|
||||
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
|
||||
local button, icon, cooldown = region.button, region.icon, region.cooldown;
|
||||
|
||||
region.useAuto = data.auto and WeakAuras.CanHaveAuto(data);
|
||||
|
||||
if MSQ then
|
||||
local masqueId = data.id:lower():gsub(" ", "_");
|
||||
if region.masqueId ~= masqueId then
|
||||
region.masqueId = masqueId
|
||||
region.MSQGroup = MSQ:Group("WeakAuras", region.masqueId, data.uid);
|
||||
region.MSQGroup:SetName(data.id)
|
||||
region.MSQGroup:AddButton(button, {Icon = icon, Cooldown = cooldown}, "WA_Aura", true);
|
||||
button.data = data
|
||||
end
|
||||
end
|
||||
|
||||
function region:UpdateSize()
|
||||
local width = region.width * math.abs(region.scalex);
|
||||
local height = region.height * math.abs(region.scaley);
|
||||
region:SetWidth(width);
|
||||
region:SetHeight(height);
|
||||
if MSQ then
|
||||
button:SetWidth(width);
|
||||
button:SetHeight(height);
|
||||
button:SetAllPoints();
|
||||
end
|
||||
region:UpdateTexCoords();
|
||||
end
|
||||
|
||||
function region:UpdateTexCoords()
|
||||
local mirror_h = region.scalex < 0;
|
||||
local mirror_v = region.scaley < 0;
|
||||
|
||||
local texWidth = 1 - 0.5 * region.zoom;
|
||||
local aspectRatio
|
||||
if not region.keepAspectRatio then
|
||||
aspectRatio = 1;
|
||||
else
|
||||
local width = region.width * math.abs(region.scalex);
|
||||
local height = region.height * math.abs(region.scaley);
|
||||
|
||||
if width == 0 or height == 0 then
|
||||
aspectRatio = 1;
|
||||
else
|
||||
aspectRatio = width / height;
|
||||
end
|
||||
end
|
||||
|
||||
if region.MSQGroup then
|
||||
region.MSQGroup:RemoveButton(button)
|
||||
region.MSQGroup:AddButton(button, {Icon = icon, Cooldown = cooldown}, "WA_Aura", true)
|
||||
end
|
||||
|
||||
local ulx, uly, llx, lly, urx, ury, lrx, lry = GetTexCoord(region, texWidth, aspectRatio)
|
||||
|
||||
if(mirror_h) then
|
||||
if(mirror_v) then
|
||||
icon:SetTexCoord(lrx, lry, urx, ury, llx, lly, ulx, uly)
|
||||
else
|
||||
icon:SetTexCoord(urx, ury, lrx, lry, ulx, uly, llx, lly)
|
||||
end
|
||||
else
|
||||
if(mirror_v) then
|
||||
icon:SetTexCoord(llx, lly, ulx, uly, lrx, lry, urx, ury)
|
||||
else
|
||||
icon:SetTexCoord(ulx, uly, llx, lly, urx, ury, lrx, lry)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
region.width = data.width;
|
||||
region.height = data.height;
|
||||
region.scalex = 1;
|
||||
region.scaley = 1;
|
||||
region.keepAspectRatio = data.keepAspectRatio;
|
||||
region.zoom = data.zoom;
|
||||
region:UpdateSize()
|
||||
|
||||
icon:SetDesaturated(data.desaturate);
|
||||
|
||||
local tooltipType = WeakAuras.CanHaveTooltip(data);
|
||||
if(tooltipType and data.useTooltip) then
|
||||
if not region.tooltipFrame then
|
||||
region.tooltipFrame = CreateFrame("frame", nil, region);
|
||||
region.tooltipFrame:SetAllPoints(region);
|
||||
region.tooltipFrame:SetScript("OnEnter", function()
|
||||
WeakAuras.ShowMouseoverTooltip(region, region);
|
||||
end);
|
||||
region.tooltipFrame:SetScript("OnLeave", WeakAuras.HideTooltip);
|
||||
end
|
||||
region.tooltipFrame:EnableMouse(true);
|
||||
elseif region.tooltipFrame then
|
||||
region.tooltipFrame:EnableMouse(false);
|
||||
end
|
||||
|
||||
cooldown:SetReverse(not data.inverse);
|
||||
|
||||
function region:Color(r, g, b, a)
|
||||
region.color_r = r;
|
||||
region.color_g = g;
|
||||
region.color_b = b;
|
||||
region.color_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
icon:SetVertexColor(region.color_anim_r or r, region.color_anim_g or g, region.color_anim_b or b, region.color_anim_a or a);
|
||||
if region.button then
|
||||
region.button:SetAlpha(region.color_anim_a or a or 1);
|
||||
end
|
||||
end
|
||||
|
||||
function region:ColorAnim(r, g, b, a)
|
||||
region.color_anim_r = r;
|
||||
region.color_anim_g = g;
|
||||
region.color_anim_b = b;
|
||||
region.color_anim_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
icon:SetVertexColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a);
|
||||
if MSQ then
|
||||
region.button:SetAlpha(a or region.color_a or 1);
|
||||
end
|
||||
end
|
||||
|
||||
function region:GetColor()
|
||||
return region.color_r or data.color[1], region.color_g or data.color[2],
|
||||
region.color_b or data.color[3], region.color_a or data.color[4];
|
||||
end
|
||||
|
||||
region:Color(data.color[1], data.color[2], data.color[3], data.color[4]);
|
||||
|
||||
function region:SetIcon(path)
|
||||
local iconPath = (
|
||||
region.useAuto
|
||||
and path ~= ""
|
||||
and path
|
||||
or data.displayIcon
|
||||
or "Interface\\Icons\\INV_Misc_QuestionMark"
|
||||
);
|
||||
icon:SetTexture(iconPath);
|
||||
end
|
||||
|
||||
function region:Scale(scalex, scaley)
|
||||
if region.scalex == scalex and region.scaley == scaley then
|
||||
return
|
||||
end
|
||||
region.scalex = scalex;
|
||||
region.scaley = scaley;
|
||||
region:UpdateSize();
|
||||
end
|
||||
|
||||
function region:SetDesaturated(b)
|
||||
icon:SetDesaturated(b);
|
||||
end
|
||||
|
||||
function region:SetRegionWidth(width)
|
||||
region.width = width
|
||||
region:UpdateSize();
|
||||
end
|
||||
|
||||
function region:SetRegionHeight(height)
|
||||
region.height = height
|
||||
region:UpdateSize();
|
||||
end
|
||||
|
||||
function region:SetInverse(inverse)
|
||||
cooldown:SetReverse(not inverse);
|
||||
if (cooldown.expirationTime and cooldown.duration and cooldown:IsShown()) then
|
||||
-- WORKAROUND SetReverse not applying until next frame
|
||||
cooldown:SetCooldown(0, 0);
|
||||
cooldown:SetCooldown(cooldown.expirationTime - cooldown.duration, cooldown.duration);
|
||||
end
|
||||
end
|
||||
|
||||
function region:SetCooldownEdge(cooldownEdge)
|
||||
region.cooldownEdge = cooldownEdge;
|
||||
cooldown:SetDrawEdge(cooldownEdge);
|
||||
end
|
||||
|
||||
region:SetCooldownEdge(data.cooldownEdge)
|
||||
|
||||
function region:SetZoom(zoom)
|
||||
region.zoom = zoom;
|
||||
region:UpdateTexCoords();
|
||||
end
|
||||
|
||||
cooldown.expirationTime = nil;
|
||||
cooldown.duration = nil;
|
||||
cooldown:Hide()
|
||||
if(data.cooldown) then
|
||||
function region:SetValue(value, total)
|
||||
cooldown.duration = 0
|
||||
cooldown.expirationTime = math.huge
|
||||
cooldown:Hide();
|
||||
end
|
||||
|
||||
function region:SetTime(duration, expirationTime)
|
||||
if (duration > 0 and expirationTime > GetTime()) then
|
||||
cooldown:Show();
|
||||
cooldown.expirationTime = expirationTime;
|
||||
cooldown.duration = duration;
|
||||
cooldown:SetCooldown(expirationTime - duration, duration);
|
||||
else
|
||||
cooldown.expirationTime = expirationTime;
|
||||
cooldown.duration = duration;
|
||||
cooldown:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
function region:PreShow()
|
||||
if (cooldown.duration and cooldown.duration > 0.01) then
|
||||
cooldown:Show();
|
||||
cooldown:SetCooldown(cooldown.expirationTime - cooldown.duration, cooldown.duration);
|
||||
end
|
||||
end
|
||||
|
||||
function region:Update()
|
||||
local state = region.state
|
||||
if state.progressType == "timed" then
|
||||
local expirationTime = state.expirationTime and state.expirationTime > 0 and state.expirationTime or math.huge;
|
||||
local duration = state.duration or 0
|
||||
if region.adjustedMinRelPercent then
|
||||
region.adjustedMinRel = region.adjustedMinRelPercent * duration
|
||||
end
|
||||
local adjustMin = region.adjustedMin or region.adjustedMinRel or 0;
|
||||
|
||||
local max
|
||||
if duration == 0 then
|
||||
max = 0
|
||||
elseif region.adjustedMax then
|
||||
max = region.adjustedMax
|
||||
elseif region.adjustedMaxRelPercent then
|
||||
region.adjustedMaxRel = region.adjustedMaxRelPercent * duration
|
||||
max = region.adjustedMaxRel
|
||||
else
|
||||
max = duration
|
||||
end
|
||||
|
||||
region:SetTime(max - adjustMin, expirationTime - adjustMin, state.inverse);
|
||||
elseif state.progressType == "static" then
|
||||
local value = state.value or 0;
|
||||
local total = state.total or 0;
|
||||
if region.adjustedMinRelPercent then
|
||||
region.adjustedMinRel = region.adjustedMinRelPercent * total
|
||||
end
|
||||
local adjustMin = region.adjustedMin or region.adjustedMinRel or 0;
|
||||
local max = region.adjustedMax or region.adjustedMaxRel or total;
|
||||
region:SetValue(value - adjustMin, max - adjustMin);
|
||||
else
|
||||
region:SetTime(0, math.huge)
|
||||
end
|
||||
|
||||
region:SetIcon(state.icon or "Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
end
|
||||
else
|
||||
region.SetValue = nil
|
||||
region.SetTime = nil
|
||||
|
||||
function region:Update()
|
||||
local state = region.state
|
||||
region:SetIcon(state.icon or "Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
end
|
||||
end
|
||||
|
||||
-- Backwards compability function
|
||||
function region:SetGlow(glow)
|
||||
for index, subRegion in ipairs(self.subRegions) do
|
||||
if subRegion.type == "subglow" then
|
||||
subRegion:SetVisible(glow)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
|
||||
--- WORKAROUND
|
||||
-- This fixes a issue with barmodels not appearing on icons if the
|
||||
-- icon is shown delayed
|
||||
region:SetWidth(region:GetWidth())
|
||||
region:SetHeight(region:GetHeight())
|
||||
end
|
||||
|
||||
WeakAuras.RegisterRegionType("icon", create, modify, default, properties);
|
||||
@@ -0,0 +1,278 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
||||
local L = WeakAuras.L;
|
||||
|
||||
-- Default settings
|
||||
local default = {
|
||||
model_path = "Creature/Arthaslichking/arthaslichking.m2",
|
||||
modelIsUnit = false,
|
||||
model_x = 0,
|
||||
model_y = 0,
|
||||
model_z = 0,
|
||||
width = 200,
|
||||
height = 200,
|
||||
sequence = 1,
|
||||
advance = false,
|
||||
rotation = 0,
|
||||
scale = 1,
|
||||
selfPoint = "CENTER",
|
||||
anchorPoint = "CENTER",
|
||||
anchorFrameType = "SCREEN",
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
frameStrata = 1,
|
||||
border = false,
|
||||
borderColor = {1.0, 1.0, 1.0, 0.5},
|
||||
backdropColor = {1.0, 1.0, 1.0, 0.5},
|
||||
borderEdge = "None",
|
||||
borderOffset = 5,
|
||||
borderInset = 11,
|
||||
borderSize = 16,
|
||||
borderBackdrop = "Blizzard Tooltip",
|
||||
};
|
||||
|
||||
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
||||
|
||||
local properties = {
|
||||
width = {
|
||||
display = L["Width"],
|
||||
setter = "SetRegionWidth",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenWidth,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
height = {
|
||||
display = L["Height"],
|
||||
setter = "SetRegionHeight",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenHeight,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
}
|
||||
|
||||
WeakAuras.regionPrototype.AddProperties(properties, default);
|
||||
|
||||
local function GetProperties(data)
|
||||
return properties;
|
||||
end
|
||||
|
||||
local regionFunctions = {
|
||||
Update = function() end
|
||||
}
|
||||
|
||||
-- Called when first creating a new region/display
|
||||
local function create(parent)
|
||||
-- Main region
|
||||
local region = CreateFrame("FRAME", nil, UIParent);
|
||||
region:SetMovable(true);
|
||||
region:SetResizable(true);
|
||||
region:SetMinResize(1, 1);
|
||||
|
||||
-- Border region
|
||||
local border = CreateFrame("frame", nil, region);
|
||||
region.border = border;
|
||||
|
||||
WeakAuras.regionPrototype.create(region);
|
||||
|
||||
for k, v in pairs (regionFunctions) do
|
||||
region[k] = v
|
||||
end
|
||||
|
||||
-- Return complete region
|
||||
return region;
|
||||
end
|
||||
|
||||
local function CreateModel()
|
||||
return CreateFrame("PlayerModel", nil, UIParent)
|
||||
end
|
||||
|
||||
-- Keep the two model apis separate
|
||||
local pool = CreateObjectPool(CreateModel)
|
||||
|
||||
local function AcquireModel(region, data)
|
||||
local model = pool:Acquire()
|
||||
|
||||
model:ClearAllPoints()
|
||||
model:SetAllPoints(region)
|
||||
model:SetParent(region)
|
||||
--model:SetKeepModelOnHide(true)
|
||||
model:Show()
|
||||
|
||||
-- Adjust model
|
||||
WeakAuras.SetModel(model, data.model_path, data.modelIsUnit, data.modelDisplayInfo)
|
||||
model:SetPosition(data.model_z, data.model_x, data.model_y);
|
||||
model:SetFacing(rad(region.rotation));
|
||||
|
||||
if data.modelIsUnit then
|
||||
model:RegisterEvent("UNIT_MODEL_CHANGED");
|
||||
if (data.model_path == "target") then
|
||||
model:RegisterEvent("PLAYER_TARGET_CHANGED");
|
||||
elseif (data.model_path == "focus") then
|
||||
model:RegisterEvent("PLAYER_FOCUS_CHANGED");
|
||||
end
|
||||
model:SetScript("OnEvent", function(self, event, unitId)
|
||||
WeakAuras.StartProfileSystem("model");
|
||||
if (event ~= "UNIT_MODEL_CHANGED" or UnitIsUnit(unitId, data.model_path)) then
|
||||
WeakAuras.SetModel(model, data.model_path, data.modelIsUnit, data.modelDisplayInfo)
|
||||
end
|
||||
WeakAuras.StopProfileSystem("model");
|
||||
end
|
||||
);
|
||||
else
|
||||
model:UnregisterEvent("UNIT_MODEL_CHANGED");
|
||||
model:UnregisterEvent("PLAYER_TARGET_CHANGED");
|
||||
model:UnregisterEvent("PLAYER_FOCUS_CHANGED");
|
||||
model:SetScript("OnEvent", nil);
|
||||
end
|
||||
|
||||
-- Enable model animation
|
||||
if(data.advance) then
|
||||
local elapsed = 0;
|
||||
model:SetScript("OnUpdate", function(self, e)
|
||||
WeakAuras.StartProfileSystem("model");
|
||||
elapsed = elapsed + (e * 1000);
|
||||
model:SetSequenceTime(data.sequence, elapsed);
|
||||
WeakAuras.StopProfileSystem("model");
|
||||
end)
|
||||
else
|
||||
model:SetScript("OnUpdate", nil)
|
||||
end
|
||||
return model
|
||||
end
|
||||
|
||||
local function ReleaseModel(model)
|
||||
--model:SetKeepModelOnHide(false)
|
||||
model:Hide()
|
||||
model:UnregisterEvent("UNIT_MODEL_CHANGED");
|
||||
model:UnregisterEvent("PLAYER_TARGET_CHANGED");
|
||||
model:UnregisterEvent("PLAYER_FOCUS_CHANGED");
|
||||
model:SetScript("OnEvent", nil);
|
||||
pool:Release(model)
|
||||
end
|
||||
|
||||
-- Modify a given region/display
|
||||
local function modify(parent, region, data)
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
-- Localize
|
||||
local border = region.border;
|
||||
|
||||
if region.model then
|
||||
ReleaseModel(region.model)
|
||||
region.model = nil
|
||||
end
|
||||
|
||||
-- Reset position and size
|
||||
region:SetWidth(data.width);
|
||||
region:SetHeight(data.height);
|
||||
region.width = data.width;
|
||||
region.height = data.height;
|
||||
region.scalex = 1;
|
||||
region.scaley = 1;
|
||||
|
||||
-- Update border
|
||||
if data.border then
|
||||
border:SetBackdrop({
|
||||
edgeFile = SharedMedia:Fetch("border", data.borderEdge),
|
||||
edgeSize = data.borderSize,
|
||||
bgFile = SharedMedia:Fetch("background", data.borderBackdrop),
|
||||
insets = {
|
||||
left = data.borderInset,
|
||||
right = data.borderInset,
|
||||
top = data.borderInset,
|
||||
bottom = data.borderInset,
|
||||
},
|
||||
});
|
||||
border:SetBackdropBorderColor(data.borderColor[1], data.borderColor[2], data.borderColor[3], data.borderColor[4]);
|
||||
border:SetBackdropColor(data.backdropColor[1], data.backdropColor[2], data.backdropColor[3], data.backdropColor[4]);
|
||||
|
||||
border:SetPoint("bottomleft", region, "bottomleft", -data.borderOffset, -data.borderOffset);
|
||||
border:SetPoint("topright", region, "topright", data.borderOffset, data.borderOffset);
|
||||
|
||||
border:Show();
|
||||
else
|
||||
border:Hide();
|
||||
end
|
||||
-- Rescale model display
|
||||
function region:Scale(scalex, scaley)
|
||||
if(scalex < 0) then
|
||||
region.mirror_h = true;
|
||||
scalex = scalex * -1;
|
||||
else
|
||||
region.mirror_h = nil;
|
||||
end
|
||||
region:SetWidth(region.width * scalex);
|
||||
if(scaley < 0) then
|
||||
scaley = scaley * -1;
|
||||
region.mirror_v = true;
|
||||
else
|
||||
region.mirror_v = nil;
|
||||
end
|
||||
region:SetHeight(region.height * scaley);
|
||||
end
|
||||
|
||||
function region:SetRegionWidth(width)
|
||||
region.width = width;
|
||||
region:Scale(region.scalex, region.scaley);
|
||||
end
|
||||
|
||||
function region:SetRegionHeight(height)
|
||||
region.height = height;
|
||||
region:Scale(region.scalex, region.scaley);
|
||||
end
|
||||
|
||||
-- Rotate model
|
||||
function region:Rotate(degrees)
|
||||
region.rotation = degrees;
|
||||
if region.model then
|
||||
region.model:SetFacing(rad(region.rotation));
|
||||
end
|
||||
end
|
||||
|
||||
region:Rotate(data.rotation);
|
||||
|
||||
-- Get model rotation
|
||||
function region:GetRotation()
|
||||
return region.rotation;
|
||||
end
|
||||
|
||||
function region:PreShow()
|
||||
if not region.model then
|
||||
region.model = AcquireModel(self, data)
|
||||
end
|
||||
end
|
||||
|
||||
function region:PreHide()
|
||||
if region.model then
|
||||
ReleaseModel(region.model)
|
||||
region.model = nil
|
||||
end
|
||||
end
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
end
|
||||
|
||||
-- Work around for movies and world map hiding all models
|
||||
do
|
||||
function WeakAuras.PreShowModels(self, event)
|
||||
WeakAuras.StartProfileSystem("model");
|
||||
for id, data in pairs(WeakAuras.regions) do
|
||||
WeakAuras.StartProfileAura(id);
|
||||
if data.region.toShow then
|
||||
if (data.regionType == "model") then
|
||||
data.region:PreShow();
|
||||
end
|
||||
end
|
||||
WeakAuras.StopProfileAura(id);
|
||||
end
|
||||
WeakAuras.StopProfileSystem("model");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Register new region type with WeakAuras
|
||||
WeakAuras.RegisterRegionType("model", create, modify, default, GetProperties);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,869 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local WeakAuras = WeakAuras;
|
||||
local L = WeakAuras.L;
|
||||
|
||||
WeakAuras.regionPrototype = {};
|
||||
|
||||
|
||||
local SubRegionEventSystem =
|
||||
{
|
||||
ClearSubscribers = function(self)
|
||||
self.events = {}
|
||||
end,
|
||||
|
||||
AddSubscriber = function(self, event, subRegion)
|
||||
if not subRegion[event] then
|
||||
print("Can't register subregion for ", event, " ", subRegion.type)
|
||||
return
|
||||
end
|
||||
|
||||
self.events[event] = self.events[event] or {}
|
||||
tinsert(self.events[event], subRegion)
|
||||
end,
|
||||
|
||||
RemoveSubscriber = function(self, event, subRegion)
|
||||
tremove(self.events[event], subRegion)
|
||||
end,
|
||||
|
||||
Notify = function(self, event, ...)
|
||||
if self.events[event] then
|
||||
for _, subRegion in ipairs(self.events[event]) do
|
||||
subRegion[event](subRegion, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local function CreateSubRegionEventSystem()
|
||||
local system = {}
|
||||
for f, func in pairs(SubRegionEventSystem) do
|
||||
system[f] = func
|
||||
system.events = {}
|
||||
end
|
||||
return system
|
||||
end
|
||||
|
||||
-- Alpha
|
||||
function WeakAuras.regionPrototype.AddAlphaToDefault(default)
|
||||
default.alpha = 1.0;
|
||||
end
|
||||
|
||||
-- Adjusted Duration
|
||||
|
||||
function WeakAuras.regionPrototype.AddAdjustedDurationToDefault(default)
|
||||
default.useAdjustededMax = false;
|
||||
default.useAdjustededMin = false;
|
||||
end
|
||||
|
||||
function WeakAuras.regionPrototype.AddAdjustedDurationOptions(options, data, order)
|
||||
options.useAdjustededMin = {
|
||||
type = "toggle",
|
||||
width = WeakAuras.normalWidth,
|
||||
name = L["Set Minimum Progress"],
|
||||
desc = L["Values/Remaining Time below this value are displayed as no progress."],
|
||||
order = order
|
||||
};
|
||||
|
||||
options.adjustedMin = {
|
||||
type = "input",
|
||||
validate = WeakAuras.ValidateNumericOrPercent,
|
||||
width = WeakAuras.normalWidth,
|
||||
order = order + 0.01,
|
||||
name = L["Minimum"],
|
||||
hidden = function() return not data.useAdjustededMin end,
|
||||
desc = L["Enter static or relative values with %"]
|
||||
};
|
||||
|
||||
options.useAdjustedMinSpacer = {
|
||||
type = "description",
|
||||
width = WeakAuras.normalWidth,
|
||||
name = "",
|
||||
order = order + 0.02,
|
||||
hidden = function() return not (not data.useAdjustededMin and data.useAdjustededMax) end,
|
||||
};
|
||||
|
||||
options.useAdjustededMax = {
|
||||
type = "toggle",
|
||||
width = WeakAuras.normalWidth,
|
||||
name = L["Set Maximum Progress"],
|
||||
desc = L["Values/Remaining Time above this value are displayed as full progress."],
|
||||
order = order + 0.03
|
||||
};
|
||||
|
||||
options.adjustedMax = {
|
||||
type = "input",
|
||||
width = WeakAuras.normalWidth,
|
||||
validate = WeakAuras.ValidateNumericOrPercent,
|
||||
order = order + 0.04,
|
||||
name = L["Maximum"],
|
||||
hidden = function() return not data.useAdjustededMax end,
|
||||
desc = L["Enter static or relative values with %"]
|
||||
};
|
||||
|
||||
options.useAdjustedMaxSpacer = {
|
||||
type = "description",
|
||||
width = WeakAuras.normalWidth,
|
||||
name = "",
|
||||
order = order + 0.05,
|
||||
hidden = function() return not (data.useAdjustededMin and not data.useAdjustededMax) end,
|
||||
};
|
||||
|
||||
return options;
|
||||
end
|
||||
|
||||
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
||||
|
||||
function WeakAuras.GetAnchorsForData(parentData, type)
|
||||
local result
|
||||
if not parentData.controlledChildren then
|
||||
if not WeakAuras.regionOptions[parentData.regionType].getAnchors then
|
||||
return
|
||||
end
|
||||
|
||||
local anchors = WeakAuras.regionOptions[parentData.regionType].getAnchors(parentData)
|
||||
for anchorId, anchorData in pairs(anchors) do
|
||||
if anchorData.type == type then
|
||||
result = result or {}
|
||||
result[anchorId] = anchorData.display
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function WeakAuras.regionPrototype:AnchorSubRegion(subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset)
|
||||
subRegion:ClearAllPoints()
|
||||
|
||||
if anchorType == "point" then
|
||||
local xOffset = anchorXOffset or 0
|
||||
local yOffset = anchorYOffset or 0
|
||||
subRegion:SetPoint(WeakAuras.point_types[selfPoint] and selfPoint or "CENTER",
|
||||
self, WeakAuras.point_types[anchorPoint] and anchorPoint or "CENTER",
|
||||
xOffset, yOffset)
|
||||
else
|
||||
anchorXOffset = anchorXOffset or 0
|
||||
anchorYOffset = anchorYOffset or 0
|
||||
subRegion:SetPoint("bottomleft", self, "bottomleft", -anchorXOffset, -anchorYOffset)
|
||||
subRegion:SetPoint("topright", self, "topright", anchorXOffset, anchorYOffset)
|
||||
end
|
||||
end
|
||||
|
||||
-- Sound / Chat Message / Custom Code
|
||||
function WeakAuras.regionPrototype.AddProperties(properties, defaultsForRegion)
|
||||
properties["sound"] = {
|
||||
display = L["Sound"],
|
||||
action = "SoundPlay",
|
||||
type = "sound",
|
||||
};
|
||||
properties["chat"] = {
|
||||
display = L["Chat Message"],
|
||||
action = "SendChat",
|
||||
type = "chat",
|
||||
};
|
||||
properties["customcode"] = {
|
||||
display = L["Run Custom Code"],
|
||||
action = "RunCode",
|
||||
type = "customcode"
|
||||
}
|
||||
properties["xOffsetRelative"] = {
|
||||
display = L["Relative X-Offset"],
|
||||
setter = "SetXOffsetRelative",
|
||||
type = "number",
|
||||
softMin = -screenWidth,
|
||||
softMax = screenWidth,
|
||||
bigStep = 1
|
||||
}
|
||||
properties["yOffsetRelative"] = {
|
||||
display = L["Relative Y-Offset"],
|
||||
setter = "SetYOffsetRelative",
|
||||
type = "number",
|
||||
softMin = -screenHeight,
|
||||
softMax = screenHeight,
|
||||
bigStep = 1
|
||||
}
|
||||
properties["glowexternal"] = {
|
||||
display = L["Glow External Element"],
|
||||
action = "GlowExternal",
|
||||
type = "glowexternal"
|
||||
}
|
||||
|
||||
if (defaultsForRegion and defaultsForRegion.alpha) then
|
||||
properties["alpha"] = {
|
||||
display = L["Alpha"],
|
||||
setter = "SetRegionAlpha",
|
||||
type = "number",
|
||||
min = 0,
|
||||
max = 1,
|
||||
bigStep = 0.01,
|
||||
isPercent = true
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function SoundRepeatStop(self)
|
||||
WeakAuras.StartProfileSystem("sound");
|
||||
if (self.soundRepeatTimer) then
|
||||
WeakAuras.timer:CancelTimer(self.soundRepeatTimer);
|
||||
self.soundRepeatTimer = nil;
|
||||
end
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
end
|
||||
|
||||
local function SoundStop(self)
|
||||
WeakAuras.StartProfileSystem("sound");
|
||||
if (self.soundHandle) then
|
||||
StopSound(self.soundHandle);
|
||||
end
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
end
|
||||
|
||||
local function SoundPlayHelper(self)
|
||||
WeakAuras.StartProfileSystem("sound");
|
||||
local options = self.soundOptions;
|
||||
self.soundHandle = nil;
|
||||
if (not options or options.sound_type == "Stop") then
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
return;
|
||||
end
|
||||
|
||||
if (WeakAuras.IsOptionsOpen() or WeakAuras.SquelchingActions()) then
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
return;
|
||||
end
|
||||
|
||||
if (options.sound == " custom") then
|
||||
if (options.sound_path) then
|
||||
local ok, _, handle = pcall(PlaySoundFile, options.sound_path, options.sound_channel or "Master");
|
||||
if ok then
|
||||
self.soundHandle = handle;
|
||||
end
|
||||
end
|
||||
elseif (options.sound == " KitID") then
|
||||
if (options.sound_kit_id) then
|
||||
local ok, _, handle = pcall(PlaySound,options.sound_kit_id, options.sound_channel or "Master");
|
||||
if ok then
|
||||
self.soundHandle = handle;
|
||||
end
|
||||
end
|
||||
else
|
||||
local ok, _, handle = pcall(PlaySoundFile, options.sound, options.sound_channel or "Master");
|
||||
if ok then
|
||||
self.soundHandle = handle;
|
||||
end
|
||||
end
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
end
|
||||
|
||||
local function SoundPlay(self, options)
|
||||
if (not options or WeakAuras.IsOptionsOpen()) then
|
||||
return
|
||||
end
|
||||
WeakAuras.StartProfileSystem("sound");
|
||||
self:SoundStop();
|
||||
self:SoundRepeatStop();
|
||||
|
||||
self.soundOptions = options;
|
||||
SoundPlayHelper(self);
|
||||
|
||||
local loop = options.do_loop or options.sound_type == "Loop";
|
||||
if (loop and options.sound_repeat and options.sound_repeat < WeakAuras.maxTimerDuration) then
|
||||
self.soundRepeatTimer = WeakAuras.timer:ScheduleRepeatingTimer(SoundPlayHelper, options.sound_repeat, self);
|
||||
end
|
||||
WeakAuras.StopProfileSystem("sound");
|
||||
end
|
||||
|
||||
local function SendChat(self, options)
|
||||
if (not options or WeakAuras.IsOptionsOpen()) then
|
||||
return
|
||||
end
|
||||
WeakAuras.HandleChatAction(options.message_type, options.message, options.message_dest, options.message_channel, options.r, options.g, options.b, self, options.message_custom);
|
||||
end
|
||||
|
||||
local function RunCode(self, func)
|
||||
if func and not WeakAuras.IsOptionsOpen() then
|
||||
WeakAuras.ActivateAuraEnvironment(self.id, self.cloneId, self.state, self.states);
|
||||
xpcall(func, geterrorhandler());
|
||||
WeakAuras.ActivateAuraEnvironment(nil);
|
||||
end
|
||||
end
|
||||
|
||||
local function GlowExternal(self, options)
|
||||
if (not options or WeakAuras.IsOptionsOpen()) then
|
||||
return
|
||||
end
|
||||
WeakAuras.HandleGlowAction(options, self)
|
||||
end
|
||||
|
||||
local function UpdatePosition(self)
|
||||
if (not self.anchorPoint or not self.relativeTo or not self.relativePoint) then
|
||||
return;
|
||||
end
|
||||
|
||||
local xOffset = self.xOffset + (self.xOffsetAnim or 0) + (self.xOffsetRelative or 0)
|
||||
local yOffset = self.yOffset + (self.yOffsetAnim or 0) + (self.yOffsetRelative or 0)
|
||||
self:RealClearAllPoints();
|
||||
|
||||
self:SetPoint(self.anchorPoint, self.relativeTo, self.relativePoint, xOffset, yOffset);
|
||||
end
|
||||
|
||||
local function ResetPosition(self)
|
||||
self.anchorPoint = nil;
|
||||
self.relativeTo = nil;
|
||||
self.relativePoint = nil;
|
||||
end
|
||||
|
||||
local function SetAnchor(self, anchorPoint, relativeTo, relativePoint)
|
||||
if self.anchorPoint == anchorPoint and self.relativeTo == relativeTo and self.relativePoint == relativePoint then
|
||||
return
|
||||
end
|
||||
|
||||
self.anchorPoint = anchorPoint;
|
||||
self.relativeTo = relativeTo;
|
||||
self.relativePoint = relativePoint;
|
||||
|
||||
UpdatePosition(self);
|
||||
end
|
||||
|
||||
local function SetOffset(self, xOffset, yOffset)
|
||||
if (self.xOffset == xOffset and self.yOffset == yOffset) then
|
||||
return;
|
||||
end
|
||||
self.xOffset = xOffset;
|
||||
self.yOffset = yOffset;
|
||||
UpdatePosition(self);
|
||||
end
|
||||
|
||||
local function SetXOffset(self, xOffset)
|
||||
self:SetOffset(xOffset, self:GetYOffset());
|
||||
end
|
||||
|
||||
local function SetYOffset(self, yOffset)
|
||||
self:SetOffset(self:GetXOffset(), yOffset);
|
||||
end
|
||||
|
||||
local function GetXOffset(self)
|
||||
return self.xOffset;
|
||||
end
|
||||
|
||||
local function GetYOffset(self)
|
||||
return self.yOffset;
|
||||
end
|
||||
|
||||
local function SetOffsetRelative(self, xOffsetRelative, yOffsetRelative)
|
||||
if (self.xOffsetRelative == xOffsetRelative and self.yOffsetRelative == yOffsetRelative) then
|
||||
return
|
||||
end
|
||||
self.xOffsetRelative = xOffsetRelative
|
||||
self.yOffsetRelative = yOffsetRelative
|
||||
UpdatePosition(self)
|
||||
end
|
||||
|
||||
local function SetXOffsetRelative(self, xOffsetRelative)
|
||||
self:SetOffsetRelative(xOffsetRelative, self:GetYOffsetRelative())
|
||||
end
|
||||
|
||||
local function SetYOffsetRelative(self, yOffsetRelative)
|
||||
self:SetOffsetRelative(self:GetXOffsetRelative(), yOffsetRelative)
|
||||
end
|
||||
|
||||
local function GetXOffsetRelative(self)
|
||||
return self.xOffsetRelative
|
||||
end
|
||||
|
||||
local function GetYOffsetRelative(self)
|
||||
return self.yOffsetRelative
|
||||
end
|
||||
|
||||
local function SetOffsetAnim(self, xOffset, yOffset)
|
||||
if (self.xOffsetAnim == xOffset and self.yOffsetAnim == yOffset) then
|
||||
return;
|
||||
end
|
||||
self.xOffsetAnim = xOffset;
|
||||
self.yOffsetAnim = yOffset;
|
||||
UpdatePosition(self);
|
||||
end
|
||||
|
||||
local function SetRegionAlpha(self, alpha)
|
||||
if (self.alpha == alpha) then
|
||||
return;
|
||||
end
|
||||
|
||||
self.alpha = alpha;
|
||||
if (WeakAuras.IsOptionsOpen()) then
|
||||
self:SetAlpha(max(self.animAlpha or self.alpha or 1, 0.5));
|
||||
else
|
||||
self:SetAlpha(self.animAlpha or self.alpha or 1);
|
||||
end
|
||||
self.subRegionEvents:Notify("AlphaChanged")
|
||||
end
|
||||
|
||||
local function GetRegionAlpha(self)
|
||||
return self.animAlpha or self.alpha or 1;
|
||||
end
|
||||
|
||||
local function SetAnimAlpha(self, alpha)
|
||||
if (self.animAlpha == alpha) then
|
||||
return;
|
||||
end
|
||||
self.animAlpha = alpha;
|
||||
if (WeakAuras.IsOptionsOpen()) then
|
||||
self:SetAlpha(max(self.animAlpha or self.alpha or 1, 0.5));
|
||||
else
|
||||
self:SetAlpha(self.animAlpha or self.alpha or 1);
|
||||
end
|
||||
self.subRegionEvents:Notify("AlphaChanged")
|
||||
end
|
||||
|
||||
local function SetTriggerProvidesTimer(self, timerTick)
|
||||
self.triggerProvidesTimer = timerTick
|
||||
self:UpdateTimerTick()
|
||||
end
|
||||
|
||||
local function UpdateRegionHasTimerTick(self)
|
||||
local hasTimerTick = false
|
||||
if self.TimerTick then
|
||||
hasTimerTick = true
|
||||
elseif (self.subRegions) then
|
||||
for index, subRegion in pairs(self.subRegions) do
|
||||
if subRegion.TimerTick then
|
||||
hasTimerTick = true
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.regionHasTimer = hasTimerTick
|
||||
self:UpdateTimerTick()
|
||||
end
|
||||
|
||||
local function UpdateTimerTick(self)
|
||||
if self.triggerProvidesTimer and self.regionHasTimer then
|
||||
if not self:GetScript("OnUpdate") then
|
||||
self:SetScript("OnUpdate", function()
|
||||
WeakAuras.TimerTick(self)
|
||||
end);
|
||||
end
|
||||
else
|
||||
if self:GetScript("OnUpdate") then
|
||||
self:SetScript("OnUpdate", nil);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function WeakAuras.regionPrototype.create(region)
|
||||
region.SoundPlay = SoundPlay;
|
||||
region.SoundStop = SoundStop;
|
||||
region.SoundRepeatStop = SoundRepeatStop;
|
||||
region.SendChat = SendChat;
|
||||
region.RunCode = RunCode;
|
||||
region.GlowExternal = GlowExternal;
|
||||
|
||||
region.SetAnchor = SetAnchor;
|
||||
region.SetOffset = SetOffset;
|
||||
region.SetXOffset = SetXOffset;
|
||||
region.SetYOffset = SetYOffset;
|
||||
region.GetXOffset = GetXOffset;
|
||||
region.GetYOffset = GetYOffset;
|
||||
region.SetOffsetRelative = SetOffsetRelative
|
||||
region.SetXOffsetRelative = SetXOffsetRelative
|
||||
region.SetYOffsetRelative = SetYOffsetRelative
|
||||
region.GetXOffsetRelative = GetXOffsetRelative
|
||||
region.GetYOffsetRelative = GetYOffsetRelative
|
||||
region.SetOffsetAnim = SetOffsetAnim;
|
||||
region.ResetPosition = ResetPosition;
|
||||
region.RealClearAllPoints = region.ClearAllPoints;
|
||||
region.ClearAllPoints = function()
|
||||
region:RealClearAllPoints();
|
||||
region:ResetPosition();
|
||||
end
|
||||
region.SetRegionAlpha = SetRegionAlpha;
|
||||
region.GetRegionAlpha = GetRegionAlpha;
|
||||
region.SetAnimAlpha = SetAnimAlpha;
|
||||
|
||||
region.SetTriggerProvidesTimer = SetTriggerProvidesTimer
|
||||
region.UpdateRegionHasTimerTick = UpdateRegionHasTimerTick
|
||||
region.UpdateTimerTick = UpdateTimerTick
|
||||
|
||||
region.subRegionEvents = CreateSubRegionEventSystem()
|
||||
|
||||
region:SetPoint("CENTER", UIParent, "CENTER")
|
||||
end
|
||||
|
||||
-- SetDurationInfo
|
||||
|
||||
function WeakAuras.regionPrototype.modify(parent, region, data)
|
||||
region.subRegionEvents:ClearSubscribers()
|
||||
|
||||
local defaultsForRegion = WeakAuras.regionTypes[data.regionType] and WeakAuras.regionTypes[data.regionType].default;
|
||||
if (defaultsForRegion and defaultsForRegion.alpha) then
|
||||
region:SetRegionAlpha(data.alpha);
|
||||
end
|
||||
local hasAdjustedMin = defaultsForRegion and defaultsForRegion.useAdjustededMin ~= nil and data.useAdjustededMin
|
||||
and data.adjustedMin;
|
||||
local hasAdjustedMax = defaultsForRegion and defaultsForRegion.useAdjustededMax ~= nil and data.useAdjustededMax
|
||||
and data.adjustedMax;
|
||||
|
||||
region.adjustedMin = nil
|
||||
region.adjustedMinRel = nil
|
||||
region.adjustedMinRelPercent = nil
|
||||
region.adjustedMax = nil
|
||||
region.adjustedMaxRel = nil
|
||||
region.adjustedMaxRelPercent = nil
|
||||
|
||||
if (hasAdjustedMin) then
|
||||
local percent = string.match(data.adjustedMin, "(%d+)%%")
|
||||
if percent then
|
||||
region.adjustedMinRelPercent = tonumber(percent) / 100
|
||||
else
|
||||
region.adjustedMin = tonumber(data.adjustedMin);
|
||||
end
|
||||
end
|
||||
if (hasAdjustedMax) then
|
||||
local percent = string.match(data.adjustedMax, "(%d+)%%")
|
||||
if percent then
|
||||
region.adjustedMaxRelPercent = tonumber(percent) / 100
|
||||
else
|
||||
region.adjustedMax = tonumber(data.adjustedMax)
|
||||
end
|
||||
end
|
||||
|
||||
region:SetOffset(data.xOffset or 0, data.yOffset or 0);
|
||||
region:SetOffsetRelative(0, 0)
|
||||
region:SetOffsetAnim(0, 0);
|
||||
|
||||
if data.anchorFrameType == "CUSTOM" and data.customAnchor then
|
||||
region.customAnchorFunc = WeakAuras.LoadFunction("return " .. data.customAnchor, data.id, "custom anchor")
|
||||
else
|
||||
region.customAnchorFunc = nil
|
||||
end
|
||||
|
||||
if not parent or parent.regionType ~= "dynamicgroup" then
|
||||
if not (
|
||||
data.anchorFrameType == "CUSTOM"
|
||||
or data.anchorFrameType == "UNITFRAME"
|
||||
) then
|
||||
WeakAuras.AnchorFrame(data, region, parent);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function WeakAuras.regionPrototype.modifyFinish(parent, region, data)
|
||||
-- Sync subRegions
|
||||
if region.subRegions then
|
||||
for index, subRegion in pairs(region.subRegions) do
|
||||
WeakAuras.subRegionTypes[subRegion.type].release(subRegion)
|
||||
end
|
||||
|
||||
wipe(region.subRegions)
|
||||
end
|
||||
|
||||
if data.subRegions then
|
||||
region.subRegions = region.subRegions or {}
|
||||
local subRegionTypes = {}
|
||||
for index, subRegionData in pairs(data.subRegions) do
|
||||
if WeakAuras.subRegionTypes[subRegionData.type] then
|
||||
local subRegion = WeakAuras.subRegionTypes[subRegionData.type].acquire()
|
||||
subRegion.type = subRegionData.type
|
||||
|
||||
if subRegion then
|
||||
WeakAuras.subRegionTypes[subRegionData.type].modify(region, subRegion, data, subRegionData, not subRegionTypes[subRegionData.type])
|
||||
subRegionTypes[subRegionData.type] = true
|
||||
end
|
||||
|
||||
tinsert(region.subRegions, subRegion)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
region:UpdateRegionHasTimerTick()
|
||||
|
||||
WeakAuras.ApplyFrameLevel(region)
|
||||
end
|
||||
|
||||
local function SetProgressValue(region, value, total)
|
||||
local adjustMin = region.adjustedMin or 0;
|
||||
local max = region.adjustedMax or total;
|
||||
|
||||
region:SetValue(value - adjustMin, max - adjustMin);
|
||||
end
|
||||
|
||||
function WeakAuras.TimerTick(region)
|
||||
WeakAuras.StartProfileSystem("timer tick")
|
||||
WeakAuras.StartProfileAura(region.id);
|
||||
if region.TimerTick then
|
||||
region:TimerTick();
|
||||
end
|
||||
|
||||
region.subRegionEvents:Notify("TimerTick")
|
||||
WeakAuras.StopProfileAura(region.id);
|
||||
WeakAuras.StopProfileSystem("timer tick")
|
||||
end
|
||||
|
||||
local regionsForFrameTick = {}
|
||||
|
||||
local frameForFrameTick = CreateFrame("FRAME");
|
||||
|
||||
WeakAuras.frames["Frame Tick Frame"] = frameForFrameTick
|
||||
|
||||
function WeakAuras.RegisterForFrameTick(region)
|
||||
-- Check for a Frame Tick function
|
||||
local hasFrameTick = region.FrameTick
|
||||
if not hasFrameTick then
|
||||
if (region.subRegions) then
|
||||
for index, subRegion in pairs(region.subRegions) do
|
||||
if subRegion.FrameTick then
|
||||
hasFrameTick = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not hasFrameTick then
|
||||
return
|
||||
end
|
||||
|
||||
regionsForFrameTick[region] = true
|
||||
if not frameForFrameTick:GetScript("OnUpdate") then
|
||||
frameForFrameTick:SetScript("OnUpdate", WeakAuras.FrameTick);
|
||||
end
|
||||
end
|
||||
|
||||
function WeakAuras.UnRegisterForFrameTick(region)
|
||||
regionsForFrameTick[region] = nil
|
||||
if not next(regionsForFrameTick) then
|
||||
frameForFrameTick:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
|
||||
function WeakAuras.FrameTick()
|
||||
if WeakAuras.IsOptionsOpen() then
|
||||
return
|
||||
end
|
||||
WeakAuras.StartProfileSystem("frame tick")
|
||||
for region in pairs(regionsForFrameTick) do
|
||||
WeakAuras.StartProfileAura(region.id);
|
||||
if region.FrameTick then
|
||||
region.FrameTick()
|
||||
end
|
||||
region.subRegionEvents:Notify("FrameTick")
|
||||
WeakAuras.StopProfileAura(region.id);
|
||||
end
|
||||
WeakAuras.StopProfileSystem("frame tick")
|
||||
end
|
||||
|
||||
local function TimerTick(self)
|
||||
local duration = self.duration
|
||||
local adjustMin = self.adjustedMin or 0;
|
||||
|
||||
local max
|
||||
if duration == 0 then
|
||||
max = 0
|
||||
elseif self.adjustedMax then
|
||||
max = self.adjustedMax
|
||||
else
|
||||
max = duration
|
||||
end
|
||||
|
||||
self:SetTime(max - adjustMin, self.expirationTime - adjustMin, self.inverse);
|
||||
end
|
||||
|
||||
function WeakAuras.regionPrototype.AddSetDurationInfo(region)
|
||||
if (region.SetValue and region.SetTime) then
|
||||
region.generatedSetDurationInfo = true;
|
||||
|
||||
-- WeakAuras no longer calls SetDurationInfo, but some people do that,
|
||||
-- In that case we also need to overwrite TimerTick
|
||||
region.SetDurationInfo = function(self, duration, expirationTime, customValue, inverse)
|
||||
self.duration = duration or 0
|
||||
self.expirationTime = expirationTime;
|
||||
self.inverse = inverse;
|
||||
|
||||
if customValue then
|
||||
SetProgressValue(region, duration, expirationTime);
|
||||
region.TimerTick = nil
|
||||
region:UpdateRegionHasTimerTick()
|
||||
else
|
||||
local adjustMin = region.adjustedMin or 0;
|
||||
region:SetTime((duration ~= 0 and region.adjustedMax or duration) - adjustMin, expirationTime - adjustMin, inverse);
|
||||
|
||||
region.TimerTick = TimerTick
|
||||
region:UpdateRegionHasTimerTick()
|
||||
end
|
||||
end
|
||||
elseif (region.generatedSetDurationInfo) then
|
||||
region.generatedSetDurationInfo = nil;
|
||||
region.SetDurationInfo = nil;
|
||||
end
|
||||
end
|
||||
|
||||
-- Expand/Collapse function
|
||||
function WeakAuras.regionPrototype.AddExpandFunction(data, region, cloneId, parent, parentRegionType)
|
||||
local id = data.id
|
||||
local indynamicgroup = parentRegionType == "dynamicgroup";
|
||||
local ingroup = parentRegionType == "group";
|
||||
|
||||
local startMainAnimation = function()
|
||||
WeakAuras.Animate("display", data, "main", data.animation.main, region, false, nil, true, cloneId);
|
||||
end
|
||||
|
||||
function region:OptionsClosed()
|
||||
region:EnableMouse(false)
|
||||
region:SetScript("OnMouseDown", nil)
|
||||
end
|
||||
|
||||
function region:ClickToPick()
|
||||
region:EnableMouse(true)
|
||||
region:SetScript("OnMouseDown", function()
|
||||
WeakAuras.PickDisplay(region.id, nil, true)
|
||||
end)
|
||||
if region.GetFrameStrata and region:GetFrameStrata() == "TOOLTIP" then
|
||||
region:SetFrameStrata("HIGH")
|
||||
end
|
||||
end
|
||||
|
||||
local hideRegion;
|
||||
if(indynamicgroup) then
|
||||
hideRegion = function()
|
||||
if region.PreHide then
|
||||
region:PreHide()
|
||||
end
|
||||
if WeakAuras.checkConditions[id] then
|
||||
WeakAuras.checkConditions[id](region, true);
|
||||
end
|
||||
region:Hide();
|
||||
if (cloneId) then
|
||||
WeakAuras.ReleaseClone(region.id, cloneId, data.regionType);
|
||||
parent:RemoveChild(id, cloneId)
|
||||
else
|
||||
parent:DeactivateChild(id, cloneId);
|
||||
end
|
||||
end
|
||||
else
|
||||
hideRegion = function()
|
||||
if region.PreHide then
|
||||
region:PreHide()
|
||||
end
|
||||
if WeakAuras.checkConditions[id] then
|
||||
WeakAuras.checkConditions[id](region, true);
|
||||
end
|
||||
region:Hide();
|
||||
if (cloneId) then
|
||||
WeakAuras.ReleaseClone(region.id, cloneId, data.regionType);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(indynamicgroup) then
|
||||
function region:Collapse()
|
||||
if (not region.toShow) then
|
||||
return;
|
||||
end
|
||||
region.toShow = false;
|
||||
region:SetScript("OnUpdate", nil)
|
||||
|
||||
WeakAuras.PerformActions(data, "finish", region);
|
||||
if (not WeakAuras.Animate("display", data, "finish", data.animation.finish, region, false, hideRegion, nil, cloneId)) then
|
||||
hideRegion();
|
||||
end
|
||||
|
||||
if (region.SoundRepeatStop) then
|
||||
region:SoundRepeatStop();
|
||||
end
|
||||
|
||||
WeakAuras.UnRegisterForFrameTick(region)
|
||||
end
|
||||
function region:Expand()
|
||||
if (region.toShow) then
|
||||
return;
|
||||
end
|
||||
region.toShow = true;
|
||||
if(region.PreShow) then
|
||||
region:PreShow();
|
||||
end
|
||||
|
||||
region.subRegionEvents:Notify("PreShow")
|
||||
|
||||
region.justCreated = nil;
|
||||
WeakAuras.ApplyFrameLevel(region)
|
||||
region:Show();
|
||||
WeakAuras.PerformActions(data, "start", region);
|
||||
if not(WeakAuras.Animate("display", data, "start", data.animation.start, region, true, startMainAnimation, nil, cloneId)) then
|
||||
startMainAnimation();
|
||||
end
|
||||
parent:ActivateChild(data.id, cloneId);
|
||||
|
||||
WeakAuras.RegisterForFrameTick(region)
|
||||
region:UpdateTimerTick()
|
||||
end
|
||||
elseif not(data.controlledChildren) then
|
||||
function region:Collapse()
|
||||
if (not region.toShow) then
|
||||
return;
|
||||
end
|
||||
region.toShow = false;
|
||||
region:SetScript("OnUpdate", nil)
|
||||
|
||||
WeakAuras.PerformActions(data, "finish", region);
|
||||
if (not WeakAuras.Animate("display", data, "finish", data.animation.finish, region, false, hideRegion, nil, cloneId)) then
|
||||
hideRegion();
|
||||
end
|
||||
|
||||
if ingroup then
|
||||
parent:UpdateBorder(region);
|
||||
end
|
||||
|
||||
if (region.SoundRepeatStop) then
|
||||
region:SoundRepeatStop();
|
||||
end
|
||||
|
||||
WeakAuras.UnRegisterForFrameTick(region)
|
||||
end
|
||||
function region:Expand()
|
||||
if data.anchorFrameType == "SELECTFRAME"
|
||||
or data.anchorFrameType == "CUSTOM"
|
||||
or data.anchorFrameType == "UNITFRAME"
|
||||
then
|
||||
WeakAuras.AnchorFrame(data, region, parent);
|
||||
end
|
||||
|
||||
if (region.toShow) then
|
||||
return;
|
||||
end
|
||||
region.toShow = true;
|
||||
|
||||
region.justCreated = nil;
|
||||
if(region.PreShow) then
|
||||
region:PreShow();
|
||||
end
|
||||
|
||||
region.subRegionEvents:Notify("PreShow")
|
||||
|
||||
WeakAuras.ApplyFrameLevel(region)
|
||||
region:Show();
|
||||
WeakAuras.PerformActions(data, "start", region);
|
||||
if not(WeakAuras.Animate("display", data, "start", data.animation.start, region, true, startMainAnimation, nil, cloneId)) then
|
||||
startMainAnimation();
|
||||
end
|
||||
|
||||
if ingroup then
|
||||
parent:UpdateBorder(region);
|
||||
end
|
||||
|
||||
WeakAuras.RegisterForFrameTick(region)
|
||||
region:UpdateTimerTick()
|
||||
end
|
||||
end
|
||||
-- Stubs that allow for polymorphism
|
||||
if not region.Collapse then
|
||||
function region:Collapse() end
|
||||
end
|
||||
if not region.Expand then
|
||||
function region:Expand() end
|
||||
end
|
||||
end
|
||||
|
||||
function WeakAuras.SetTexture(texture, path, wrapModeH, wrapModeV)
|
||||
texture:SetTexture(path, wrapModeH, wrapModeV);
|
||||
end
|
||||
@@ -0,0 +1,275 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
||||
local L = WeakAuras.L;
|
||||
|
||||
local defaultFont = WeakAuras.defaultFont
|
||||
local defaultFontSize = WeakAuras.defaultFontSize
|
||||
|
||||
|
||||
local default = {
|
||||
displayText = "%p",
|
||||
outline = "OUTLINE",
|
||||
color = {1, 1, 1, 1},
|
||||
justify = "LEFT",
|
||||
selfPoint = "BOTTOM",
|
||||
anchorPoint = "CENTER",
|
||||
anchorFrameType = "SCREEN",
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
font = defaultFont,
|
||||
fontSize = defaultFontSize,
|
||||
frameStrata = 1,
|
||||
customTextUpdate = "event",
|
||||
automaticWidth = "Auto",
|
||||
fixedWidth = 200,
|
||||
wordWrap = "WordWrap",
|
||||
|
||||
shadowColor = { 0, 0, 0, 1},
|
||||
shadowXOffset = 1,
|
||||
shadowYOffset = -1,
|
||||
};
|
||||
|
||||
local properties = {
|
||||
color = {
|
||||
display = L["Color"],
|
||||
setter = "Color",
|
||||
type = "color",
|
||||
},
|
||||
fontSize = {
|
||||
display = L["Font Size"],
|
||||
setter = "SetTextHeight",
|
||||
type = "number",
|
||||
min = 6,
|
||||
softMax = 72,
|
||||
step = 1,
|
||||
default = 12
|
||||
}
|
||||
}
|
||||
|
||||
WeakAuras.regionPrototype.AddProperties(properties, default);
|
||||
|
||||
local function GetProperties(data)
|
||||
return properties;
|
||||
end
|
||||
|
||||
local function create(parent)
|
||||
local region = CreateFrame("FRAME", nil, parent);
|
||||
region:SetMovable(true);
|
||||
|
||||
local text = region:CreateFontString(nil, "OVERLAY");
|
||||
region.text = text;
|
||||
text:SetWordWrap(true);
|
||||
text:SetNonSpaceWrap(true);
|
||||
|
||||
region.values = {};
|
||||
region.duration = 0;
|
||||
region.expirationTime = math.huge;
|
||||
|
||||
WeakAuras.regionPrototype.create(region);
|
||||
|
||||
return region;
|
||||
end
|
||||
|
||||
local function modify(parent, region, data)
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
local text = region.text;
|
||||
|
||||
region.useAuto = WeakAuras.CanHaveAuto(data);
|
||||
region.progressPrecision = data.progressPrecision;
|
||||
region.totalPrecision = data.totalPrecision;
|
||||
|
||||
local fontPath = SharedMedia:Fetch("font", data.font);
|
||||
text:SetFont(fontPath, data.fontSize, data.outline);
|
||||
if not text:GetFont() then -- Font invalid, set the font but keep the setting
|
||||
text:SetFont(STANDARD_TEXT_FONT, data.fontSize, data.outline);
|
||||
end
|
||||
if text:GetFont() then
|
||||
text:SetText("")
|
||||
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(data.displayText));
|
||||
end
|
||||
text.displayText = data.displayText;
|
||||
text:SetJustifyH(data.justify);
|
||||
|
||||
text:ClearAllPoints();
|
||||
text:SetPoint("CENTER", UIParent, "CENTER");
|
||||
|
||||
region.width = text:GetWidth();
|
||||
region.height = text:GetStringHeight();
|
||||
region:SetWidth(region.width);
|
||||
region:SetHeight(region.height);
|
||||
|
||||
text:SetTextHeight(data.fontSize);
|
||||
text:SetShadowColor(unpack(data.shadowColor))
|
||||
text:SetShadowOffset(data.shadowXOffset, data.shadowYOffset)
|
||||
|
||||
text:ClearAllPoints();
|
||||
text:SetPoint(data.justify, region, data.justify);
|
||||
|
||||
local SetText;
|
||||
|
||||
if (data.automaticWidth == "Fixed") then
|
||||
if (data.wordWrap == "WordWrap") then
|
||||
text:SetWordWrap(true);
|
||||
text:SetNonSpaceWrap(true);
|
||||
else
|
||||
text:SetWordWrap(false);
|
||||
text:SetNonSpaceWrap(false);
|
||||
end
|
||||
|
||||
text:SetWidth(data.fixedWidth);
|
||||
region:SetWidth(data.fixedWidth);
|
||||
region.width = data.fixedWidth;
|
||||
SetText = function(textStr)
|
||||
if text:GetFont() then
|
||||
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(textStr));
|
||||
end
|
||||
|
||||
local height = text:GetStringHeight();
|
||||
|
||||
if(region.height ~= height) then
|
||||
region.height = text:GetStringHeight();
|
||||
region:SetHeight(region.height);
|
||||
if(data.parent and WeakAuras.regions[data.parent].region.PositionChildren) then
|
||||
WeakAuras.regions[data.parent].region:PositionChildren();
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
text:SetWidth(0);
|
||||
text:SetWordWrap(true);
|
||||
text:SetNonSpaceWrap(true);
|
||||
SetText = function(textStr)
|
||||
if(textStr ~= text.displayText) then
|
||||
if text:GetFont() then
|
||||
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(textStr));
|
||||
end
|
||||
end
|
||||
local width = text:GetWidth();
|
||||
local height = text:GetStringHeight();
|
||||
if(width ~= region.width or height ~= region.height ) then
|
||||
region.width = width;
|
||||
region.height = height;
|
||||
region:SetWidth(region.width);
|
||||
region:SetHeight(region.height);
|
||||
if(data.parent and WeakAuras.regions[data.parent].region.PositionChildren) then
|
||||
WeakAuras.regions[data.parent].region:PositionChildren();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local UpdateText
|
||||
if WeakAuras.ContainsAnyPlaceHolders(data.displayText) then
|
||||
UpdateText = function()
|
||||
local textStr = data.displayText;
|
||||
textStr = WeakAuras.ReplacePlaceHolders(textStr, region, nil);
|
||||
if (textStr == nil or textStr == "") then
|
||||
textStr = " ";
|
||||
end
|
||||
|
||||
SetText(textStr)
|
||||
end
|
||||
end
|
||||
|
||||
local customTextFunc = nil
|
||||
if(WeakAuras.ContainsCustomPlaceHolder(data.displayText) and data.customText) then
|
||||
customTextFunc = WeakAuras.LoadFunction("return "..data.customText, region.id, "custom text")
|
||||
end
|
||||
|
||||
local Update
|
||||
if customTextFunc then
|
||||
if UpdateText then
|
||||
Update = function()
|
||||
region.values.custom = WeakAuras.RunCustomTextFunc(region, customTextFunc)
|
||||
UpdateText()
|
||||
end
|
||||
end
|
||||
else
|
||||
Update = UpdateText or function() end
|
||||
end
|
||||
|
||||
local TimerTick
|
||||
if WeakAuras.ContainsPlaceHolders(data.displayText, "p") then
|
||||
TimerTick = UpdateText
|
||||
end
|
||||
|
||||
local FrameTick
|
||||
if customTextFunc and data.customTextUpdate == "update" then
|
||||
FrameTick = function()
|
||||
region.values.custom = WeakAuras.RunCustomTextFunc(region, customTextFunc)
|
||||
UpdateText()
|
||||
end
|
||||
end
|
||||
|
||||
region.Update = Update
|
||||
region.FrameTick = FrameTick
|
||||
region.TimerTick = TimerTick
|
||||
|
||||
if not UpdateText then
|
||||
SetText(data.displayText);
|
||||
end
|
||||
|
||||
function region:Color(r, g, b, a)
|
||||
region.color_r = r;
|
||||
region.color_g = g;
|
||||
region.color_b = b;
|
||||
region.color_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
text:SetTextColor(region.color_anim_r or r, region.color_anim_g or g, region.color_anim_b or b, region.color_anim_a or a);
|
||||
end
|
||||
|
||||
function region:ColorAnim(r, g, b, a)
|
||||
region.color_anim_r = r;
|
||||
region.color_anim_g = g;
|
||||
region.color_anim_b = b;
|
||||
region.color_anim_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
text:SetTextColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a);
|
||||
end
|
||||
|
||||
function region:GetColor()
|
||||
return region.color_r or data.color[1], region.color_g or data.color[2],
|
||||
region.color_b or data.color[3], region.color_a or data.color[4];
|
||||
end
|
||||
|
||||
region:Color(data.color[1], data.color[2], data.color[3], data.color[4]);
|
||||
|
||||
function region:SetTextHeight(size)
|
||||
local fontPath = SharedMedia:Fetch("font", data.font);
|
||||
region.text:SetFont(fontPath, size, data.outline);
|
||||
region.text:SetTextHeight(size)
|
||||
end
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
end
|
||||
|
||||
WeakAuras.RegisterRegionType("text", create, modify, default, GetProperties);
|
||||
|
||||
-- Fallback region type
|
||||
|
||||
local function fallbackmodify(parent, region, data)
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
local text = region.text;
|
||||
|
||||
text:SetFont(STANDARD_TEXT_FONT, data.fontSize, data.outline and "OUTLINE" or nil);
|
||||
if text:GetFont() then
|
||||
text:SetText(WeakAuras.L["Region type %s not supported"]:format(data.regionType));
|
||||
end
|
||||
|
||||
text:ClearAllPoints();
|
||||
text:SetPoint("CENTER", region, "CENTER");
|
||||
|
||||
region:SetWidth(text:GetWidth());
|
||||
region:SetHeight(text:GetStringHeight());
|
||||
|
||||
region.Update = function() end
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
end
|
||||
|
||||
WeakAuras.RegisterRegionType("fallback", create, fallbackmodify, default);
|
||||
@@ -0,0 +1,239 @@
|
||||
if not WeakAuras.IsCorrectVersion() then return end
|
||||
|
||||
local L = WeakAuras.L;
|
||||
|
||||
local root2 = math.sqrt(2);
|
||||
local halfroot2 = root2/2;
|
||||
|
||||
local default = {
|
||||
texture = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\Aura3",
|
||||
desaturate = false,
|
||||
width = 200,
|
||||
height = 200,
|
||||
color = {1, 1, 1, 0.75},
|
||||
blendMode = "BLEND",
|
||||
rotation = 0,
|
||||
discrete_rotation = 0,
|
||||
mirror = false,
|
||||
rotate = true,
|
||||
selfPoint = "CENTER",
|
||||
anchorPoint = "CENTER",
|
||||
anchorFrameType = "SCREEN",
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
frameStrata = 1
|
||||
};
|
||||
|
||||
WeakAuras.regionPrototype.AddAlphaToDefault(default);
|
||||
|
||||
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
||||
|
||||
local properties = {
|
||||
color = {
|
||||
display = L["Color"],
|
||||
setter = "Color",
|
||||
type = "color",
|
||||
},
|
||||
desaturate = {
|
||||
display = L["Desaturate"],
|
||||
setter = "SetDesaturated",
|
||||
type = "bool"
|
||||
},
|
||||
width = {
|
||||
display = L["Width"],
|
||||
setter = "SetRegionWidth",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenWidth,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
height = {
|
||||
display = L["Height"],
|
||||
setter = "SetRegionHeight",
|
||||
type = "number",
|
||||
min = 1,
|
||||
softMax = screenHeight,
|
||||
bigStep = 1,
|
||||
default = 32
|
||||
},
|
||||
mirror = {
|
||||
display = L["Mirror"],
|
||||
setter = "SetMirror",
|
||||
type = "bool"
|
||||
}
|
||||
}
|
||||
|
||||
WeakAuras.regionPrototype.AddProperties(properties, default);
|
||||
|
||||
local function create(parent)
|
||||
local region = CreateFrame("FRAME", nil, UIParent);
|
||||
region:SetMovable(true);
|
||||
region:SetResizable(true);
|
||||
region:SetMinResize(1, 1);
|
||||
|
||||
local texture = region:CreateTexture();
|
||||
region.texture = texture;
|
||||
texture:SetAllPoints(region);
|
||||
|
||||
WeakAuras.regionPrototype.create(region);
|
||||
region.values = {};
|
||||
|
||||
region.AnchorSubRegion = WeakAuras.regionPrototype.AnchorSubRegion
|
||||
|
||||
return region;
|
||||
end
|
||||
|
||||
local function modify(parent, region, data)
|
||||
WeakAuras.regionPrototype.modify(parent, region, data);
|
||||
WeakAuras.SetTexture(region.texture, data.texture);
|
||||
region.texture:SetDesaturated(data.desaturate)
|
||||
region:SetWidth(data.width);
|
||||
region:SetHeight(data.height);
|
||||
region.width = data.width;
|
||||
region.height = data.height;
|
||||
region.scalex = 1;
|
||||
region.scaley = 1;
|
||||
region.texture:SetBlendMode(data.blendMode);
|
||||
--region.texture:SetRotation((data.rotation / 180) * math.pi);
|
||||
|
||||
local function GetRotatedPoints(degrees)
|
||||
local angle = rad(135 - degrees);
|
||||
local vx = math.cos(angle);
|
||||
local vy = math.sin(angle);
|
||||
|
||||
return 0.5+vx,0.5-vy , 0.5-vy,0.5-vx , 0.5+vy,0.5+vx , 0.5-vx,0.5+vy
|
||||
end
|
||||
|
||||
region.mirror = data.mirror
|
||||
|
||||
local function DoTexCoord()
|
||||
local mirror_h, mirror_v = region.mirror_h, region.mirror_v;
|
||||
if(region.mirror) then
|
||||
mirror_h = not mirror_h;
|
||||
end
|
||||
local ulx,uly , llx,lly , urx,ury , lrx,lry;
|
||||
if(data.rotate) then
|
||||
ulx,uly , llx,lly , urx,ury , lrx,lry = GetRotatedPoints(region.rotation);
|
||||
else
|
||||
if(data.discrete_rotation == 0 or data.discrete_rotation == 360) then
|
||||
ulx,uly , llx,lly , urx,ury , lrx,lry = 0,0 , 0,1 , 1,0 , 1,1;
|
||||
elseif(data.discrete_rotation == 90) then
|
||||
ulx,uly , llx,lly , urx,ury , lrx,lry = 1,0 , 0,0 , 1,1 , 0,1;
|
||||
elseif(data.discrete_rotation == 180) then
|
||||
ulx,uly , llx,lly , urx,ury , lrx,lry = 1,1 , 1,0 , 0,1 , 0,0;
|
||||
elseif(data.discrete_rotation == 270) then
|
||||
ulx,uly , llx,lly , urx,ury , lrx,lry = 0,1 , 1,1 , 0,0 , 1,0;
|
||||
end
|
||||
end
|
||||
if(mirror_h) then
|
||||
if(mirror_v) then
|
||||
region.texture:SetTexCoord(lrx,lry , urx,ury , llx,lly , ulx,uly);
|
||||
else
|
||||
region.texture:SetTexCoord(urx,ury , lrx,lry , ulx,uly , llx,lly);
|
||||
end
|
||||
else
|
||||
if(mirror_v) then
|
||||
region.texture:SetTexCoord(llx,lly , ulx,uly , lrx,lry , urx,ury);
|
||||
else
|
||||
region.texture:SetTexCoord(ulx,uly , llx,lly , urx,ury , lrx,lry);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
region.rotation = data.rotation;
|
||||
DoTexCoord();
|
||||
|
||||
function region:Scale(scalex, scaley)
|
||||
region.scalex = scalex;
|
||||
region.scaley = scaley;
|
||||
if(scalex < 0) then
|
||||
region.mirror_h = true;
|
||||
scalex = scalex * -1;
|
||||
else
|
||||
region.mirror_h = nil;
|
||||
end
|
||||
region:SetWidth(region.width * scalex);
|
||||
if(scaley < 0) then
|
||||
scaley = scaley * -1;
|
||||
region.mirror_v = true;
|
||||
else
|
||||
region.mirror_v = nil;
|
||||
end
|
||||
region:SetHeight(region.height * scaley);
|
||||
|
||||
DoTexCoord();
|
||||
end
|
||||
|
||||
function region:SetRegionWidth(width)
|
||||
region.width = width;
|
||||
region:Scale(region.scalex, region.scaley);
|
||||
end
|
||||
|
||||
function region:SetRegionHeight(height)
|
||||
region.height = height;
|
||||
region:Scale(region.scalex, region.scaley);
|
||||
end
|
||||
|
||||
function region:SetMirror(mirror)
|
||||
region.mirror = mirror
|
||||
DoTexCoord()
|
||||
end
|
||||
|
||||
function region:Update()
|
||||
if region.state.texture then
|
||||
WeakAuras.SetTexture(region.texture, region.state.texture);
|
||||
end
|
||||
end
|
||||
|
||||
function region:Color(r, g, b, a)
|
||||
region.color_r = r;
|
||||
region.color_g = g;
|
||||
region.color_b = b;
|
||||
region.color_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
region.texture:SetVertexColor(region.color_anim_r or r, region.color_anim_g or g, region.color_anim_b or b, region.color_anim_a or a);
|
||||
end
|
||||
|
||||
function region:ColorAnim(r, g, b, a)
|
||||
region.color_anim_r = r;
|
||||
region.color_anim_g = g;
|
||||
region.color_anim_b = b;
|
||||
region.color_anim_a = a;
|
||||
if (r or g or b) then
|
||||
a = a or 1;
|
||||
end
|
||||
region.texture:SetVertexColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a);
|
||||
end
|
||||
|
||||
function region:GetColor()
|
||||
return region.color_r or data.color[1], region.color_g or data.color[2],
|
||||
region.color_b or data.color[3], region.color_a or data.color[4];
|
||||
end
|
||||
|
||||
region:Color(data.color[1], data.color[2], data.color[3], data.color[4]);
|
||||
|
||||
function region:SetDesaturated(b)
|
||||
region.texture:SetDesaturated(b);
|
||||
end
|
||||
|
||||
if(data.rotate) then
|
||||
function region:Rotate(degrees)
|
||||
region.rotation = degrees;
|
||||
DoTexCoord();
|
||||
end
|
||||
|
||||
function region:GetRotation()
|
||||
return region.rotation;
|
||||
end
|
||||
else
|
||||
region.Rotate = nil;
|
||||
region.GetRotation = nil;
|
||||
end
|
||||
|
||||
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
||||
end
|
||||
|
||||
WeakAuras.RegisterRegionType("texture", create, modify, default, properties);
|
||||
Reference in New Issue
Block a user