1375 lines
40 KiB
Lua
1375 lines
40 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName, Private = ...
|
|
|
|
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
|
local L = WeakAuras.L;
|
|
|
|
-- Default settings
|
|
local default = {
|
|
icon = false,
|
|
desaturate = false,
|
|
iconSource = -1,
|
|
texture = "Blizzard",
|
|
width = 200,
|
|
height = 15,
|
|
orientation = "HORIZONTAL",
|
|
inverse = false,
|
|
barColor = {1.0, 0.0, 0.0, 1.0},
|
|
backgroundColor = {0.0, 0.0, 0.0, 0.5},
|
|
spark = false,
|
|
sparkWidth = 10,
|
|
sparkHeight = 30,
|
|
sparkColor = {1.0, 1.0, 1.0, 1.0},
|
|
sparkTexture = "Interface\\CastingBar\\UI-CastingBar-Spark",
|
|
sparkBlendMode = "ADD",
|
|
sparkOffsetX = 0,
|
|
sparkOffsetY = 0,
|
|
sparkRotationMode = "AUTO",
|
|
sparkRotation = 0,
|
|
sparkHidden = "NEVER",
|
|
selfPoint = "CENTER",
|
|
anchorPoint = "CENTER",
|
|
anchorFrameType = "SCREEN",
|
|
xOffset = 0,
|
|
yOffset = 0,
|
|
icon_side = "RIGHT",
|
|
icon_color = {1.0, 1.0, 1.0, 1.0},
|
|
frameStrata = 1,
|
|
zoom = 0
|
|
};
|
|
|
|
WeakAuras.regionPrototype.AddAdjustedDurationToDefault(default);
|
|
WeakAuras.regionPrototype.AddAlphaToDefault(default);
|
|
|
|
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
|
|
|
local properties = {
|
|
barColor = {
|
|
display = L["Bar Color"],
|
|
setter = "Color",
|
|
type = "color",
|
|
},
|
|
icon_visible = {
|
|
display = {L["Icon"], L["Visibility"]},
|
|
setter = "SetIconVisible",
|
|
type = "bool"
|
|
},
|
|
icon_color = {
|
|
display = {L["Icon"], L["Color"]},
|
|
setter = "SetIconColor",
|
|
type = "color"
|
|
},
|
|
iconSource = {
|
|
display = {L["Icon"], L["Source"]},
|
|
setter = "SetIconSource",
|
|
type = "list",
|
|
values = {}
|
|
},
|
|
displayIcon = {
|
|
display = {L["Icon"], L["Fallback"]},
|
|
setter = "SetIcon",
|
|
type = "icon",
|
|
},
|
|
desaturate = {
|
|
display = {L["Icon"], L["Desaturate"]},
|
|
setter = "SetIconDesaturated",
|
|
type = "bool",
|
|
},
|
|
backgroundColor = {
|
|
display = L["Background Color"],
|
|
setter = "SetBackgroundColor",
|
|
type = "color"
|
|
},
|
|
sparkColor = {
|
|
display = {L["Spark"], L["Color"]},
|
|
setter = "SetSparkColor",
|
|
type = "color"
|
|
},
|
|
sparkHeight = {
|
|
display = {L["Spark"], L["Height"]},
|
|
setter = "SetSparkHeight",
|
|
type = "number",
|
|
min = 1,
|
|
softMax = screenHeight,
|
|
bigStep = 1
|
|
},
|
|
sparkWidth = {
|
|
display = {L["Spark"], L["Width"]},
|
|
setter = "SetSparkWidth",
|
|
type = "number",
|
|
min = 1,
|
|
softMax = screenWidth,
|
|
bigStep = 1
|
|
},
|
|
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
|
|
},
|
|
orientation = {
|
|
display = L["Orientation"],
|
|
setter = "SetOrientation",
|
|
type = "list",
|
|
values = Private.orientation_types
|
|
},
|
|
inverse = {
|
|
display = L["Inverse"],
|
|
setter = "SetInverse",
|
|
type = "bool"
|
|
},
|
|
};
|
|
|
|
WeakAuras.regionPrototype.AddProperties(properties, default);
|
|
|
|
local function GetProperties(data)
|
|
local overlayInfo = Private.GetOverlayInfo(data);
|
|
local auraProperties = CopyTable(properties)
|
|
if (overlayInfo and next(overlayInfo)) then
|
|
for id, display in ipairs(overlayInfo) do
|
|
auraProperties["overlays." .. id] = {
|
|
display = string.format(L["%s Overlay Color"], display),
|
|
setter = "SetOverlayColor",
|
|
arg1 = id,
|
|
type = "color",
|
|
}
|
|
end
|
|
end
|
|
|
|
auraProperties.iconSource.values = Private.IconSources(data)
|
|
return auraProperties;
|
|
end
|
|
|
|
-- Returns tex Coord for 90° rotations + x or y flip
|
|
|
|
local texCoords = {
|
|
0, 0, 1, 1,
|
|
0, 0, 1, 1,
|
|
0, 0, 1, 1
|
|
};
|
|
|
|
-- only supports multipliers of 90° degree
|
|
-- returns in order: TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy
|
|
local GetTexCoordSpark = function(degree, mirror)
|
|
local offset = (degree or 0) / 90
|
|
local TLx, TLy = texCoords[2 + offset], texCoords[1 + offset]
|
|
local TRx, TRy = texCoords[3 + offset], texCoords[2 + offset]
|
|
local BLx, BLy = texCoords[1 + offset], texCoords[4 + offset]
|
|
local BRx, BRy = texCoords[4 + offset], texCoords[3 + offset]
|
|
|
|
if (mirror) then
|
|
TLx, TRx = TRx, TLx
|
|
TLy, TRy = TRy, TLy
|
|
BLx, BRx = BRx, BLx
|
|
BLy, BRy = BRy, BLy
|
|
end
|
|
|
|
return TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy
|
|
end
|
|
|
|
local GetTexCoordFunctions =
|
|
{
|
|
["HORIZONTAL"] = function(startProgress, endProgress)
|
|
local TLx, TLy = startProgress, 0;
|
|
local TRx, TRy = endProgress, 0;
|
|
local BLx, BLy = startProgress, 1;
|
|
local BRx, BRy = endProgress, 1;
|
|
return TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy;
|
|
end,
|
|
["HORIZONTAL_INVERSE"] = function(startProgress, endProgress)
|
|
local TLx, TLy = endProgress, 0;
|
|
local TRx, TRy = startProgress, 0;
|
|
local BLx, BLy = endProgress, 1;
|
|
local BRx, BRy = startProgress, 1;
|
|
return TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy;
|
|
end,
|
|
["VERTICAL"] = function(startProgress, endProgress)
|
|
local TLx, TLy = startProgress, 1;
|
|
local TRx, TRy = startProgress, 0;
|
|
local BLx, BLy = endProgress, 1;
|
|
local BRx, BRy = endProgress, 0;
|
|
return TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy;
|
|
end,
|
|
["VERTICAL_INVERSE"] = function(startProgress, endProgress)
|
|
local TLx, TLy = endProgress, 0;
|
|
local TRx, TRy = endProgress, 1;
|
|
local BLx, BLy = startProgress, 0;
|
|
local BRx, BRy = startProgress, 1;
|
|
return TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy;
|
|
end
|
|
}
|
|
|
|
local anchorAlignment = {
|
|
["HORIZONTAL"] = { "TOPLEFT", "BOTTOMLEFT", "RIGHT" },
|
|
["HORIZONTAL_INVERSE"] = { "TOPRIGHT", "BOTTOMRIGHT", "LEFT" },
|
|
["VERTICAL"] = { "TOPLEFT", "TOPRIGHT", "BOTTOM" },
|
|
["VERTICAL_INVERSE"] = { "BOTTOMLEFT", "BOTTOMRIGHT", "TOP" }
|
|
}
|
|
|
|
-- Emulate blizzard statusbar with advanced features (more grow directions)
|
|
local barPrototype = {
|
|
["UpdateAnchors"] = function(self)
|
|
-- Do not flip/rotate textures
|
|
local orientation = self.orientation;
|
|
if not self.rotate then
|
|
if orientation == "HORIZONTAL_INVERSE" then
|
|
orientation = "HORIZONTAL";
|
|
elseif orientation == "VERTICAL_INVERSE" then
|
|
orientation = "VERTICAL";
|
|
end
|
|
end
|
|
|
|
self.GetTexCoord = GetTexCoordFunctions[orientation];
|
|
local anchorAlignment = anchorAlignment[orientation];
|
|
self.align1 = anchorAlignment[1];
|
|
self.align2 = anchorAlignment[2];
|
|
self.alignSpark = anchorAlignment[3];
|
|
|
|
self.horizontal = (self.orientation == "HORIZONTAL_INVERSE") or (self.orientation == "HORIZONTAL")
|
|
self.directionInverse = (self.orientation == "HORIZONTAL_INVERSE") or (self.orientation == "VERTICAL")
|
|
|
|
local TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy = self.GetTexCoord(0, 1);
|
|
self.bg:SetTexCoord(TLx , TLy , BLx , BLy , TRx , TRy , BRx , BRy );
|
|
|
|
-- Set alignment
|
|
self.fg:ClearAllPoints();
|
|
self.fg:SetPoint(self.align1);
|
|
self.fg:SetPoint(self.align2);
|
|
self.fgFrame:ClearAllPoints()
|
|
self.fgFrame:SetPoint(self.align1);
|
|
self.fgFrame:SetPoint(self.align2);
|
|
|
|
self.spark:SetPoint("CENTER", self.fg, self.alignSpark, self.spark.sparkOffsetX or 0, self.spark.sparkOffsetY or 0);
|
|
|
|
local sparkMirror = self.spark.sparkMirror;
|
|
local sparkRotationMode = self.spark.sparkRotationMode;
|
|
local sTLx, sTLy, sBLx, sBLy, sTRx, sTRy, sBRx, sBRy; -- spark rotation
|
|
if (sparkRotationMode == "AUTO") then
|
|
sTLx, sTLy, sBLx, sBLy, sTRx, sTRy, sBRx, sBRy = TLx, TLy, BLx, BLy, TRx, TRy, BRx, BRy;
|
|
else
|
|
local sparkRotation = tonumber(self.spark.sparkRotation);
|
|
sTLx, sTLy, sTRx, sTRy, sBLx, sBLy, sBRx, sBRy = GetTexCoordSpark(sparkRotation, sparkMirror)
|
|
end
|
|
self.spark:SetTexCoord(sTLx , sTLy , sBLx , sBLy , sTRx , sTRy , sBRx , sBRy);
|
|
end,
|
|
|
|
["UpdateProgress"] = function(self)
|
|
-- Limit values
|
|
local value = self.value;
|
|
value = math.max(self.min, value);
|
|
value = math.min(self.max, value);
|
|
|
|
-- Alignment variables
|
|
local progress = (value - self.min) / (self.max - self.min);
|
|
|
|
-- Create statusbar illusion
|
|
if (self.horizontal) then
|
|
local xProgress = self:GetRealSize() * progress;
|
|
self.fg:SetWidth(xProgress > 0.0001 and xProgress or 0.0001);
|
|
self.fgFrame:SetWidth(xProgress > 0.0001 and xProgress or 0.0001);
|
|
else
|
|
local yProgress = select(2, self:GetRealSize()) * progress;
|
|
self.fg:SetHeight(yProgress > 0.0001 and yProgress or 0.0001);
|
|
self.fgFrame:SetHeight(yProgress > 0.0001 and yProgress or 0.0001);
|
|
end
|
|
|
|
-- Stretch texture
|
|
local TLx_, TLy_, BLx_, BLy_, TRx_, TRy_, BRx_, BRy_ = self.GetTexCoord(0, progress);
|
|
self.fg:SetTexCoord(TLx_, TLy_, BLx_, BLy_, TRx_, TRy_, BRx_, BRy_);
|
|
|
|
local sparkHidden = self.spark.sparkHidden;
|
|
local sparkVisible = sparkHidden == "NEVER"
|
|
or (sparkHidden == "FULL" and progress < 1)
|
|
or (sparkHidden == "EMPTY" and progress > 0)
|
|
or (sparkHidden == "BOTH" and progress < 1 and progress > 0);
|
|
|
|
if (sparkVisible) then
|
|
self.spark:Show();
|
|
else
|
|
self.spark:Hide();
|
|
end
|
|
end,
|
|
|
|
["UpdateAdditionalBars"] = function(self)
|
|
if (type(self.additionalBars) == "table") then
|
|
for index, additionalBar in ipairs(self.additionalBars) do
|
|
if (not self.extraTextures[index]) then
|
|
local extraTexture = self:CreateTexture(nil, "ARTWORK");
|
|
extraTexture:SetDrawLayer("ARTWORK", min(index, 7));
|
|
self.extraTextures[index] = extraTexture;
|
|
end
|
|
|
|
local extraTexture = self.extraTextures[index];
|
|
|
|
local valueStart = self.additionalBarsMin
|
|
local valueWidth = self.additionalBarsMax - valueStart;
|
|
|
|
local startProgress = 0;
|
|
local endProgress = 0;
|
|
|
|
if (additionalBar.min and additionalBar.max) then
|
|
if (valueWidth ~= 0) then
|
|
startProgress = (additionalBar.min - valueStart) / valueWidth;
|
|
endProgress = (additionalBar.max - valueStart) / valueWidth;
|
|
|
|
if (self.additionalBarsInverse) then
|
|
startProgress = 1 - startProgress;
|
|
endProgress = 1 - endProgress;
|
|
end
|
|
end
|
|
elseif (additionalBar.direction) then
|
|
local forwardDirection = (additionalBar.direction or "forward") == "forward";
|
|
if (self.additionalBarsInverse) then
|
|
forwardDirection = not forwardDirection;
|
|
end
|
|
|
|
local width = additionalBar.width or 0;
|
|
local offset = additionalBar.offset or 0;
|
|
|
|
if (width ~= 0 and valueWidth ~= 0) then
|
|
if (forwardDirection) then
|
|
startProgress = self.value + offset / valueWidth;
|
|
endProgress = self.value + (width + offset) / valueWidth;
|
|
else
|
|
startProgress = self.value - (width + offset) / valueWidth;
|
|
endProgress = self.value - offset / valueWidth;
|
|
end
|
|
end
|
|
end
|
|
|
|
if (self.additionalBarsClip) then
|
|
startProgress = max(0, min(1, startProgress));
|
|
endProgress = max(0, min(1, endProgress));
|
|
else
|
|
startProgress = max(-10, min(11, startProgress));
|
|
endProgress = max(-10, min(11, endProgress));
|
|
end
|
|
|
|
if ((endProgress - startProgress) == 0) then
|
|
extraTexture:Hide();
|
|
else
|
|
extraTexture:Show();
|
|
local TLx_, TLy_, BLx_, BLy_, TRx_, TRy_, BRx_, BRy_ = self.GetTexCoord(startProgress, endProgress);
|
|
extraTexture:SetTexCoord(TLx_, TLy_, BLx_, BLy_, TRx_, TRy_, BRx_, BRy_);
|
|
|
|
local color = self.additionalBarsColors and self.additionalBarsColors[index];
|
|
if (color) then
|
|
extraTexture:SetVertexColor(unpack(color));
|
|
else
|
|
extraTexture:SetVertexColor(1, 1, 1, 1);
|
|
end
|
|
|
|
local texture = self.additionalBarsTextures and self.additionalBarsTextures[index];
|
|
if texture then
|
|
local texturePath = SharedMedia:Fetch("statusbar", texture) or ""
|
|
extraTexture:SetTexture(texturePath)
|
|
else
|
|
extraTexture:SetTexture(self:GetStatusBarTexture());
|
|
end
|
|
|
|
local xOffset = 0;
|
|
local yOffset = 0;
|
|
local width, height = self:GetRealSize()
|
|
if (self.horizontal) then
|
|
xOffset = startProgress * width;
|
|
local width = (endProgress - startProgress) * width;
|
|
extraTexture:SetWidth( width );
|
|
extraTexture:SetHeight( height );
|
|
else
|
|
yOffset = startProgress * height;
|
|
local height = (endProgress - startProgress) * height;
|
|
extraTexture:SetWidth( width );
|
|
extraTexture:SetHeight( height );
|
|
end
|
|
|
|
if (self.directionInverse) then
|
|
xOffset = -xOffset;
|
|
yOffset = -yOffset;
|
|
end
|
|
|
|
extraTexture:ClearAllPoints();
|
|
extraTexture:SetPoint(self.align1, self, self.align1, xOffset, yOffset);
|
|
extraTexture:SetPoint(self.align2, self, self.align2, xOffset, yOffset);
|
|
end
|
|
end
|
|
|
|
if (#self.additionalBars < #self.extraTextures) then
|
|
for i = #self.additionalBars + 1, #self.extraTextures do
|
|
self.extraTextures[i]:Hide();
|
|
end
|
|
end
|
|
else
|
|
for i = 1, #self.extraTextures do
|
|
self.extraTextures[i]:Hide();
|
|
end
|
|
end
|
|
end,
|
|
["Update"] = function(self)
|
|
self:UpdateAnchors();
|
|
self:UpdateProgress();
|
|
self:UpdateAdditionalBars();
|
|
end,
|
|
|
|
-- Need to update progress!
|
|
["OnSizeChanged"] = function(self, width, height)
|
|
self:UpdateProgress();
|
|
self:UpdateAdditionalBars();
|
|
self:GetParent().subRegionEvents:Notify("OnRegionSizeChanged")
|
|
end,
|
|
|
|
-- Blizzard like SetMinMaxValues
|
|
["SetMinMaxValues"] = function(self, minVal, maxVal)
|
|
local update = false;
|
|
if minVal and type(minVal) == "number" then
|
|
self.min = minVal;
|
|
update = true;
|
|
end
|
|
|
|
if maxVal and type(maxVal) == "number" then
|
|
self.max = maxVal;
|
|
update = true;
|
|
end
|
|
|
|
if update then
|
|
self:UpdateProgress();
|
|
self:UpdateAdditionalBars();
|
|
end
|
|
end,
|
|
|
|
["GetMinMaxValues"] = function(self)
|
|
return self.min, self.max
|
|
end,
|
|
|
|
-- Blizzard like SetValue
|
|
["SetValue"] = function(self, value)
|
|
if value and type(value) == "number" then
|
|
self.value = value;
|
|
self:UpdateProgress();
|
|
self:UpdateAdditionalBars();
|
|
end
|
|
end,
|
|
|
|
["SetAdditionalBars"] = function(self, additionalBars, colors, textures, min, max, inverse, overlayclip)
|
|
self.additionalBars = additionalBars;
|
|
self.additionalBarsColors = colors;
|
|
self.additionalBarsTextures = textures;
|
|
self.additionalBarsMin = min or 0;
|
|
self.additionalBarsMax = max or 0;
|
|
self.additionalBarsInverse = inverse;
|
|
self.additionalBarsClip = overlayclip;
|
|
self:UpdateAdditionalBars();
|
|
end,
|
|
|
|
["GetAdditionalBarsInverse"] = function(self)
|
|
return self.additionalBarsInverse
|
|
end,
|
|
|
|
["SetAdditionalBarsInverse"] = function(self, value)
|
|
self.additionalBarsInverse = value;
|
|
self:UpdateAdditionalBars();
|
|
end,
|
|
|
|
["SetAdditionalBarColor"] = function(self, id, color)
|
|
self.additionalBarsColors[id] = color;
|
|
if self.extraTextures[id] then
|
|
self.extraTextures[id]:SetVertexColor(unpack(color));
|
|
end
|
|
end,
|
|
|
|
["GetValue"] = function(self)
|
|
return self.value;
|
|
end,
|
|
|
|
-- Blizzard like SetOrientation (added: HORIZONTAL_INVERSE, VERTICAL_INVERSE)
|
|
["SetOrientation"] = function(self, orientation)
|
|
if orientation == "HORIZONTAL"
|
|
or orientation == "HORIZONTAL_INVERSE"
|
|
or orientation == "VERTICAL"
|
|
or orientation == "VERTICAL_INVERSE"
|
|
then
|
|
self.orientation = orientation;
|
|
self:Update();
|
|
end
|
|
end,
|
|
|
|
["GetOrientation"] = function(self)
|
|
return self.orientation;
|
|
end,
|
|
|
|
-- Blizzard like SetRotatesTexture (added: flip texture for right->left, bottom->top)
|
|
["SetRotatesTexture"] = function(self, rotate)
|
|
if rotate and type(rotate) == "boolean" then
|
|
self.rotate = rotate;
|
|
self:Update();
|
|
end
|
|
end,
|
|
|
|
["GetRotatesTexture"] = function(self)
|
|
return self.rotate;
|
|
end,
|
|
|
|
-- Blizzard like SetStatusBarTexture
|
|
["SetStatusBarTexture"] = function(self, texture)
|
|
self.fg:SetTexture(texture);
|
|
self.bg:SetTexture(texture);
|
|
for index, extraTexture in ipairs(self.extraTextures) do
|
|
extraTexture:SetTexture(texture);
|
|
end
|
|
end,
|
|
|
|
["GetStatusBarTexture"] = function(self)
|
|
return self.fg:GetTexture();
|
|
end,
|
|
|
|
-- Set bar color
|
|
["SetForegroundColor"] = function(self, r, g, b, a)
|
|
self.fg:SetVertexColor(r, g, b, a);
|
|
end,
|
|
|
|
["GetForegroundColor"] = function(self)
|
|
return self.fg:GetVertexColor();
|
|
end,
|
|
|
|
-- Set background color
|
|
["SetBackgroundColor"] = function(self, r, g, b, a)
|
|
self.bg:SetVertexColor(r, g, b, a);
|
|
end,
|
|
|
|
["GetBackgroundColor"] = function(self)
|
|
return self.bg:GetVertexColor();
|
|
end,
|
|
|
|
-- Convenience methods
|
|
["SetTexture"] = function(self, texture)
|
|
self:SetStatusBarTexture(texture);
|
|
end,
|
|
|
|
["GetTexture"] = function(self)
|
|
return self:GetStatusBarTexture();
|
|
end,
|
|
|
|
["SetVertexColor"] = function(self, r, g, b, a)
|
|
self:SetForegroundColor(r, g, b, a);
|
|
end,
|
|
|
|
["GetVertexColor"] = function(self)
|
|
return self.fg:GetVertexColor();
|
|
end,
|
|
|
|
["GetRealSize"] = function(self)
|
|
return 0, 0
|
|
end,
|
|
|
|
-- Internal variables
|
|
["min"] = 0,
|
|
["max"] = 1,
|
|
["value"] = 0.5,
|
|
["rotate"] = true,
|
|
["orientation"] = "HORIZONTAL",
|
|
}
|
|
|
|
local GetRealSize = {
|
|
["HORIZONTAL"] = {
|
|
[true] = function(self)
|
|
return self.totalWidth - self.iconWidth, self.totalHeight
|
|
end,
|
|
[false] = function(self)
|
|
return self.totalWidth, self.totalHeight
|
|
end
|
|
},
|
|
["VERTICAL"] = {
|
|
[true] = function(self)
|
|
return self.totalWidth, self.totalHeight - self.iconHeight
|
|
end,
|
|
[false] = function(self)
|
|
return self.totalWidth, self.totalHeight
|
|
end
|
|
},
|
|
}
|
|
|
|
-- Orientation helper methods
|
|
local function orientHorizontalInverse(region)
|
|
-- Localize
|
|
local bar, icon = region.bar, region.icon;
|
|
|
|
-- Reset
|
|
icon:ClearAllPoints();
|
|
bar:ClearAllPoints();
|
|
|
|
bar.GetRealSize = GetRealSize["HORIZONTAL"][region.iconVisible or false]
|
|
|
|
-- Align icon and bar
|
|
if region.iconVisible then
|
|
if region.icon_side == "LEFT" then
|
|
icon:SetPoint("LEFT", region, "LEFT");
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", icon, "TOPRIGHT");
|
|
else
|
|
icon:SetPoint("RIGHT", region, "RIGHT");
|
|
bar:SetPoint("BOTTOMLEFT", region, "BOTTOMLEFT");
|
|
bar:SetPoint("TOPRIGHT", icon, "TOPLEFT");
|
|
end
|
|
else
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", region, "TOPLEFT");
|
|
end
|
|
|
|
-- Save orientation
|
|
bar:SetOrientation(region.effectiveOrientation);
|
|
end
|
|
|
|
local function orientHorizontal(region)
|
|
-- Localize
|
|
local bar, icon = region.bar, region.icon;
|
|
|
|
bar.GetRealSize = GetRealSize["HORIZONTAL"][region.iconVisible or false]
|
|
|
|
-- Reset
|
|
icon:ClearAllPoints();
|
|
bar:ClearAllPoints();
|
|
|
|
-- Align icon and bar
|
|
if region.iconVisible then
|
|
if region.icon_side == "LEFT" then
|
|
icon:SetPoint("LEFT", region, "LEFT");
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", icon, "TOPRIGHT");
|
|
else
|
|
icon:SetPoint("RIGHT", region, "RIGHT");
|
|
bar:SetPoint("BOTTOMLEFT", region, "BOTTOMLEFT");
|
|
bar:SetPoint("TOPRIGHT", icon, "TOPLEFT");
|
|
end
|
|
else
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", region, "TOPLEFT");
|
|
end
|
|
|
|
-- Save orientation
|
|
bar:SetOrientation(region.effectiveOrientation);
|
|
end
|
|
|
|
local function orientVerticalInverse(region)
|
|
-- Localize
|
|
local bar, icon = region.bar, region.icon;
|
|
|
|
bar.GetRealSize = GetRealSize["VERTICAL"][region.iconVisible or false]
|
|
|
|
-- Reset
|
|
icon:ClearAllPoints();
|
|
bar:ClearAllPoints();
|
|
|
|
-- Align icon and bar
|
|
if region.iconVisible then
|
|
if region.icon_side == "LEFT" then
|
|
icon:SetPoint("TOP", region, "TOP");
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", icon, "BOTTOMLEFT");
|
|
else
|
|
icon:SetPoint("BOTTOM", region, "BOTTOM");
|
|
bar:SetPoint("TOPRIGHT", region, "TOPRIGHT");
|
|
bar:SetPoint("BOTTOMLEFT", icon, "TOPLEFT");
|
|
end
|
|
else
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", region, "TOPLEFT");
|
|
end
|
|
|
|
-- Save orientation
|
|
bar:SetOrientation("VERTICAL_INVERSE");
|
|
end
|
|
|
|
local function orientVertical(region)
|
|
-- Localize
|
|
local bar, icon = region.bar, region.icon;
|
|
|
|
bar.GetRealSize = GetRealSize["VERTICAL"][region.iconVisible or false]
|
|
|
|
-- Reset
|
|
icon:ClearAllPoints();
|
|
bar:ClearAllPoints();
|
|
|
|
-- Align icon and bar
|
|
if region.iconVisible then
|
|
if region.icon_side == "LEFT" then
|
|
icon:SetPoint("TOP", region, "TOP");
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", icon, "BOTTOMLEFT");
|
|
else
|
|
icon:SetPoint("BOTTOM", region, "BOTTOM");
|
|
bar:SetPoint("TOPRIGHT", region, "TOPRIGHT");
|
|
bar:SetPoint("BOTTOMLEFT", icon, "TOPLEFT");
|
|
end
|
|
else
|
|
bar:SetPoint("BOTTOMRIGHT", region, "BOTTOMRIGHT");
|
|
bar:SetPoint("TOPLEFT", region, "TOPLEFT");
|
|
end
|
|
|
|
-- Save orientation
|
|
bar:SetOrientation("VERTICAL");
|
|
end
|
|
|
|
local function GetTexCoordZoom(texWidth)
|
|
local texCoord = {texWidth, texWidth, texWidth, 1 - texWidth, 1 - texWidth, texWidth, 1 - texWidth, 1 - texWidth}
|
|
return unpack(texCoord)
|
|
end
|
|
|
|
local funcs = {
|
|
AnchorSubRegion = function(self, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset)
|
|
if anchorType == "area" then
|
|
local anchor = self
|
|
if selfPoint == "bar" then
|
|
anchor = self
|
|
elseif selfPoint == "icon" then
|
|
anchor = self.icon
|
|
elseif selfPoint == "fg" then
|
|
anchor = self.bar.fgFrame
|
|
elseif selfPoint == "bg" then
|
|
anchor = self.bar.bg
|
|
end
|
|
|
|
anchorXOffset = anchorXOffset or 0
|
|
anchorYOffset = anchorYOffset or 0
|
|
subRegion:ClearAllPoints()
|
|
subRegion:SetPoint("bottomleft", anchor, "bottomleft", -anchorXOffset, -anchorYOffset)
|
|
subRegion:SetPoint("topright", anchor, "topright", anchorXOffset, anchorYOffset)
|
|
else
|
|
subRegion:ClearAllPoints()
|
|
anchorPoint = anchorPoint or "CENTER"
|
|
|
|
local anchorRegion = self.bar
|
|
|
|
anchorXOffset = anchorXOffset or 0
|
|
anchorYOffset = anchorYOffset or 0
|
|
|
|
if anchorPoint:sub(1, 5) == "ICON_" then
|
|
anchorRegion = self.icon
|
|
anchorPoint = anchorPoint:sub(6)
|
|
elseif anchorPoint:sub(1, 6) == "INNER_" then
|
|
anchorPoint = anchorPoint:sub(7)
|
|
|
|
if anchorPoint:find("LEFT", 1, true) then
|
|
anchorXOffset = anchorXOffset + 2
|
|
elseif anchorPoint:find("RIGHT", 1, true) then
|
|
anchorXOffset = anchorXOffset - 2
|
|
end
|
|
|
|
if anchorPoint:find("TOP", 1, true) then
|
|
anchorYOffset = anchorYOffset - 2
|
|
elseif anchorPoint:find("BOTTOM", 1, true) then
|
|
anchorYOffset = anchorYOffset + 2
|
|
end
|
|
elseif anchorPoint == "SPARK" then
|
|
anchorRegion = self.bar.spark
|
|
anchorPoint = "CENTER"
|
|
end
|
|
|
|
selfPoint = selfPoint or "CENTER"
|
|
|
|
if not Private.point_types[selfPoint] then
|
|
selfPoint = "CENTER"
|
|
end
|
|
|
|
if not Private.point_types[anchorPoint] then
|
|
anchorPoint = "CENTER"
|
|
end
|
|
|
|
subRegion:SetPoint(selfPoint, anchorRegion, anchorPoint, anchorXOffset, anchorYOffset)
|
|
end
|
|
end,
|
|
SetIconColor = function(self, r, g, b, a)
|
|
self.icon_color = {r, g, b, a}
|
|
self.icon:SetVertexColor(r, g, b, a);
|
|
end,
|
|
SetIconDesaturated = function(self, b)
|
|
self.desaturateIcon = b
|
|
self.icon:SetDesaturated(b);
|
|
end,
|
|
SetBackgroundColor = function (self, r, g, b, a)
|
|
self.bar:SetBackgroundColor(r, g, b, a);
|
|
end,
|
|
SetSparkColor = function(self, r, g, b, a)
|
|
self.bar.spark:SetVertexColor(r, g, b, a);
|
|
end,
|
|
SetSparkHeight = function(self, height)
|
|
self.bar.spark:SetHeight(height);
|
|
end,
|
|
SetSparkWidth = function(self, width)
|
|
self.bar.spark:SetWidth(width);
|
|
end,
|
|
SetRegionWidth = function(self, width)
|
|
self.width = width;
|
|
self:Scale(self.scalex, self.scaley);
|
|
end,
|
|
SetRegionHeight = function(self, height)
|
|
self.height = height;
|
|
self:Scale(self.scalex, self.scaley);
|
|
end,
|
|
SetValue = function(self, value, total)
|
|
local progress = 0;
|
|
if (total ~= 0) then
|
|
progress = value / total;
|
|
end
|
|
|
|
if self.inverseDirection then
|
|
progress = 1 - progress;
|
|
end
|
|
|
|
if (self.smoothProgress) then
|
|
self.bar.targetValue = progress
|
|
self.bar:SetSmoothedValue(progress);
|
|
else
|
|
self.bar:SetValue(progress);
|
|
end
|
|
end,
|
|
SetTime = function(self, duration, expirationTime, inverse)
|
|
local remaining = expirationTime - GetTime();
|
|
local progress = duration ~= 0 and remaining / duration or 0;
|
|
-- Need to invert?
|
|
if (
|
|
(self.inverseDirection and not inverse)
|
|
or (inverse and not self.inverseDirection)
|
|
)
|
|
then
|
|
progress = 1 - progress;
|
|
end
|
|
if (self.smoothProgress) then
|
|
self.bar.targetValue = progress
|
|
self.bar:SetSmoothedValue(progress);
|
|
else
|
|
self.bar:SetValue(progress);
|
|
end
|
|
end,
|
|
SetInverse = function(self, inverse)
|
|
if (self.inverseDirection == inverse) then
|
|
return;
|
|
end
|
|
self.inverseDirection = inverse;
|
|
if (self.smoothProgress) then
|
|
if (self.bar.targetValue) then
|
|
self.bar.targetValue = 1 - self.bar.targetValue
|
|
self.bar:SetSmoothedValue(self.bar.targetValue);
|
|
end
|
|
else
|
|
self.bar:SetValue(1 - self.bar:GetValue());
|
|
end
|
|
self.bar:SetAdditionalBarsInverse(not self.bar:GetAdditionalBarsInverse())
|
|
self.subRegionEvents:Notify("InverseChanged")
|
|
end,
|
|
SetOrientation = function(self, orientation)
|
|
self.orientation = orientation
|
|
self:UpdateEffectiveOrientation()
|
|
if (self.smoothProgress) then
|
|
if self.bar.targetValue then
|
|
self.bar:SetSmoothedValue(self.bar.targetValue);
|
|
end
|
|
else
|
|
self.bar:SetValue(self.bar:GetValue());
|
|
end
|
|
end,
|
|
|
|
SetIconVisible = function(self, iconVisible)
|
|
if (self.iconVisible == iconVisible) then
|
|
return
|
|
end
|
|
|
|
self.iconVisible = iconVisible
|
|
|
|
local icon = self.icon
|
|
if self.iconVisible then
|
|
-- Update icon
|
|
local iconsize = math.min(self.height, self.width);
|
|
icon:SetWidth(iconsize);
|
|
icon:SetHeight(iconsize);
|
|
self.bar.iconWidth = iconsize
|
|
self.bar.iconHeight = iconsize
|
|
local texWidth = 0.25 * self.zoom;
|
|
icon:SetTexCoord(GetTexCoordZoom(texWidth))
|
|
icon:SetDesaturated(self.desaturateIcon);
|
|
icon:SetVertexColor(self.icon_color[1], self.icon_color[2], self.icon_color[3], self.icon_color[4]);
|
|
|
|
-- Update icon visibility
|
|
icon:Show();
|
|
else
|
|
self.bar.iconWidth = 0
|
|
self.bar.iconHeight = 0
|
|
icon:Hide();
|
|
end
|
|
|
|
self:ReOrient()
|
|
self.subRegionEvents:Notify("OrientationChanged")
|
|
end,
|
|
SetIcon = function(self, iconPath)
|
|
if self.displayIcon == iconPath then
|
|
return
|
|
end
|
|
self.displayIcon = iconPath
|
|
self:UpdateIcon()
|
|
end,
|
|
SetIconSource = function(self, source)
|
|
if self.iconSource == source then
|
|
return
|
|
end
|
|
|
|
self.iconSource = source
|
|
self:UpdateIcon()
|
|
end,
|
|
UpdateIcon = function(self)
|
|
local iconPath
|
|
if self.iconSource == -1 then
|
|
iconPath = self.state.icon
|
|
elseif self.iconSource == 0 then
|
|
iconPath = self.displayIcon
|
|
else
|
|
local triggernumber = self.iconSource
|
|
if triggernumber and self.states[triggernumber] then
|
|
iconPath = self.states[triggernumber].icon
|
|
end
|
|
end
|
|
|
|
iconPath = iconPath or self.displayIcon or "Interface\\Icons\\INV_Misc_QuestionMark"
|
|
self.icon:SetTexture(iconPath)
|
|
end,
|
|
SetOverlayColor = function(self, id, r, g, b, a)
|
|
self.bar:SetAdditionalBarColor(id, { r, g, b, a});
|
|
end,
|
|
GetEffectiveOrientation = function(self)
|
|
return self.effectiveOrientation
|
|
end,
|
|
GetInverse = function(self)
|
|
return self.inverseDirection
|
|
end,
|
|
ReOrient = function(self)
|
|
if self.effectiveOrientation == "HORIZONTAL_INVERSE" then
|
|
orientHorizontalInverse(self);
|
|
elseif self.effectiveOrientation == "HORIZONTAL" then
|
|
orientHorizontal(self);
|
|
elseif self.effectiveOrientation == "VERTICAL_INVERSE" then
|
|
orientVerticalInverse(self);
|
|
elseif self.effectiveOrientation == "VERTICAL" then
|
|
orientVertical(self);
|
|
end
|
|
end,
|
|
UpdateEffectiveOrientation = function(self, force)
|
|
local orientation = self.orientation
|
|
|
|
if self.flipX then
|
|
if self.orientation == "HORIZONTAL" then
|
|
orientation = "HORIZONTAL_INVERSE"
|
|
elseif self.orientation == "HORIZONTAL_INVERSE" then
|
|
orientation = "HORIZONTAL"
|
|
end
|
|
end
|
|
if self.flipY then
|
|
if self.orientation == "VERTICAL" then
|
|
orientation = "VERTICAL_INVERSE"
|
|
elseif self.orientation == "VERTICAL_INVERSE" then
|
|
orientation = "VERTICAL"
|
|
end
|
|
end
|
|
|
|
if orientation ~= self.effectiveOrientation or force then
|
|
self.effectiveOrientation = orientation
|
|
self:ReOrient()
|
|
end
|
|
|
|
self.subRegionEvents:Notify("OrientationChanged")
|
|
end
|
|
}
|
|
|
|
local function setDesaturated(self, desaturated, ...)
|
|
self.isDesaturated = desaturated and 1 or 0
|
|
return self._SetDesaturated(self, desaturated, ...)
|
|
end
|
|
|
|
local function setTexture(self, ...)
|
|
local apply = self._SetTexture(self, ...)
|
|
if self.isDesaturated ~= nil then
|
|
self:_SetDesaturated(self.isDesaturated)
|
|
end
|
|
return apply
|
|
end
|
|
|
|
-- Called when first creating a new region/display
|
|
local function create(parent)
|
|
-- Create overall region (containing everything else)
|
|
local region = CreateFrame("Frame", nil, parent);
|
|
region.regionType = "aurabar"
|
|
region:SetMovable(true);
|
|
region:SetResizable(true);
|
|
region:SetMinResize(1, 1);
|
|
|
|
-- Create statusbar (inherit prototype)
|
|
local bar = CreateFrame("Frame", nil, region);
|
|
WeakAuras.Mixin(bar, SmoothStatusBarMixin);
|
|
local fg = bar:CreateTexture(nil, "BORDER");
|
|
local bg = bar:CreateTexture(nil, "BACKGROUND");
|
|
bg:SetAllPoints();
|
|
local fgFrame = CreateFrame("Frame", nil, bar)
|
|
local spark = bar:CreateTexture(nil, "ARTWORK");
|
|
bar.fg = fg;
|
|
bar.fgFrame = fgFrame
|
|
bar.bg = bg;
|
|
bar.spark = spark;
|
|
for key, value in pairs(barPrototype) do
|
|
bar[key] = value;
|
|
end
|
|
bar.extraTextures = {};
|
|
bar:SetRotatesTexture(true);
|
|
bar:HookScript("OnSizeChanged", bar.OnSizeChanged);
|
|
region.bar = bar;
|
|
|
|
-- Create icon
|
|
local iconFrame = CreateFrame("Frame", nil, region);
|
|
region.iconFrame = iconFrame;
|
|
local icon = iconFrame:CreateTexture(nil, "OVERLAY");
|
|
region.icon = icon;
|
|
icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark");
|
|
|
|
icon._SetDesaturated = icon.SetDesaturated
|
|
icon.SetDesaturated = setDesaturated
|
|
icon._SetTexture = icon.SetTexture
|
|
icon.SetTexture = setTexture
|
|
|
|
local oldSetFrameLevel = region.SetFrameLevel;
|
|
function region.SetFrameLevel(self, frameLevel)
|
|
oldSetFrameLevel(self, frameLevel);
|
|
|
|
if (self.__WAGlowFrame) then
|
|
self.__WAGlowFrame:SetFrameLevel(frameLevel + 5);
|
|
end
|
|
end
|
|
|
|
WeakAuras.regionPrototype.create(region);
|
|
|
|
for k, f in pairs(funcs) do
|
|
region[k] = f
|
|
end
|
|
|
|
-- Return new display/region
|
|
return region;
|
|
end
|
|
|
|
local function TimerTick(self)
|
|
local state = self.state
|
|
local duration = state.duration or 0
|
|
local adjustMin = self.adjustedMin or self.adjustedMinRel or 0;
|
|
local expirationTime = state.expirationTime and state.expirationTime > 0 and state.expirationTime or math.huge;
|
|
self:SetTime((duration ~= 0 and (self.adjustedMax or self.adjustedMaxRel) or duration) - adjustMin, expirationTime - adjustMin, state.inverse);
|
|
end
|
|
|
|
-- Modify a given region/display
|
|
local function modify(parent, region, data)
|
|
region.timer = nil
|
|
region.text = nil
|
|
region.stacks = nil
|
|
|
|
WeakAuras.regionPrototype.modify(parent, region, data);
|
|
-- Localize
|
|
local bar, iconFrame, icon = region.bar, region.iconFrame, region.icon;
|
|
|
|
region.iconSource = data.iconSource
|
|
region.displayIcon = data.displayIcon
|
|
|
|
-- Adjust region size
|
|
region:SetWidth(data.width);
|
|
region:SetHeight(data.height);
|
|
region.bar.totalWidth = data.width
|
|
region.bar.totalHeight = data.height
|
|
|
|
region.width = data.width;
|
|
region.height = data.height;
|
|
region.scalex = 1;
|
|
region.scaley = 1;
|
|
region.flipX = false
|
|
region.flipY = false
|
|
region.orientation = data.orientation
|
|
region.effectiveOrientation = nil
|
|
|
|
region.overlayclip = data.overlayclip;
|
|
region.iconVisible = data.icon
|
|
region.icon_side = data.icon_side
|
|
region.icon_color = CopyTable(data.icon_color)
|
|
region.desaturateIcon = data.desaturate
|
|
region.zoom = data.zoom
|
|
|
|
if (data.overlays) then
|
|
region.overlays = CopyTable(data.overlays);
|
|
else
|
|
region.overlays = {}
|
|
end
|
|
if data.overlaysTexture then
|
|
region.overlaysTexture = CopyTable(data.overlaysTexture)
|
|
else
|
|
region.overlaysTexture = {}
|
|
end
|
|
|
|
-- Update texture settings
|
|
local texturePath = SharedMedia:Fetch("statusbar", data.texture) or "";
|
|
bar:SetStatusBarTexture(texturePath);
|
|
bar:SetBackgroundColor(data.backgroundColor[1], data.backgroundColor[2], data.backgroundColor[3], data.backgroundColor[4]);
|
|
-- Update spark settings
|
|
bar.spark:SetTexture(data.sparkTexture);
|
|
bar.spark:SetVertexColor(data.sparkColor[1], data.sparkColor[2], data.sparkColor[3], data.sparkColor[4]);
|
|
bar.spark:SetWidth(data.sparkWidth);
|
|
bar.spark:SetHeight(data.sparkHeight);
|
|
bar.spark.sparkHidden = data.spark and data.sparkHidden or "ALWAYS";
|
|
bar.spark:SetBlendMode(data.sparkBlendMode);
|
|
bar.spark:SetDesaturated(data.sparkDesaturate);
|
|
bar.spark.sparkOffsetX = data.sparkOffsetX;
|
|
bar.spark.sparkOffsetY = data.sparkOffsetY;
|
|
bar.spark.sparkRotationMode = data.sparkRotationMode;
|
|
bar.spark.sparkRotation = data.sparkRotation;
|
|
bar.spark.sparkMirror = data.sparkMirror;
|
|
|
|
-- Color update function
|
|
region.Color = region.Color or function(self, r, g, b, a)
|
|
self.color_r = r;
|
|
self.color_g = g;
|
|
self.color_b = b;
|
|
self.color_a = a;
|
|
self.bar:SetForegroundColor(self.color_anim_r or r, self.color_anim_g or g, self.color_anim_b or b, self.color_anim_a or a);
|
|
end
|
|
|
|
region.ColorAnim = function(self, r, g, b, a)
|
|
self.color_anim_r = r;
|
|
self.color_anim_g = g;
|
|
self.color_anim_b = b;
|
|
self.color_anim_a = a;
|
|
self.bar:SetForegroundColor(r or self.color_r, g or self.color_g, b or self.color_b, a or self.color_a);
|
|
end
|
|
|
|
region.GetColor = region.GetColor or function(self)
|
|
return self.color_r, self.color_g, self.color_b, self.color_a
|
|
end
|
|
region:Color(data.barColor[1], data.barColor[2], data.barColor[3], data.barColor[4]);
|
|
|
|
-- Update icon visibility
|
|
if region.iconVisible then
|
|
-- Update icon
|
|
local iconsize = math.min(region.height, region.width);
|
|
icon:SetWidth(iconsize);
|
|
icon:SetHeight(iconsize);
|
|
region.bar.iconWidth = iconsize
|
|
region.bar.iconHeight = iconsize
|
|
local texWidth = 0.25 * data.zoom;
|
|
icon:SetTexCoord(GetTexCoordZoom(texWidth))
|
|
icon:SetDesaturated(data.desaturate);
|
|
icon:SetVertexColor(data.icon_color[1], data.icon_color[2], data.icon_color[3], data.icon_color[4]);
|
|
|
|
-- Update icon visibility
|
|
icon:Show();
|
|
|
|
else
|
|
region.bar.iconWidth = 0
|
|
region.bar.iconHeight = 0
|
|
icon:Hide();
|
|
end
|
|
|
|
region.inverseDirection = data.inverse;
|
|
|
|
-- Apply orientation alignment
|
|
region:UpdateEffectiveOrientation()
|
|
|
|
-- Update tooltip availability
|
|
local tooltipType = Private.CanHaveTooltip(data);
|
|
if tooltipType and data.useTooltip then
|
|
-- Create and enable tooltip-hover frame
|
|
if not region.tooltipFrame then
|
|
region.tooltipFrame = CreateFrame("Frame", nil, region);
|
|
region.tooltipFrame:SetAllPoints(icon);
|
|
region.tooltipFrame:SetScript("OnEnter", function()
|
|
Private.ShowMouseoverTooltip(region, region.tooltipFrame);
|
|
end);
|
|
region.tooltipFrame:SetScript("OnLeave", Private.HideTooltip);
|
|
end
|
|
|
|
region.tooltipFrame:EnableMouse(true);
|
|
elseif region.tooltipFrame then
|
|
-- Disable tooltip
|
|
region.tooltipFrame:EnableMouse(false);
|
|
end
|
|
|
|
function region:UpdateMinMax()
|
|
local state = region.state
|
|
local min
|
|
local max
|
|
if state.progressType == "timed" then
|
|
local duration = state.duration or 0
|
|
if region.adjustedMinRelPercent then
|
|
region.adjustedMinRel = region.adjustedMinRelPercent * duration
|
|
end
|
|
|
|
min = region.adjustedMin or region.adjustedMinRel or 0;
|
|
|
|
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
|
|
elseif state.progressType == "static" then
|
|
local total = state.total or 0;
|
|
if region.adjustedMinRelPercent then
|
|
region.adjustedMinRel = region.adjustedMinRelPercent * total
|
|
end
|
|
min = region.adjustedMin or region.adjustedMinRel or 0;
|
|
|
|
if region.adjustedMax then
|
|
max = region.adjustedMax
|
|
elseif region.adjustedMaxRelPercent then
|
|
region.adjustedMaxRel = region.adjustedMaxRelPercent * total
|
|
max = region.adjustedMaxRel
|
|
else
|
|
max = total
|
|
end
|
|
end
|
|
region.currentMin, region.currentMax = min, max
|
|
end
|
|
|
|
function region:GetMinMax()
|
|
return region.currentMin or 0, region.currentMax or 0
|
|
end
|
|
|
|
function region:Update()
|
|
local state = region.state
|
|
region:UpdateMinMax()
|
|
if state.progressType == "timed" then
|
|
local expirationTime
|
|
if state.paused == true then
|
|
if not region.paused then
|
|
region:Pause()
|
|
end
|
|
if region.TimerTick then
|
|
region.TimerTick = nil
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
expirationTime = GetTime() + (state.remaining or 0)
|
|
else
|
|
if region.paused then
|
|
region:Resume()
|
|
end
|
|
if not region.TimerTick then
|
|
region.TimerTick = TimerTick
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
expirationTime = state.expirationTime and state.expirationTime > 0 and state.expirationTime or math.huge;
|
|
end
|
|
local duration = state.duration or 0
|
|
|
|
region:SetTime(region.currentMax - region.currentMin, expirationTime - region.currentMin, state.inverse);
|
|
elseif state.progressType == "static" then
|
|
if region.paused then
|
|
region:Resume()
|
|
end
|
|
local value = state.value or 0;
|
|
local total = state.total or 0;
|
|
|
|
region:SetValue(value - region.currentMin, region.currentMax - region.currentMin);
|
|
if region.TimerTick then
|
|
region.TimerTick = nil
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
else
|
|
if region.paused then
|
|
region:Resume()
|
|
end
|
|
region:SetTime(0, math.huge)
|
|
if region.TimerTick then
|
|
region.TimerTick = nil
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
end
|
|
|
|
region:UpdateIcon()
|
|
|
|
local duration = state.duration or 0
|
|
local effectiveInverse = (state.inverse and not region.inverseDirection) or (not state.inverse and region.inverseDirection);
|
|
region.bar:SetAdditionalBars(state.additionalProgress, region.overlays, region.overlaysTexture, region.currentMin, region.currentMax, effectiveInverse, region.overlayclip);
|
|
end
|
|
|
|
-- Scale update function
|
|
function region:Scale(scalex, scaley)
|
|
region.scalex = scalex;
|
|
region.scaley = scaley;
|
|
-- Icon size
|
|
local iconsize = math.min(region.height, region.width);
|
|
|
|
-- Re-orientate region
|
|
if scalex < 0 then
|
|
scalex = -scalex;
|
|
region.flipX = true
|
|
else
|
|
region.flipX = false
|
|
end
|
|
|
|
-- Update width
|
|
self.bar.totalWidth = region.width * scalex
|
|
self.bar.iconWidth = iconsize * scalex
|
|
|
|
self:SetWidth(self.bar.totalWidth);
|
|
icon:SetWidth(self.bar.iconWidth);
|
|
|
|
-- Re-orientate region
|
|
if scaley < 0 then
|
|
scaley = -scaley;
|
|
region.flipY = true
|
|
else
|
|
region.flipY = false
|
|
end
|
|
|
|
-- Update height
|
|
self.bar.totalHeight = region.height * scaley
|
|
self.bar.iconHeight = iconsize * scaley
|
|
self:SetHeight(self.bar.totalHeight);
|
|
icon:SetHeight(self.bar.iconHeight);
|
|
|
|
region:UpdateEffectiveOrientation(true)
|
|
end
|
|
-- region:Scale(1.0, 1.0);
|
|
if data.smoothProgress then
|
|
region.PreShow = function()
|
|
region.bar:ResetSmoothedValue();
|
|
end
|
|
else
|
|
region.PreShow = nil
|
|
end
|
|
|
|
region.smoothProgress = data.smoothProgress
|
|
--- Update internal bar alignment
|
|
region.bar:Update();
|
|
|
|
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
|
end
|
|
|
|
local function validate(data)
|
|
-- pre-migration
|
|
if data.subRegions then
|
|
for _, subRegionData in ipairs(data.subRegions) do
|
|
if subRegionData.type == "aurabar_bar" then
|
|
subRegionData.type = "subforeground"
|
|
end
|
|
end
|
|
end
|
|
Private.EnforceSubregionExists(data, "subforeground")
|
|
Private.EnforceSubregionExists(data, "subbackground")
|
|
end
|
|
|
|
-- Register new region type with WeakAuras
|
|
WeakAuras.RegisterRegionType("aurabar", create, modify, default, GetProperties, validate);
|