1397 lines
44 KiB
Lua
1397 lines
44 KiB
Lua
if not WeakAuras.IsCorrectVersion() then return end
|
|
|
|
local L = WeakAuras.L;
|
|
|
|
local defaultFont = WeakAuras.defaultFont
|
|
local defaultFontSize = WeakAuras.defaultFontSize
|
|
|
|
-- Credit to CommanderSirow for taking the time to properly craft the TransformPoint function
|
|
-- to the enhance the abilities of Progress Textures.
|
|
-- Also Credit to Semlar for explaining how circular progress can be shown
|
|
|
|
-- NOTES:
|
|
-- Most SetValue() changes are quite equal (among compress/non-compress)
|
|
-- (There is no GUI button for mirror_v, but mirror_h)
|
|
-- New/Used variables
|
|
-- region.user_x (0) - User defined center x-shift [-1, 1]
|
|
-- region.user_y (0) - User defined center y-shift [-1, 1]
|
|
-- region.mirror_v (false) - Mirroring along x-axis [bool]
|
|
-- region.mirror_h (false) - Mirroring along y-axis [bool]
|
|
-- region.scale (1.0) - user defined scaling [1, INF]
|
|
-- region.full_rotation (false) - Allow full rotation [bool]
|
|
|
|
local default = {
|
|
foregroundTexture = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\Aura3",
|
|
backgroundTexture = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\Aura3",
|
|
desaturateBackground = false,
|
|
desaturateForeground = false,
|
|
sameTexture = true,
|
|
compress = false,
|
|
blendMode = "BLEND",
|
|
textureWrapMode = "CLAMP",
|
|
backgroundOffset = 2,
|
|
width = 200,
|
|
height = 200,
|
|
orientation = "VERTICAL",
|
|
inverse = false,
|
|
foregroundColor = {1, 1, 1, 1},
|
|
backgroundColor = {0.5, 0.5, 0.5, 0.5},
|
|
startAngle = 0,
|
|
endAngle = 360,
|
|
user_x = 0,
|
|
user_y = 0,
|
|
crop_x = 0.41,
|
|
crop_y = 0.41,
|
|
rotation = 0,
|
|
selfPoint = "CENTER",
|
|
anchorPoint = "CENTER",
|
|
anchorFrameType = "SCREEN",
|
|
xOffset = 0,
|
|
yOffset = 0,
|
|
font = defaultFont,
|
|
fontSize = defaultFontSize,
|
|
mirror = false,
|
|
frameStrata = 1,
|
|
slantMode = "INSIDE"
|
|
};
|
|
|
|
WeakAuras.regionPrototype.AddAlphaToDefault(default);
|
|
|
|
WeakAuras.regionPrototype.AddAdjustedDurationToDefault(default);
|
|
|
|
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
|
|
|
local properties = {
|
|
desaturateForeground = {
|
|
display = L["Desaturate Foreground"],
|
|
setter = "SetForegroundDesaturated",
|
|
type = "bool",
|
|
},
|
|
desaturateBackground = {
|
|
display = L["Desaturate Background"],
|
|
setter = "SetBackgroundDesaturated",
|
|
type = "bool",
|
|
},
|
|
foregroundColor = {
|
|
display = L["Foreground Color"],
|
|
setter = "Color",
|
|
type = "color"
|
|
},
|
|
backgroundColor = {
|
|
display = L["Background Color"],
|
|
setter = "SetBackgroundColor",
|
|
type = "color"
|
|
},
|
|
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 = WeakAuras.orientation_with_circle_types
|
|
},
|
|
inverse = {
|
|
display = L["Inverse"],
|
|
setter = "SetInverse",
|
|
type = "bool"
|
|
},
|
|
mirror = {
|
|
display = L["Mirror"],
|
|
setter = "SetMirror",
|
|
type = "bool"
|
|
}
|
|
}
|
|
|
|
WeakAuras.regionPrototype.AddProperties(properties, default);
|
|
|
|
local function GetProperties(data)
|
|
local overlayInfo = WeakAuras.GetOverlayInfo(data);
|
|
if (overlayInfo and next(overlayInfo)) then
|
|
local auraProperties = {};
|
|
WeakAuras.DeepCopy(properties, auraProperties);
|
|
|
|
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
|
|
|
|
return auraProperties;
|
|
else
|
|
return CopyTable(properties);
|
|
end
|
|
end
|
|
|
|
local spinnerFunctions = {};
|
|
|
|
function spinnerFunctions.SetTexture(self, texture)
|
|
for i = 1, 3 do
|
|
WeakAuras.SetTexture(self.textures[i], texture)
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.SetDesaturated(self, desaturate)
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetDesaturated(desaturate);
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.SetBlendMode(self, blendMode)
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetBlendMode(blendMode);
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.Show(self)
|
|
for i = 1, 3 do
|
|
self.textures[i]:Show();
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.Hide(self)
|
|
for i = 1, 3 do
|
|
self.textures[i]:Hide();
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.Color(self, r, g, b, a)
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetVertexColor(r, g, b, a);
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.UpdateSize(self)
|
|
if (self.region) then
|
|
self:SetProgress(self.region, self.angle1, self.angle2);
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.SetProgress(self, region, angle1, angle2)
|
|
self.region = region;
|
|
self.angle1 = angle1;
|
|
self.angle2 = angle2;
|
|
|
|
local crop_x = region.crop_x or 1;
|
|
local crop_y = region.crop_y or 1;
|
|
local rotation = region.rotation or 0;
|
|
local mirror_h = region.mirror_h or false;
|
|
if region.mirror then
|
|
mirror_h = not mirror_h
|
|
end
|
|
local mirror_v = region.mirror_v or false;
|
|
|
|
local width = region.width * (region.scalex or 1) + 2 * self.offset;
|
|
local height = region.height * (region.scaley or 1) + 2 * self.offset;
|
|
|
|
if (angle2 - angle1 >= 360) then
|
|
-- SHOW everything
|
|
self.coords[1]:SetFull();
|
|
self.coords[1]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[1]:Show();
|
|
|
|
self.coords[2]:Hide();
|
|
self.coords[3]:Hide();
|
|
return;
|
|
end
|
|
if (angle1 == angle2) then
|
|
self.coords[1]:Hide();
|
|
self.coords[2]:Hide();
|
|
self.coords[3]:Hide();
|
|
return;
|
|
end
|
|
|
|
local index1 = floor((angle1 + 45) / 90);
|
|
local index2 = floor((angle2 + 45) / 90);
|
|
|
|
if (index1 + 1 >= index2) then
|
|
self.coords[1]:SetAngle(width, height, angle1, angle2);
|
|
self.coords[1]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[1]:Show();
|
|
self.coords[2]:Hide();
|
|
self.coords[3]:Hide();
|
|
elseif(index1 + 3 >= index2) then
|
|
local firstEndAngle = (index1 + 1) * 90 + 45;
|
|
self.coords[1]:SetAngle(width, height, angle1, firstEndAngle);
|
|
self.coords[1]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[1]:Show();
|
|
|
|
self.coords[2]:SetAngle(width, height, firstEndAngle, angle2);
|
|
self.coords[2]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[2]:Show();
|
|
|
|
self.coords[3]:Hide();
|
|
else
|
|
local firstEndAngle = (index1 + 1) * 90 + 45;
|
|
local secondEndAngle = firstEndAngle + 180;
|
|
|
|
self.coords[1]:SetAngle(width, height, angle1, firstEndAngle);
|
|
self.coords[1]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[1]:Show();
|
|
|
|
self.coords[2]:SetAngle(width, height, firstEndAngle, secondEndAngle);
|
|
self.coords[2]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[2]:Show();
|
|
|
|
self.coords[3]:SetAngle(width, height, secondEndAngle, angle2);
|
|
self.coords[3]:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v);
|
|
self.coords[3]:Show();
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions.SetBackgroundOffset(self, region, offset)
|
|
self.offset = offset;
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetPoint('TOPRIGHT', region, offset, offset)
|
|
self.textures[i]:SetPoint('BOTTOMRIGHT', region, offset, -offset)
|
|
self.textures[i]:SetPoint('BOTTOMLEFT', region, -offset, -offset)
|
|
self.textures[i]:SetPoint('TOPLEFT', region, -offset, offset)
|
|
end
|
|
self:UpdateSize();
|
|
end
|
|
|
|
function spinnerFunctions:SetHeight(height)
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetHeight(height);
|
|
end
|
|
end
|
|
|
|
function spinnerFunctions:SetWidth(width)
|
|
for i = 1, 3 do
|
|
self.textures[i]:SetWidth(width);
|
|
end
|
|
end
|
|
|
|
local defaultTexCoord = {
|
|
ULx = 0,
|
|
ULy = 0,
|
|
LLx = 0,
|
|
LLy = 1,
|
|
URx = 1,
|
|
URy = 0,
|
|
LRx = 1,
|
|
LRy = 1,
|
|
};
|
|
|
|
local function createTexCoord(texture)
|
|
local coord = {
|
|
ULx = 0,
|
|
ULy = 0,
|
|
LLx = 0,
|
|
LLy = 1,
|
|
URx = 1,
|
|
URy = 0,
|
|
LRx = 1,
|
|
LRy = 1,
|
|
|
|
ULvx = 0,
|
|
ULvy = 0,
|
|
LLvx = 0,
|
|
LLvy = 0,
|
|
URvx = 0,
|
|
URvy = 0,
|
|
LRvx = 0,
|
|
LRvy = 0,
|
|
|
|
texture = texture;
|
|
};
|
|
|
|
function coord:MoveCorner(width, height, corner, x, y)
|
|
local rx = defaultTexCoord[corner .. "x"] - x;
|
|
local ry = defaultTexCoord[corner .. "y"] - y;
|
|
coord[corner .. "vx"] = -rx * width;
|
|
coord[corner .. "vy"] = ry * height;
|
|
|
|
coord[corner .. "x"] = x;
|
|
coord[corner .. "y"] = y;
|
|
end
|
|
|
|
function coord:Hide()
|
|
coord.texture:Hide();
|
|
end
|
|
|
|
function coord:Show()
|
|
coord:Apply();
|
|
coord.texture:Show();
|
|
end
|
|
|
|
function coord:SetFull()
|
|
coord.ULx = 0;
|
|
coord.ULy = 0;
|
|
coord.LLx = 0;
|
|
coord.LLy = 1;
|
|
coord.URx = 1;
|
|
coord.URy = 0;
|
|
coord.LRx = 1;
|
|
coord.LRy = 1;
|
|
|
|
coord.ULvx = 0;
|
|
coord.ULvy = 0;
|
|
coord.LLvx = 0;
|
|
coord.LLvy = 0;
|
|
coord.URvx = 0;
|
|
coord.URvy = 0;
|
|
coord.LRvx = 0;
|
|
coord.LRvy = 0;
|
|
end
|
|
|
|
function coord:Apply()
|
|
--coord.texture:SetVertexOffset(UPPER_RIGHT_VERTEX, coord.URvx, coord.URvy);
|
|
--coord.texture:SetVertexOffset(UPPER_LEFT_VERTEX, coord.ULvx, coord.ULvy);
|
|
--coord.texture:SetVertexOffset(LOWER_RIGHT_VERTEX, coord.LRvx, coord.LRvy);
|
|
--coord.texture:SetVertexOffset(LOWER_LEFT_VERTEX, coord.LLvx, coord.LLvy);
|
|
|
|
coord.texture:SetTexCoord(coord.ULx, coord.ULy, coord.LLx, coord.LLy, coord.URx, coord.URy, coord.LRx, coord.LRy);
|
|
end
|
|
|
|
local exactAngles = {
|
|
{0.5, 0}, -- 0°
|
|
{1, 0}, -- 45°
|
|
{1, 0.5}, -- 90°
|
|
{1, 1}, -- 135°
|
|
{0.5, 1}, -- 180°
|
|
{0, 1}, -- 225°
|
|
{0, 0.5}, -- 270°
|
|
{0, 0} -- 315°
|
|
}
|
|
|
|
local function angleToCoord(angle)
|
|
angle = angle % 360;
|
|
|
|
if (angle % 45 == 0) then
|
|
local index = floor (angle / 45) + 1;
|
|
return exactAngles[index][1], exactAngles[index][2];
|
|
end
|
|
|
|
if (angle < 45) then
|
|
return 0.5 + tan(angle) / 2, 0;
|
|
elseif (angle < 135) then
|
|
return 1, 0.5 + tan(angle - 90) / 2 ;
|
|
elseif (angle < 225) then
|
|
return 0.5 - tan(angle) / 2, 1;
|
|
elseif (angle < 315) then
|
|
return 0, 0.5 - tan(angle - 90) / 2;
|
|
elseif (angle < 360) then
|
|
return 0.5 + tan(angle) / 2, 0;
|
|
end
|
|
end
|
|
|
|
local pointOrder = { "LL", "UL", "UR", "LR", "LL", "UL", "UR", "LR", "LL", "UL", "UR", "LR" }
|
|
|
|
function coord:SetAngle(width, height, angle1, angle2)
|
|
local index = floor((angle1 + 45) / 90);
|
|
|
|
local middleCorner = pointOrder[index + 1];
|
|
local startCorner = pointOrder[index + 2];
|
|
local endCorner1 = pointOrder[index + 3];
|
|
local endCorner2 = pointOrder[index + 4];
|
|
|
|
-- LL => 32, 32
|
|
-- UL => 32, -32
|
|
self:MoveCorner(width, height, middleCorner, 0.5, 0.5)
|
|
self:MoveCorner(width, height, startCorner, angleToCoord(angle1));
|
|
|
|
local edge1 = floor((angle1 - 45) / 90);
|
|
local edge2 = floor((angle2 -45) / 90);
|
|
|
|
if (edge1 == edge2) then
|
|
self:MoveCorner(width, height, endCorner1, angleToCoord(angle2));
|
|
else
|
|
self:MoveCorner(width, height, endCorner1, defaultTexCoord[endCorner1 .. "x"], defaultTexCoord[endCorner1 .. "y"]);
|
|
end
|
|
|
|
self:MoveCorner(width, height, endCorner2, angleToCoord(angle2));
|
|
end
|
|
|
|
local function TransformPoint(x, y, scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y)
|
|
-- 1) Translate texture-coords to user-defined center
|
|
x = x - 0.5
|
|
y = y - 0.5
|
|
|
|
-- 2) Shrink texture by 1/sqrt(2)
|
|
x = x * 1.4142
|
|
y = y * 1.4142
|
|
|
|
-- Not yet supported for circular progress
|
|
-- 3) Scale texture by user-defined amount
|
|
x = x / scalex
|
|
y = y / scaley
|
|
|
|
-- 4) Apply mirroring if defined
|
|
if mirror_h then
|
|
x = -x
|
|
end
|
|
if mirror_v then
|
|
y = -y
|
|
end
|
|
|
|
local cos_rotation = cos(rotation);
|
|
local sin_rotation = sin(rotation);
|
|
|
|
-- 5) Rotate texture by user-defined value
|
|
x, y = cos_rotation * x - sin_rotation * y, sin_rotation * x + cos_rotation * y
|
|
|
|
-- 6) Translate texture-coords back to (0,0)
|
|
x = x + 0.5
|
|
y = y + 0.5
|
|
|
|
x = x + (user_x or 0);
|
|
y = y + (user_y or 0);
|
|
|
|
return x, y
|
|
end
|
|
|
|
function coord:Transform(scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y)
|
|
coord.ULx, coord.ULy = TransformPoint(coord.ULx, coord.ULy, scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y);
|
|
coord.LLx, coord.LLy = TransformPoint(coord.LLx, coord.LLy, scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y);
|
|
coord.URx, coord.URy = TransformPoint(coord.URx, coord.URy, scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y);
|
|
coord.LRx, coord.LRy = TransformPoint(coord.LRx, coord.LRy, scalex, scaley, rotation, mirror_h, mirror_v, user_x, user_y);
|
|
end
|
|
|
|
return coord;
|
|
end
|
|
|
|
|
|
local function createSpinner(parent, layer, drawlayer)
|
|
local spinner = {};
|
|
spinner.textures = {};
|
|
spinner.coords = {};
|
|
spinner.offset = 0;
|
|
|
|
for i = 1, 3 do
|
|
local texture = parent:CreateTexture(nil, layer);
|
|
texture:SetDrawLayer(layer, drawlayer);
|
|
texture:SetAllPoints(parent);
|
|
spinner.textures[i] = texture;
|
|
|
|
spinner.coords[i] = createTexCoord(texture);
|
|
end
|
|
|
|
for k, v in pairs(spinnerFunctions) do
|
|
spinner[k] = v;
|
|
end
|
|
|
|
return spinner;
|
|
end
|
|
|
|
-- Make available for the thumbnail display
|
|
WeakAuras.createSpinner = createSpinner;
|
|
|
|
local orientationToAnchorPoint = {
|
|
["HORIZONTAL"] = "LEFT",
|
|
["HORIZONTAL_INVERSE"] = "RIGHT",
|
|
["VERTICAL"] = "BOTTOM",
|
|
["VERTICAL_INVERSE"] = "TOP"
|
|
}
|
|
|
|
local textureFunctions = {
|
|
SetValueFunctions = {
|
|
["HORIZONTAL"] = function(self, startProgress, endProgress)
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", startProgress, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", startProgress, 1 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", endProgress, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", endProgress, 1 );
|
|
end,
|
|
["HORIZONTAL_INVERSE"] = function(self, startProgress, endProgress)
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 1 - endProgress, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 1 - endProgress, 1 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1 - startProgress, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1 - startProgress, 1 );
|
|
end,
|
|
["VERTICAL"] = function(self, startProgress, endProgress)
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 0, 1 - endProgress );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1, 1 - endProgress );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 0, 1 - startProgress );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1, 1 - startProgress );
|
|
end,
|
|
["VERTICAL_INVERSE"] = function(self, startProgress, endProgress)
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 0, startProgress );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1, startProgress );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 0, endProgress );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1, endProgress );
|
|
end,
|
|
},
|
|
|
|
SetValueFunctionsSlanted = {
|
|
["HORIZONTAL"] = function(self, startProgress, endProgress)
|
|
local slant = self.slant or 0;
|
|
if (self.slantMode == "EXTEND") then
|
|
startProgress = startProgress * (1 + slant) - slant;
|
|
endProgress = endProgress * (1 + slant) - slant;
|
|
else
|
|
startProgress = startProgress * (1 - slant);
|
|
endProgress = endProgress * (1 - slant);
|
|
end
|
|
|
|
local slant1 = self.slantFirst and 0 or slant;
|
|
local slant2 = self.slantFirst and slant or 0;
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", startProgress + slant1, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", startProgress + slant2, 1 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", endProgress + slant1, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", endProgress + slant2, 1 );
|
|
end,
|
|
["HORIZONTAL_INVERSE"] = function(self, startProgress, endProgress)
|
|
local slant = self.slant or 0;
|
|
if (self.slantMode == "EXTEND") then
|
|
startProgress = startProgress * (1 + slant) - slant;
|
|
endProgress = endProgress * (1 + slant) - slant;
|
|
else
|
|
startProgress = startProgress * (1 - slant);
|
|
endProgress = endProgress * (1 - slant);
|
|
end
|
|
|
|
local slant1 = self.slantFirst and slant or 0;
|
|
local slant2 = self.slantFirst and 0 or slant;
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 1 - endProgress - slant1, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 1 - endProgress - slant2, 1 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1 - startProgress - slant1, 0 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1 - startProgress - slant2, 1 );
|
|
end,
|
|
["VERTICAL"] = function(self, startProgress, endProgress)
|
|
local slant = self.slant or 0;
|
|
if (self.slantMode == "EXTEND") then
|
|
startProgress = startProgress * (1 + slant) - slant;
|
|
endProgress = endProgress * (1 + slant) - slant;
|
|
else
|
|
startProgress = startProgress * (1 - slant);
|
|
endProgress = endProgress * (1 - slant);
|
|
end
|
|
|
|
local slant1 = self.slantFirst and slant or 0;
|
|
local slant2 = self.slantFirst and 0 or slant;
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 0, 1 - endProgress - slant1 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1, 1 - endProgress - slant2 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 0, 1 - startProgress - slant1 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1, 1 - startProgress - slant2 );
|
|
end,
|
|
["VERTICAL_INVERSE"] = function(self, startProgress, endProgress)
|
|
local slant = self.slant or 0;
|
|
if (self.slantMode == "EXTEND") then
|
|
startProgress = startProgress * (1 + slant) - slant;
|
|
endProgress = endProgress * (1 + slant) - slant;
|
|
else
|
|
startProgress = startProgress * (1 - slant);
|
|
endProgress = endProgress * (1 - slant);
|
|
end
|
|
|
|
local slant1 = self.slantFirst and 0 or slant;
|
|
local slant2 = self.slantFirst and slant or 0;
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UL", 0, startProgress + slant1 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "UR", 1, startProgress + slant2 );
|
|
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LL", 0, endProgress + slant1 );
|
|
self.coord:MoveCorner(self:GetWidth(), self:GetHeight(), "LR", 1, endProgress + slant2 );
|
|
end,
|
|
},
|
|
|
|
SetBackgroundOffset = function(self, backgroundOffset)
|
|
self.backgroundOffset = backgroundOffset;
|
|
end,
|
|
|
|
SetOrientation = function(self, orientation, compress, slanted, slant, slantFirst, slantMode)
|
|
self.SetValueFunction = slanted and self.SetValueFunctionsSlanted[orientation] or self.SetValueFunctions[orientation];
|
|
self.compress = compress;
|
|
self.slanted = slanted;
|
|
self.slant = slant;
|
|
self.slantFirst = slantFirst;
|
|
self.slantMode = slantMode;
|
|
if (self.compress) then
|
|
self:ClearAllPoints();
|
|
local anchor = orientationToAnchorPoint[orientation];
|
|
self:SetPoint(anchor, self.region, anchor);
|
|
self.horizontal = orientation == "HORIZONTAL" or orientation == "HORIZONTAL_INVERSE";
|
|
else
|
|
local offset = self.backgroundOffset or 0;
|
|
self:ClearAllPoints();
|
|
self:SetPoint("BOTTOMLEFT", self.region, "BOTTOMLEFT", -1 * offset, -1 * offset);
|
|
self:SetPoint("TOPRIGHT", self.region, "TOPRIGHT", offset, offset);
|
|
end
|
|
self:Update();
|
|
end,
|
|
|
|
SetValue = function(self, startProgress, endProgress)
|
|
self.startProgress = startProgress;
|
|
self.endProgress = endProgress;
|
|
|
|
if (self.compress) then
|
|
local progress = self.region.progress or 1;
|
|
local horScale = self.horizontal and progress or 1;
|
|
local verScale = self.horizontal and 1 or progress;
|
|
self:SetWidth(self.region:GetWidth() * horScale);
|
|
self:SetHeight(self.region:GetHeight() * verScale);
|
|
|
|
if (progress > 0.1) then
|
|
startProgress = startProgress / progress;
|
|
endProgress = endProgress / progress;
|
|
else
|
|
startProgress, endProgress = 0, 0;
|
|
end
|
|
end
|
|
|
|
self.coord:SetFull();
|
|
self:SetValueFunction(startProgress, endProgress);
|
|
|
|
local region = self.region;
|
|
local crop_x = region.crop_x or 1;
|
|
local crop_y = region.crop_y or 1;
|
|
local rotation = region.rotation or 0;
|
|
local mirror_h = region.mirror_h or false;
|
|
if region.mirror then
|
|
mirror_h = not mirror_h
|
|
end
|
|
local mirror_v = region.mirror_v or false;
|
|
local user_x = region.user_x;
|
|
local user_y = region.user_y;
|
|
|
|
self.coord:Transform(crop_x, crop_y, rotation, mirror_h, mirror_v, user_x, user_y);
|
|
self.coord:Apply();
|
|
end,
|
|
|
|
Update = function(self)
|
|
self:SetValue(self.startProgress, self.endProgress);
|
|
end,
|
|
}
|
|
|
|
|
|
local function createTexture(region, layer, drawlayer)
|
|
local texture = region:CreateTexture(nil, layer);
|
|
texture:SetDrawLayer(layer, drawlayer);
|
|
|
|
for k, v in pairs(textureFunctions) do
|
|
texture[k] = v;
|
|
end
|
|
|
|
local OrgSetTexture = texture.SetTexture;
|
|
-- WORKAROUND, setting the same texture with a different wrap mode does not change the wrap mode
|
|
texture.SetTexture = function(self, texture, horWrapMode, verWrapMode)
|
|
local needToClear = (self.horWrapMode and self.horWrapMode ~= horWrapMode) or (self.verWrapMode and self.verWrapMode ~= verWrapMode);
|
|
self.horWrapMode = horWrapMode;
|
|
self.verWrapMode = verWrapMode;
|
|
if (needToClear) then
|
|
OrgSetTexture(self, nil);
|
|
end
|
|
OrgSetTexture(self, texture, horWrapMode, verWrapMode);
|
|
end
|
|
|
|
texture.coord = createTexCoord(texture);
|
|
texture.region = region;
|
|
texture.startProgress = 0;
|
|
texture.endProgress = 1;
|
|
|
|
texture:SetAllPoints(region);
|
|
|
|
return texture;
|
|
end
|
|
|
|
local TextureSetValueFunction = function(self, progress)
|
|
self.progress = progress;
|
|
progress = max(0, progress);
|
|
progress = min(1, progress);
|
|
self.foreground:SetValue(0, progress);
|
|
end
|
|
|
|
local CircularSetValueFunctions = {
|
|
["CLOCKWISE"] = function(self, progress)
|
|
local startAngle = self.startAngle;
|
|
local endAngle = self.endAngle;
|
|
progress = progress or 0;
|
|
self.progress = progress;
|
|
|
|
if (progress < 0) then
|
|
progress = 0;
|
|
end
|
|
|
|
if (progress > 1) then
|
|
progress = 1;
|
|
end
|
|
|
|
local pAngle = (endAngle - startAngle) * progress + startAngle;
|
|
self.foregroundSpinner:SetProgress(self, startAngle, pAngle);
|
|
end,
|
|
["ANTICLOCKWISE"] = function(self, progress)
|
|
local startAngle = self.startAngle;
|
|
local endAngle = self.endAngle;
|
|
progress = progress or 0;
|
|
self.progress = progress;
|
|
|
|
if (progress < 0) then
|
|
progress = 0;
|
|
end
|
|
|
|
if (progress > 1) then
|
|
progress = 1;
|
|
end
|
|
progress = 1 - progress;
|
|
|
|
local pAngle = (endAngle - startAngle) * progress + startAngle;
|
|
self.foregroundSpinner:SetProgress(self, pAngle, endAngle);
|
|
end
|
|
}
|
|
|
|
local function hideExtraTextures(extraTextures, from)
|
|
for i = from, #extraTextures do
|
|
extraTextures[i]:Hide();
|
|
end
|
|
end
|
|
|
|
local function ensureExtraTextures(region, count)
|
|
for i = #region.extraTextures + 1, count do
|
|
local extraTexture = createTexture(region, "ARTWORK", min(i, 7));
|
|
extraTexture:SetTexture(region.currentTexture, region.textureWrapMode, region.textureWrapMode)
|
|
extraTexture:SetBlendMode(region.foreground:GetBlendMode());
|
|
extraTexture:SetOrientation(region.orientation, region.compress, region.slanted, region.slant, region.slantFirst, region.slantMode);
|
|
region.extraTextures[i] = extraTexture;
|
|
end
|
|
end
|
|
|
|
local function ensureExtraSpinners(region, count)
|
|
local parent = region:GetParent();
|
|
for i = #region.extraSpinners + 1, count do
|
|
local extraSpinner = createSpinner(region, "OVERLAY", min(i, 7));
|
|
extraSpinner:SetTexture(region.currentTexture);
|
|
extraSpinner:SetBlendMode(region.foreground:GetBlendMode());
|
|
region.extraSpinners[i] = extraSpinner;
|
|
end
|
|
end
|
|
|
|
local function convertToProgress(rprogress, additionalProgress, adjustMin, totalWidth, inverse, clamp)
|
|
local startProgress = 0;
|
|
local endProgress = 0;
|
|
|
|
if (additionalProgress.min and additionalProgress.max) then
|
|
if (totalWidth ~= 0) then
|
|
startProgress = max( (additionalProgress.min - adjustMin) / totalWidth, 0);
|
|
endProgress = (additionalProgress.max - adjustMin) / totalWidth;
|
|
|
|
if (inverse) then
|
|
startProgress = 1 - startProgress;
|
|
endProgress = 1 - endProgress;
|
|
end
|
|
end
|
|
elseif (additionalProgress.direction) then
|
|
local forwardDirection = (additionalProgress.direction or "forward") == "forward";
|
|
if (inverse) then
|
|
forwardDirection = not forwardDirection;
|
|
end
|
|
local width = additionalProgress.width or 0;
|
|
local offset = additionalProgress.offset or 0;
|
|
if (width ~= 0) then
|
|
if (forwardDirection) then
|
|
startProgress = rprogress + offset / totalWidth ;
|
|
endProgress = rprogress + (offset + width) / totalWidth;
|
|
else
|
|
startProgress = rprogress - (width + offset) / totalWidth;
|
|
endProgress = rprogress - offset / totalWidth;
|
|
end
|
|
end
|
|
end
|
|
|
|
if (clamp) then
|
|
startProgress = max(0, min(1, startProgress));
|
|
endProgress = max(0, min(1, endProgress));
|
|
end
|
|
|
|
return startProgress, endProgress;
|
|
end
|
|
|
|
local function UpdateAdditionalProgress(self)
|
|
self:SetAdditionalProgress(self.additionalProgress, self.additionalProgressMin, self.additionalProgressMax, self.additionalProgressInverse)
|
|
end
|
|
|
|
local function SetAdditionalProgress(self, additionalProgress, min, max, inverse)
|
|
self.additionalProgress = additionalProgress;
|
|
self.additionalProgressMin = min;
|
|
self.additionalProgressMax = max;
|
|
self.additionalProgressInverse = inverse;
|
|
|
|
local effectiveInverse = (inverse and not self.inverseDirection) or (not inverse and self.inverseDirection);
|
|
|
|
if (additionalProgress) then
|
|
ensureExtraTextures(self, #additionalProgress);
|
|
for index, additionalProgress in ipairs(additionalProgress) do
|
|
local extraTexture = self.extraTextures[index];
|
|
|
|
local totalWidth = max - min;
|
|
local startProgress, endProgress = convertToProgress(self.progress, additionalProgress, min, totalWidth, effectiveInverse, self.overlayclip);
|
|
if ((endProgress - startProgress) == 0) then
|
|
extraTexture:Hide();
|
|
else
|
|
extraTexture:Show();
|
|
local color = self.overlays[index];
|
|
if (color) then
|
|
extraTexture:SetVertexColor(unpack(color));
|
|
else
|
|
extraTexture:SetVertexColor(1, 1, 1, 1);
|
|
end
|
|
|
|
extraTexture:SetValue(startProgress, endProgress)
|
|
end
|
|
end
|
|
|
|
hideExtraTextures(self.extraTextures, #additionalProgress + 1);
|
|
else
|
|
hideExtraTextures(self.extraTextures, 1);
|
|
end
|
|
end
|
|
|
|
local function SetAdditionalProgressCircular(self, additionalProgress, min, max, inverse)
|
|
self.additionalProgress = additionalProgress;
|
|
self.additionalProgressMin = min;
|
|
self.additionalProgressMax = max;
|
|
self.additionalProgressInverse = inverse;
|
|
|
|
local effectiveInverse = (inverse and not self.inverseDirection) or (not inverse and self.inverseDirection);
|
|
|
|
if (additionalProgress) then
|
|
ensureExtraSpinners(self, #additionalProgress);
|
|
|
|
for index, additionalProgress in ipairs(additionalProgress) do
|
|
local extraSpinner = self.extraSpinners[index];
|
|
|
|
local totalWidth = max - min;
|
|
local startProgress, endProgress = convertToProgress(self.progress, additionalProgress, min, totalWidth, effectiveInverse, self.overlayclip);
|
|
if (endProgress < startProgress) then
|
|
startProgress, endProgress = endProgress, startProgress;
|
|
end
|
|
|
|
if (self.orientation == "ANTICLOCKWISE") then
|
|
startProgress, endProgress = 1 - endProgress, 1 - startProgress;
|
|
end
|
|
|
|
if ((endProgress - startProgress) == 0) then
|
|
extraSpinner:SetProgress(self, 0, 0);
|
|
else
|
|
local color = self.overlays[index];
|
|
if (color) then
|
|
extraSpinner:Color(unpack(color));
|
|
else
|
|
extraSpinner:Color(1, 1, 1, 1);
|
|
end
|
|
|
|
local startAngle = self.startAngle;
|
|
local diffAngle = self.endAngle - startAngle;
|
|
local pAngleStart = diffAngle * startProgress + startAngle;
|
|
local pAngleEnd = diffAngle * endProgress + startAngle;
|
|
|
|
if (pAngleStart < 0) then
|
|
pAngleStart = pAngleStart + 360;
|
|
pAngleEnd = pAngleEnd + 360;
|
|
end
|
|
|
|
extraSpinner:SetProgress(self, pAngleStart, pAngleEnd);
|
|
end
|
|
end
|
|
|
|
else
|
|
hideExtraTextures(self.extraSpinners, 1);
|
|
end
|
|
end
|
|
|
|
local function showCircularProgress(region)
|
|
region.foreground:Hide();
|
|
region.background:Hide();
|
|
region.foregroundSpinner:Show();
|
|
region.backgroundSpinner:Show();
|
|
|
|
for i = 1, #region.extraTextures do
|
|
region.extraTextures[i]:Hide();
|
|
end
|
|
end
|
|
|
|
local function hideCircularProgress(region)
|
|
region.foreground:Show();
|
|
region.background:Show();
|
|
region.foregroundSpinner:Hide();
|
|
region.backgroundSpinner:Hide();
|
|
|
|
for i = 1, #region.extraSpinners do
|
|
region.extraSpinners[i]:Hide();
|
|
end
|
|
end
|
|
|
|
local function SetOrientation(region, orientation)
|
|
region.orientation = orientation;
|
|
if(region.orientation == "CLOCKWISE" or region.orientation == "ANTICLOCKWISE") then
|
|
showCircularProgress(region);
|
|
region.foregroundSpinner:UpdateSize();
|
|
region.backgroundSpinner:UpdateSize();
|
|
region.SetValueOnTexture = CircularSetValueFunctions[region.orientation];
|
|
region.SetAdditionalProgress = SetAdditionalProgressCircular;
|
|
else
|
|
hideCircularProgress(region);
|
|
region.background:SetOrientation(orientation, nil, region.slanted, region.slant, region.slantFirst, region.slantMode);
|
|
region.foreground:SetOrientation(orientation, region.compress, region.slanted, region.slant, region.slantFirst, region.slantMode);
|
|
region.SetValueOnTexture = TextureSetValueFunction;
|
|
region.SetAdditionalProgress = SetAdditionalProgress;
|
|
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:SetOrientation(orientation, region.compress, region.slanted, region.slant, region.slantFirst, region.slantMode);
|
|
end
|
|
end
|
|
region:SetValueOnTexture(region.progress);
|
|
region:UpdateAdditionalProgress();
|
|
end
|
|
|
|
local function create(parent)
|
|
local font = "GameFontHighlight";
|
|
|
|
local region = CreateFrame("FRAME", nil, parent);
|
|
region:SetMovable(true);
|
|
region:SetResizable(true);
|
|
region:SetMinResize(1, 1);
|
|
|
|
local background = createTexture(region, "BACKGROUND", 0);
|
|
region.background = background;
|
|
|
|
-- For horizontal/vertical progress
|
|
local foreground = createTexture(region, "ARTWORK", 0);
|
|
region.foreground = foreground;
|
|
|
|
region.foregroundSpinner = createSpinner(region, "ARTWORK", 1);
|
|
region.backgroundSpinner = createSpinner(region, "BACKGROUND", 1);
|
|
|
|
region.extraTextures = {};
|
|
region.extraSpinners = {};
|
|
|
|
region.values = {};
|
|
|
|
-- Use a dummy object for the SmoothStatusBarMixin, because our SetValue
|
|
-- is used for a different purpose
|
|
region.smoothProgress = {};
|
|
WeakAuras:Mixin(region.smoothProgress, SmoothStatusBarMixin);
|
|
region.smoothProgress.SetValue = function(self, progress)
|
|
region:SetValueOnTexture(progress);
|
|
region:UpdateAdditionalProgress();
|
|
end
|
|
|
|
region.smoothProgress.GetValue = function(self)
|
|
return region.progress;
|
|
end
|
|
|
|
region.smoothProgress.GetMinMaxValues = function(self)
|
|
return 0, 1;
|
|
end
|
|
|
|
region.SetOrientation = SetOrientation;
|
|
|
|
WeakAuras.regionPrototype.create(region);
|
|
|
|
region.AnchorSubRegion = WeakAuras.regionPrototype.AnchorSubRegion
|
|
|
|
return region;
|
|
end
|
|
|
|
local function TimerTick(self)
|
|
local adjustMin = self.adjustedMin or self.adjustedMinRel or 0;
|
|
local duration = self.state.duration
|
|
self:SetTime( (duration ~= 0 and (self.adjustedMax or self.adjustedMaxRel) or duration) - adjustMin, self.state.expirationTime - adjustMin, self.state.inverse);
|
|
end
|
|
|
|
local function modify(parent, region, data)
|
|
WeakAuras.regionPrototype.modify(parent, region, data);
|
|
|
|
local background, foreground = region.background, region.foreground;
|
|
local foregroundSpinner, backgroundSpinner = region.foregroundSpinner, region.backgroundSpinner;
|
|
|
|
region:SetWidth(data.width);
|
|
region:SetHeight(data.height);
|
|
region.width = data.width;
|
|
region.height = data.height;
|
|
region.scalex = 1;
|
|
region.scaley = 1;
|
|
region.aspect = data.width / data.height;
|
|
region.overlayclip = data.overlayclip;
|
|
|
|
region.textureWrapMode = data.textureWrapMode;
|
|
|
|
background:SetBackgroundOffset(data.backgroundOffset);
|
|
background:SetTexture(data.sameTexture and data.foregroundTexture or data.backgroundTexture, region.textureWrapMode, region.textureWrapMode);
|
|
background:SetDesaturated(data.desaturateBackground)
|
|
background:SetVertexColor(data.backgroundColor[1], data.backgroundColor[2], data.backgroundColor[3], data.backgroundColor[4]);
|
|
background:SetBlendMode(data.blendMode);
|
|
|
|
backgroundSpinner:SetTexture(data.sameTexture and data.foregroundTexture or data.backgroundTexture);
|
|
backgroundSpinner:SetDesaturated(data.desaturateBackground)
|
|
backgroundSpinner:Color(data.backgroundColor[1], data.backgroundColor[2], data.backgroundColor[3], data.backgroundColor[4]);
|
|
backgroundSpinner:SetBlendMode(data.blendMode);
|
|
|
|
region.currentTexture = data.foregroundTexture;
|
|
foreground:SetTexture(data.foregroundTexture, region.textureWrapMode, region.textureWrapMode);
|
|
foreground:SetDesaturated(data.desaturateForeground)
|
|
foreground:SetBlendMode(data.blendMode);
|
|
|
|
foregroundSpinner:SetTexture(data.foregroundTexture);
|
|
foregroundSpinner:SetDesaturated(data.desaturateForeground);
|
|
foregroundSpinner:SetBlendMode(data.blendMode);
|
|
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:SetTexture(data.foregroundTexture, region.textureWrapMode, region.textureWrapMode)
|
|
extraTexture:SetBlendMode(data.blendMode);
|
|
end
|
|
|
|
for _, extraSpinner in ipairs(region.extraSpinners) do
|
|
extraSpinner:SetTexture(data.foregroundTexture);
|
|
extraSpinner:SetBlendMode(data.blendMode);
|
|
end
|
|
|
|
region.mirror = data.mirror
|
|
region.crop_x = 1 + (data.crop_x or 0.41);
|
|
region.crop_y = 1 + (data.crop_y or 0.41);
|
|
region.rotation = data.rotation or 0;
|
|
region.user_x = -1 * (data.user_x or 0);
|
|
region.user_y = data.user_y or 0;
|
|
|
|
region.startAngle = (data.startAngle or 0) % 360;
|
|
region.endAngle = (data.endAngle or 360) % 360;
|
|
|
|
if (region.endAngle <= region.startAngle) then
|
|
region.endAngle = region.endAngle + 360;
|
|
end
|
|
|
|
region.compress = data.compress;
|
|
|
|
region.inverseDirection = data.inverse;
|
|
region.progress = 0.667;
|
|
backgroundSpinner:SetProgress(region, region.startAngle, region.endAngle);
|
|
backgroundSpinner:SetBackgroundOffset(region, data.backgroundOffset);
|
|
|
|
region.overlays = {};
|
|
if (data.overlays) then
|
|
WeakAuras.DeepCopy(data.overlays, region.overlays);
|
|
end
|
|
|
|
region.UpdateAdditionalProgress = UpdateAdditionalProgress;
|
|
|
|
region.slanted = data.slanted;
|
|
region.slant = data.slant;
|
|
region.slantFirst = data.slantFirst;
|
|
region.slantMode = data.slantMode;
|
|
region:SetOrientation(data.orientation);
|
|
|
|
local function DoPosition(region)
|
|
local mirror = region.mirror_h
|
|
if region.mirror then
|
|
mirror = not mirror
|
|
end
|
|
|
|
if(mirror) then
|
|
if(data.orientation == "HORIZONTAL_INVERSE") then
|
|
foreground:SetPoint("RIGHT", region, "RIGHT");
|
|
elseif(data.orientation == "HORIZONTAL") then
|
|
foreground:SetPoint("LEFT", region, "LEFT");
|
|
end
|
|
else
|
|
if(data.orientation == "HORIZONTAL") then
|
|
foreground:SetPoint("LEFT", region, "LEFT");
|
|
elseif(data.orientation == "HORIZONTAL_INVERSE") then
|
|
foreground:SetPoint("RIGHT", region, "RIGHT");
|
|
end
|
|
end
|
|
|
|
if(region.mirror_v) then
|
|
if(data.orientation == "VERTICAL_INVERSE") then
|
|
foreground:SetPoint("TOP", region, "TOP");
|
|
elseif(data.orientation == "VERTICAL") then
|
|
foreground:SetPoint("BOTTOM", region, "BOTTOM");
|
|
end
|
|
else
|
|
if(data.orientation == "VERTICAL") then
|
|
foreground:SetPoint("BOTTOM", region, "BOTTOM");
|
|
elseif(data.orientation == "VERTICAL_INVERSE") then
|
|
foreground:SetPoint("TOP", region, "TOP");
|
|
end
|
|
end
|
|
|
|
region:SetWidth(region.width * region.scalex);
|
|
region:SetHeight(region.height * region.scaley);
|
|
|
|
if (data.orientation == "CLOCKWISE" or data.orientation == "ANTICLOCKWISE") then
|
|
region.foregroundSpinner:UpdateSize();
|
|
region.backgroundSpinner:UpdateSize();
|
|
for i = 1, #region.extraSpinners do
|
|
region.extraSpinners[i]:UpdateSize();
|
|
end
|
|
else
|
|
region.background:Update();
|
|
region.foreground:Update();
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:Update();
|
|
end
|
|
end
|
|
end
|
|
|
|
function region:Scale(scalex, scaley)
|
|
if(scalex < 0) then
|
|
region.mirror_h = true;
|
|
scalex = scalex * -1;
|
|
end
|
|
|
|
if(scaley < 0) then
|
|
region.mirror_v = true;
|
|
scaley = scaley * -1;
|
|
end
|
|
|
|
region.scalex = scalex;
|
|
region.scaley = scaley;
|
|
|
|
DoPosition(region)
|
|
end
|
|
|
|
function region:SetMirror(mirror)
|
|
region.mirror = mirror
|
|
DoPosition(region)
|
|
end
|
|
|
|
function region:Rotate(angle)
|
|
region.rotation = angle or 0;
|
|
if (data.orientation == "CLOCKWISE" or data.orientation == "ANTICLOCKWISE") then
|
|
region.foregroundSpinner:UpdateSize();
|
|
region.backgroundSpinner:UpdateSize();
|
|
for i = 1, #region.extraSpinners do
|
|
region.extraSpinners[i]:UpdateSize();
|
|
end
|
|
else
|
|
region.background:Update();
|
|
region.foreground:Update();
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:Update();
|
|
end
|
|
end
|
|
end
|
|
|
|
function region:GetRotation()
|
|
return region.rotation;
|
|
end
|
|
|
|
function region:Color(r, g, b, a)
|
|
region.color_r = r;
|
|
region.color_g = g;
|
|
region.color_b = b;
|
|
if (r or g or b) then
|
|
a = a or 1;
|
|
end
|
|
region.color_a = a;
|
|
foreground: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);
|
|
foregroundSpinner:Color(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
|
|
foreground:SetVertexColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a);
|
|
foregroundSpinner:Color(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.foregroundColor[1], region.color_g or data.foregroundColor[2],
|
|
region.color_b or data.foregroundColor[3], region.color_a or data.foregroundColor[4];
|
|
end
|
|
|
|
region:Color(data.foregroundColor[1], data.foregroundColor[2], data.foregroundColor[3], data.foregroundColor[4]);
|
|
|
|
function region:SetTime(duration, expirationTime, inverse)
|
|
local progress = 1;
|
|
if (duration ~= 0) then
|
|
local remaining = expirationTime - GetTime();
|
|
progress = remaining / duration;
|
|
local inversed = (not inverse and region.inverseDirection) or (inverse and not region.inverseDirection);
|
|
if(inversed) then
|
|
progress = 1 - progress;
|
|
end
|
|
end
|
|
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
if (data.smoothProgress) then
|
|
region.smoothProgress:SetSmoothedValue(progress);
|
|
else
|
|
region:SetValueOnTexture(progress);
|
|
region:UpdateAdditionalProgress();
|
|
end
|
|
end
|
|
|
|
function region:SetValue(value, total)
|
|
local progress = 1
|
|
if(total > 0) then
|
|
progress = value / total;
|
|
if(region.inverseDirection) then
|
|
progress = 1 - progress;
|
|
end
|
|
end
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
if (data.smoothProgress) then
|
|
region.smoothProgress:SetSmoothedValue(progress);
|
|
else
|
|
region:SetValueOnTexture(progress);
|
|
region:UpdateAdditionalProgress();
|
|
end
|
|
end
|
|
|
|
function region:Update()
|
|
local state = region.state
|
|
|
|
local max
|
|
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;
|
|
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);
|
|
if not region.TimerTick then
|
|
region.TimerTick = TimerTick
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
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;
|
|
|
|
if region.adjustedMax then
|
|
max = region.adjustedMax
|
|
elseif region.adjustedMaxRelPercent then
|
|
region.adjustedMaxRel = region.adjustedMaxRelPercent * total
|
|
max = region.adjustedMaxRel
|
|
else
|
|
max = total
|
|
end
|
|
|
|
region:SetValue(value - adjustMin, max - adjustMin);
|
|
if region.TimerTick then
|
|
region.TimerTick = nil
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
else
|
|
region:SetTime(0, math.huge)
|
|
if region.TimerTick then
|
|
region.TimerTick = nil
|
|
region:UpdateRegionHasTimerTick()
|
|
end
|
|
end
|
|
|
|
max = max or 0
|
|
|
|
region:SetAdditionalProgress(state.additionalProgress, region.adjustMin or 0, region.state.duration ~= 0 and max or state.total or state.duration or 0, state.inverse)
|
|
|
|
if state.texture then
|
|
region:SetTexture(state.texture)
|
|
end
|
|
end
|
|
|
|
function region:SetTexture(texture)
|
|
region.currentTexture = texture;
|
|
region.foreground:SetTexture(texture, region.textureWrapMode, region.textureWrapMode);
|
|
foregroundSpinner:SetTexture(texture);
|
|
if (data.sameTexture) then
|
|
background:SetTexture(texture, region.textureWrapMode, region.textureWrapMode);
|
|
backgroundSpinner:SetTexture(texture);
|
|
end
|
|
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:SetTexture(texture, region.textureWrapMode, region.textureWrapMode)
|
|
end
|
|
|
|
for _, extraSpinner in ipairs(region.extraSpinners) do
|
|
extraSpinner:SetTexture(texture);
|
|
end
|
|
end
|
|
|
|
function region:SetForegroundDesaturated(b)
|
|
region.foreground:SetDesaturated(b);
|
|
region.foregroundSpinner:SetDesaturated(b);
|
|
end
|
|
|
|
function region:SetBackgroundDesaturated(b)
|
|
region.background:SetDesaturated(b);
|
|
region.backgroundSpinner:SetDesaturated(b);
|
|
end
|
|
|
|
function region:SetBackgroundColor(r, g, b, a)
|
|
region.background:SetVertexColor(r, g, b, a);
|
|
region.backgroundSpinner:Color(r, g, b, a);
|
|
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:SetInverse(inverse)
|
|
if (region.inverseDirection == inverse) then
|
|
return;
|
|
end
|
|
region.inverseDirection = inverse;
|
|
local progress = 1 - region.progress;
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
region:SetValueOnTexture(progress);
|
|
region:UpdateAdditionalProgress();
|
|
end
|
|
|
|
function region:SetOverlayColor(id, r, g, b, a)
|
|
self.overlays[id] = { r, g, b, a};
|
|
if (self.extraTextures[id]) then
|
|
self.extraTextures[id]:SetVertexColor(r, g, b, a);
|
|
end
|
|
if (self.extraSpinners[id]) then
|
|
self.extraSpinners[id]:Color(r, g, b, a);
|
|
end
|
|
end
|
|
|
|
WeakAuras.regionPrototype.modifyFinish(parent, region, data);
|
|
end
|
|
|
|
--WeakAuras.RegisterRegionType("progresstexture", create, modify, default, GetProperties);
|