1007 lines
32 KiB
Lua
1007 lines
32 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName = ...
|
|
local Private = select(2, ...)
|
|
|
|
local L = WeakAuras.L;
|
|
|
|
local defaultFont = WeakAuras.defaultFont
|
|
local defaultFontSize = WeakAuras.defaultFontSize
|
|
|
|
-- Credit to CommanderSirow for taking the time to properly craft the ApplyTransform 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.cos_rotation (1) - cos(ANGLE), precalculated cos-function for given ANGLE [-1, 1]
|
|
-- region.sin_rotation (0) - sin(ANGLE), precalculated cos-function for given ANGLE [-1, 1]
|
|
-- region.scale (1.0) - user defined scaling [1, INF]
|
|
-- region.full_rotation (false) - Allow full rotation [bool]
|
|
|
|
|
|
local function ApplyTransform(x, y, region)
|
|
-- 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
|
|
|
|
if (region.orientation ~= "CLOCKWISE" and region.orientation ~= "ANTICLOCKWISE") then
|
|
-- Not yet supported for circular progress
|
|
-- 3) Scale texture by user-defined amount
|
|
x = x / region.scale_x
|
|
y = y / region.scale_y
|
|
|
|
-- 4) Apply mirroring if defined
|
|
if region.mirror_h then
|
|
x = -x
|
|
end
|
|
if region.mirror_v then
|
|
y = -y
|
|
end
|
|
else
|
|
x = x / region.scale
|
|
y = y / region.scale
|
|
end
|
|
|
|
-- 5) Rotate texture by user-defined value
|
|
x, y = region.cos_rotation * x - region.sin_rotation * y, region.sin_rotation * x + region.cos_rotation * y
|
|
|
|
-- 6) Translate texture-coords back to (0,0)
|
|
x = x + 0.5
|
|
y = y + 0.5
|
|
|
|
if (region.orientation ~= "CLOCKWISE" and region.orientation ~= "ANTICLOCKWISE") then
|
|
x = x + region.user_x
|
|
y = y + region.user_y
|
|
end
|
|
|
|
return x, y
|
|
end
|
|
|
|
local function Transform(tx, x, y, angle, aspect) -- Translates texture to x, y and rotates around its center
|
|
local c, s = cos(angle), sin(angle)
|
|
y = y / aspect
|
|
local oy = 0.5 / aspect
|
|
|
|
|
|
local ULx, ULy = 0.5 + (x - 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x - 0.5) * s) * aspect
|
|
local LLx, LLy = 0.5 + (x - 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x - 0.5) * s) * aspect
|
|
local URx, URy = 0.5 + (x + 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x + 0.5) * s) * aspect
|
|
local LRx, LRy = 0.5 + (x + 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x + 0.5) * s) * aspect
|
|
tx:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
|
|
end
|
|
|
|
local default = {
|
|
progressSource = {-1, "" },
|
|
adjustedMax = "",
|
|
adjustedMin = "",
|
|
foregroundTexture = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\Aura3",
|
|
backgroundTexture = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\Aura3",
|
|
desaturateBackground = false,
|
|
desaturateForeground = false,
|
|
sameTexture = true,
|
|
compress = false,
|
|
blendMode = "BLEND",
|
|
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"
|
|
};
|
|
|
|
Private.regionPrototype.AddAlphaToDefault(default);
|
|
|
|
Private.regionPrototype.AddProgressSourceToDefault(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 = Private.orientation_with_circle_types
|
|
},
|
|
inverse = {
|
|
display = L["Inverse"],
|
|
setter = "SetInverse",
|
|
type = "bool"
|
|
},
|
|
mirror = {
|
|
display = L["Mirror"],
|
|
setter = "SetMirror",
|
|
type = "bool"
|
|
}
|
|
}
|
|
|
|
Private.regionPrototype.AddProperties(properties, default);
|
|
|
|
local function GetProperties(data)
|
|
local overlayInfo = Private.GetOverlayInfo(data);
|
|
local auraProperties = CopyTable(properties)
|
|
auraProperties.progressSource.values = Private.GetProgressSourcesForUi(data)
|
|
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
|
|
return auraProperties
|
|
else
|
|
return auraProperties
|
|
end
|
|
end
|
|
|
|
local spinnerFunctions = {};
|
|
|
|
function spinnerFunctions.SetTexture(self, texture)
|
|
for i = 1, 4 do
|
|
self.textures[i]:SetTexture(texture);
|
|
end
|
|
self.wedge:SetTexture(texture);
|
|
end
|
|
|
|
function spinnerFunctions.SetDesaturated(self, desaturate)
|
|
for i = 1, 4 do
|
|
self.textures[i]:SetDesaturated(desaturate);
|
|
end
|
|
self.wedge:SetDesaturated(desaturate);
|
|
end
|
|
|
|
function spinnerFunctions.SetBlendMode(self, blendMode)
|
|
for i = 1, 4 do
|
|
self.textures[i]:SetBlendMode(blendMode);
|
|
end
|
|
self.wedge:SetBlendMode(blendMode);
|
|
end
|
|
|
|
function spinnerFunctions.Show(self)
|
|
for i = 1, 4 do
|
|
self.textures[i]:Show();
|
|
end
|
|
self.wedge:Show();
|
|
end
|
|
|
|
function spinnerFunctions.Hide(self)
|
|
for i = 1, 4 do
|
|
self.textures[i]:Hide();
|
|
end
|
|
self.wedge:Hide();
|
|
end
|
|
|
|
function spinnerFunctions.Color(self, r, g, b, a)
|
|
for i = 1, 4 do
|
|
self.textures[i]:SetVertexColor(r, g, b, a);
|
|
end
|
|
self.wedge:SetVertexColor(r, g, b, a);
|
|
end
|
|
|
|
function spinnerFunctions.SetBackgroundOffset(self, region, offset)
|
|
self.offset = offset;
|
|
self.textures[1]:SetPoint("TOPRIGHT", region, offset, offset)
|
|
self.textures[2]:SetPoint("BOTTOMRIGHT", region, offset, -offset)
|
|
self.textures[3]:SetPoint("BOTTOMLEFT", region, -offset, -offset)
|
|
self.textures[4]:SetPoint("TOPLEFT", region, -offset, offset)
|
|
end
|
|
|
|
function spinnerFunctions:SetHeight(height)
|
|
self.wedge:SetHeight(height);
|
|
end
|
|
|
|
function spinnerFunctions:SetWidth(width)
|
|
self.wedge:SetWidth(width);
|
|
end
|
|
|
|
local function betweenAngles(low, high, needle1, needle2)
|
|
if (low <= needle1 and needle1 <= high
|
|
and low <= needle2 and needle2 <= high) then
|
|
return true;
|
|
end
|
|
|
|
needle1 = needle1 + 360;
|
|
needle2 = needle2 + 360;
|
|
if (low <= needle1 and needle1 <= high
|
|
and low <= needle2 and needle2 <= high) then
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
local function animRotate(object, degrees, anchor, regionRotate, aspect)
|
|
if (not anchor) then
|
|
anchor = "CENTER";
|
|
end
|
|
|
|
object.degrees = degrees;
|
|
object.regionRotate = regionRotate;
|
|
object.aspect = aspect;
|
|
|
|
-- Something to rotate
|
|
-- Create AnimationGroup and rotation animation
|
|
if (not object.animationGroup) then
|
|
object.animationGroup = object:CreateAnimationGroup();
|
|
object.animationGroup:SetLooping("REPEAT")
|
|
end
|
|
|
|
object.animationGroup.rotate = object.animationGroup.rotate or object.animationGroup:CreateAnimation("rotation");
|
|
|
|
local rotate = object.animationGroup.rotate;
|
|
rotate:SetOrigin(anchor, 0, 0);
|
|
rotate:SetDegrees(degrees);
|
|
rotate:SetDuration( 0 );
|
|
rotate:SetEndDelay(15); -- 2147483647
|
|
Transform(object, -0.5, -0.5, -degrees + regionRotate, aspect)
|
|
object.animationGroup:Play();
|
|
end
|
|
|
|
function spinnerFunctions.SetProgress(self, region, startAngle, endAngle, progress, clockwise)
|
|
local pAngle = (endAngle - startAngle) * progress + startAngle;
|
|
|
|
-- Show/hide necessary textures if we need to
|
|
for i = 1, 4 do
|
|
local quadrantAngle1;
|
|
local quadrantAngle2;
|
|
|
|
if (clockwise) then
|
|
quadrantAngle2 = i * 90;
|
|
quadrantAngle1 = quadrantAngle2 - 90;
|
|
else
|
|
quadrantAngle2 = (5 - i) * 90;
|
|
quadrantAngle1 = quadrantAngle2 - 90;
|
|
end
|
|
|
|
if clockwise then
|
|
if betweenAngles(startAngle, pAngle, quadrantAngle1, quadrantAngle2) then
|
|
self.textures[i]:Show()
|
|
else
|
|
self.textures[i]:Hide()
|
|
end
|
|
else
|
|
if betweenAngles(startAngle, pAngle, quadrantAngle1, quadrantAngle2) then
|
|
self.textures[i]:Show()
|
|
else
|
|
self.textures[i]:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Move scrollframe/wedge to the proper quadrant
|
|
local quadrant = floor(pAngle % 360 / 90) + 1;
|
|
if (not clockwise) then
|
|
quadrant = 5 - quadrant;
|
|
end
|
|
self.scrollframe:Hide();
|
|
self.scrollframe:SetAllPoints(self.textures[quadrant])
|
|
self.scrollframe:Show();
|
|
|
|
local ULx, ULy = ApplyTransform(0, 0, region)
|
|
local LLx, LLy = ApplyTransform(0, 1, region)
|
|
local URx, URy = ApplyTransform(1, 0, region)
|
|
local LRx, LRy = ApplyTransform(1, 1, region)
|
|
|
|
local Lx, Ly = ApplyTransform(0, 0.5, region)
|
|
local Tx, Ty = ApplyTransform(0.5, 0, region)
|
|
local Bx, By = ApplyTransform(0.5, 1, region)
|
|
local Rx, Ry = ApplyTransform(1, 0.5, region)
|
|
local Cx, Cy = ApplyTransform(0.5, 0.5, region)
|
|
|
|
self.textures[1]:SetTexCoord(Tx, Ty, Cx, Cy, URx, URy, Rx, Ry);
|
|
self.textures[2]:SetTexCoord(Cx, Cy, Bx, By, Rx, Ry, LRx, LRy);
|
|
self.textures[3]:SetTexCoord(Lx, Ly, LLx, LLy, Cx, Cy, Bx, By);
|
|
self.textures[4]:SetTexCoord(ULx, ULy, Lx, Ly, Tx, Ty, Cx, Cy);
|
|
|
|
local degree = pAngle;
|
|
if not clockwise then degree = -degree + 90 end
|
|
|
|
animRotate(self.wedge, -degree, "BOTTOMRIGHT", region.rotation, region.aspect);
|
|
end
|
|
|
|
local function createSpinner(parent, layer, frameLevel)
|
|
-- For circular progress
|
|
local scrollframe = CreateFrame("ScrollFrame", nil, parent)
|
|
scrollframe:SetPoint("BOTTOMLEFT", parent, "CENTER")
|
|
scrollframe:SetPoint("TOPRIGHT")
|
|
scrollframe:SetFrameLevel(frameLevel);
|
|
|
|
local scrollchild = CreateFrame("Frame", nil, scrollframe)
|
|
scrollframe:SetScrollChild(scrollchild)
|
|
scrollchild:SetAllPoints(scrollframe)
|
|
scrollchild:SetFrameLevel(frameLevel);
|
|
|
|
-- Wedge thing
|
|
local wedge = scrollchild:CreateTexture(nil, layer)
|
|
wedge:SetPoint("BOTTOMRIGHT", parent, "CENTER")
|
|
|
|
-- Top Right
|
|
local trTexture = parent:CreateTexture(nil, layer)
|
|
trTexture:SetPoint("BOTTOMLEFT", parent, "CENTER")
|
|
trTexture:SetPoint("TOPRIGHT")
|
|
trTexture:SetTexCoord(0.5, 1, 0, 0.5)
|
|
|
|
-- Bottom Right
|
|
local brTexture = parent:CreateTexture(nil, layer)
|
|
brTexture:SetPoint("TOPLEFT", parent, "CENTER")
|
|
brTexture:SetPoint("BOTTOMRIGHT")
|
|
brTexture:SetTexCoord(0.5, 1, 0.5, 1)
|
|
|
|
-- Bottom Left
|
|
local blTexture = parent:CreateTexture(nil, layer)
|
|
blTexture:SetPoint("TOPRIGHT", parent, "CENTER")
|
|
blTexture:SetPoint("BOTTOMLEFT")
|
|
blTexture:SetTexCoord(0, 0.5, 0.5, 1)
|
|
|
|
-- Top Left
|
|
local tlTexture = parent:CreateTexture(nil, layer)
|
|
tlTexture:SetPoint("BOTTOMRIGHT", parent, "CENTER")
|
|
tlTexture:SetPoint("TOPLEFT")
|
|
tlTexture:SetTexCoord(0, 0.5, 0, 0.5)
|
|
|
|
-- /4|1\ -- Clockwise texture arrangement
|
|
-- \3|2/ --
|
|
|
|
local spinner = {};
|
|
|
|
spinner.scrollframe = scrollframe
|
|
spinner.wedge = wedge
|
|
spinner.textures = {trTexture, brTexture, blTexture, tlTexture}
|
|
|
|
for k, v in pairs(spinnerFunctions) do
|
|
spinner[k] = v;
|
|
end
|
|
|
|
return spinner;
|
|
end
|
|
|
|
-- Make available for the thumbnail display
|
|
WeakAuras.createSpinner = createSpinner;
|
|
|
|
local function create(parent)
|
|
local font = "GameFontHighlight";
|
|
|
|
local region = CreateFrame("Frame", nil, parent);
|
|
region.regionType = "progresstexture"
|
|
region:SetMovable(true);
|
|
region:SetResizable(true);
|
|
region:SetMinResize(1, 1);
|
|
|
|
local background = region:CreateTexture(nil, "BACKGROUND");
|
|
region.background = background;
|
|
|
|
-- For horizontal/vertical progress
|
|
local foreground = region:CreateTexture(nil, "ARTWORK");
|
|
region.foreground = foreground;
|
|
|
|
region.foregroundSpinner = createSpinner(region, "ARTWORK", parent:GetFrameLevel() + 2);
|
|
region.backgroundSpinner = createSpinner(region, "BACKGROUND", parent:GetFrameLevel() + 1);
|
|
|
|
region.extraTextures = {};
|
|
region.extraSpinners = {};
|
|
|
|
-- Use a dummy object for the SmoothStatusBarMixin, because our SetValue
|
|
-- is used for a different purpose
|
|
region.smoothProgress = {};
|
|
WeakAuras.Mixin(region.smoothProgress, Private.SmoothStatusBarMixin);
|
|
region.smoothProgress.SetValue = function(self, progress)
|
|
region:SetValueOnTexture(progress);
|
|
end
|
|
|
|
region.smoothProgress.GetValue = function(self)
|
|
return region.progress;
|
|
end
|
|
|
|
region.smoothProgress.GetMinMaxValues = function(self)
|
|
return 0, 1;
|
|
end
|
|
|
|
region.duration = 0;
|
|
region.expirationTime = math.huge;
|
|
|
|
Private.regionPrototype.create(region);
|
|
|
|
return region;
|
|
end
|
|
|
|
local function FrameTick(self)
|
|
local duration = self.duration
|
|
local expirationTime = self.expirationTime
|
|
local inverse = self.inverse
|
|
|
|
local progress = 1;
|
|
if (duration ~= 0) then
|
|
local remaining = expirationTime - GetTime();
|
|
progress = remaining / duration;
|
|
local inversed = not inverse ~= not self.inverseDirection
|
|
if(inversed) then
|
|
progress = 1 - progress;
|
|
end
|
|
end
|
|
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
|
|
if (self.useSmoothProgress) then
|
|
self.smoothProgress:SetSmoothedValue(progress);
|
|
else
|
|
self:SetValueOnTexture(progress);
|
|
end
|
|
end
|
|
|
|
local function modify(parent, region, data)
|
|
Private.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.useSmoothProgress = data.smoothProgress
|
|
foreground:SetWidth(data.width);
|
|
foreground:SetHeight(data.height);
|
|
local scaleWedge = 1 / 1.4142 * (1 + (data.crop or 0.41));
|
|
foregroundSpinner:SetWidth(data.width * scaleWedge);
|
|
foregroundSpinner:SetHeight(data.height * scaleWedge);
|
|
backgroundSpinner:SetWidth((data.width + data.backgroundOffset * 2) * scaleWedge);
|
|
backgroundSpinner:SetHeight((data.height + data.backgroundOffset * 2) * scaleWedge);
|
|
|
|
region:ClearAllPoints();
|
|
Private.AnchorFrame(data, region, parent)
|
|
region:SetAlpha(data.alpha);
|
|
|
|
background:SetTexture(data.sameTexture and data.foregroundTexture or data.backgroundTexture);
|
|
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);
|
|
|
|
foreground:SetTexture(data.foregroundTexture);
|
|
foreground:SetDesaturated(data.desaturateForeground)
|
|
foreground:SetBlendMode(data.blendMode);
|
|
|
|
foregroundSpinner:SetTexture(data.foregroundTexture);
|
|
foregroundSpinner:SetDesaturated(data.desaturateForeground);
|
|
foregroundSpinner:SetBlendMode(data.blendMode);
|
|
|
|
background:ClearAllPoints();
|
|
foreground:ClearAllPoints();
|
|
background:SetPoint("BOTTOMLEFT", region, "BOTTOMLEFT", -1 * data.backgroundOffset, -1 * data.backgroundOffset);
|
|
background:SetPoint("TOPRIGHT", region, "TOPRIGHT", data.backgroundOffset, data.backgroundOffset);
|
|
backgroundSpinner:SetBackgroundOffset(region, data.backgroundOffset);
|
|
|
|
region.mirror_h = data.mirror;
|
|
region.scale_x = 1 + (data.crop_x or 0.41);
|
|
region.scale_y = 1 + (data.crop_y or 0.41);
|
|
region.scale = 1 + (data.crop or 0.41);
|
|
region.rotation = data.rotation or 0;
|
|
region.cos_rotation = cos(region.rotation);
|
|
region.sin_rotation = sin(region.rotation);
|
|
region.user_x = -1 * (data.user_x or 0);
|
|
region.user_y = data.user_y or 0;
|
|
|
|
region.startAngle = data.startAngle or 0;
|
|
region.endAngle = data.endAngle or 360;
|
|
|
|
local function orientHorizontal()
|
|
foreground:ClearAllPoints();
|
|
foreground:SetPoint("LEFT", region, "LEFT");
|
|
region.orientation = "HORIZONTAL_INVERSE";
|
|
if(data.compress) then
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx, ULy = ApplyTransform(0, 0, region)
|
|
local LLx, LLy = ApplyTransform(0, 1, region)
|
|
local URx, URy = ApplyTransform(1, 0, region)
|
|
local LRx, LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetWidth(region:GetWidth() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
end
|
|
else
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx , ULy = ApplyTransform(0, 0, region)
|
|
local LLx , LLy = ApplyTransform(0, 1, region)
|
|
local URx , URy = ApplyTransform(progress, 0, region)
|
|
local URx_, URy_ = ApplyTransform(1, 0, region)
|
|
local LRx , LRy = ApplyTransform(progress, 1, region)
|
|
local LRx_, LRy_ = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx , URy , LRx , LRy );
|
|
foreground:SetWidth(region:GetWidth() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx, LLy, URx_, URy_, LRx_, LRy_);
|
|
end
|
|
end
|
|
end
|
|
local function orientHorizontalInverse()
|
|
foreground:ClearAllPoints();
|
|
foreground:SetPoint("RIGHT", region, "RIGHT");
|
|
region.orientation = "HORIZONTAL";
|
|
if(data.compress) then
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx, ULy = ApplyTransform(0, 0, region)
|
|
local LLx, LLy = ApplyTransform(0, 1, region)
|
|
local URx, URy = ApplyTransform(1, 0, region)
|
|
local LRx, LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetWidth(region:GetWidth() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
end
|
|
else
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx , ULy = ApplyTransform(1-progress, 0, region)
|
|
local ULx_, ULy_ = ApplyTransform(0, 0, region)
|
|
local LLx , LLy = ApplyTransform(1-progress, 1, region)
|
|
local LLx_, LLy_ = ApplyTransform(0, 1, region)
|
|
local URx , URy = ApplyTransform(1, 0, region)
|
|
local LRx , LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx , ULy , LLx , LLy , URx, URy, LRx, LRy);
|
|
foreground:SetWidth(region:GetWidth() * progress);
|
|
background:SetTexCoord(ULx_, ULy_, LLx_, LLy_, URx, URy, LRx, LRy);
|
|
end
|
|
end
|
|
end
|
|
local function orientVertical()
|
|
foreground:ClearAllPoints();
|
|
foreground:SetPoint("BOTTOM", region, "BOTTOM");
|
|
region.orientation = "VERTICAL_INVERSE";
|
|
if(data.compress) then
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx, ULy = ApplyTransform(0, 0, region)
|
|
local LLx, LLy = ApplyTransform(0, 1, region)
|
|
local URx, URy = ApplyTransform(1, 0, region)
|
|
local LRx, LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetHeight(region:GetHeight() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
end
|
|
else
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx , ULy = ApplyTransform(0, 1 - progress, region)
|
|
local ULx_, ULy_ = ApplyTransform(0, 0, region)
|
|
local LLx , LLy = ApplyTransform(0, 1, region)
|
|
local URx , URy = ApplyTransform(1, 1 - progress, region)
|
|
local URx_, URy_ = ApplyTransform(1, 0, region)
|
|
local LRx , LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetHeight(region:GetHeight() * progress);
|
|
background:SetTexCoord(ULx_, ULy_, LLx, LLy, URx_, URy_, LRx, LRy);
|
|
end
|
|
end
|
|
end
|
|
local function orientVerticalInverse()
|
|
foreground:ClearAllPoints();
|
|
foreground:SetPoint("TOP", region, "TOP");
|
|
region.orientation = "VERTICAL";
|
|
if(data.compress) then
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx, ULy = ApplyTransform(0, 0, region)
|
|
local LLx, LLy = ApplyTransform(0, 1, region)
|
|
local URx, URy = ApplyTransform(1, 0, region)
|
|
local LRx, LRy = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetHeight(region:GetHeight() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
end
|
|
else
|
|
function region:SetValueOnTexture(progress)
|
|
region.progress = progress;
|
|
|
|
local ULx , ULy = ApplyTransform(0, 0, region)
|
|
local LLx , LLy = ApplyTransform(0, progress, region)
|
|
local LLx_, LLy_ = ApplyTransform(0, 1, region)
|
|
local URx , URy = ApplyTransform(1, 0, region)
|
|
local LRx , LRy = ApplyTransform(1, progress, region)
|
|
local LRx_, LRy_ = ApplyTransform(1, 1, region)
|
|
|
|
foreground:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy);
|
|
foreground:SetHeight(region:GetHeight() * progress);
|
|
background:SetTexCoord(ULx, ULy, LLx_, LLy_, URx, URy, LRx_, LRy_);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function orientCircular(clockwise)
|
|
local startAngle = region.startAngle % 360; -- Convert 360 to 0
|
|
local endAngle = region.endAngle % 360;
|
|
|
|
if (data.inverse) then
|
|
clockwise = not clockwise;
|
|
startAngle = 360 - startAngle;
|
|
endAngle = 360 - endAngle;
|
|
end
|
|
if (endAngle <= startAngle) then
|
|
endAngle = endAngle + 360;
|
|
end
|
|
|
|
-- start is now 0-359, end 1-719, but at most 360 difference
|
|
|
|
region.orientation = clockwise and "CLOCKWISE" or "ANTICLOCKWISE";
|
|
|
|
backgroundSpinner:SetProgress(region, startAngle, endAngle, 1, clockwise);
|
|
|
|
function region:SetValueOnTexture(progress)
|
|
progress = progress or 0;
|
|
region.progress = progress;
|
|
if (progress < 0) then
|
|
progress = 0;
|
|
end
|
|
|
|
if (progress > 1) then
|
|
progress = 1;
|
|
end
|
|
foregroundSpinner:SetProgress(region, startAngle, endAngle, progress, clockwise);
|
|
end
|
|
end
|
|
|
|
local function showCircularProgress()
|
|
foreground:Hide();
|
|
background:Hide();
|
|
foregroundSpinner:Show();
|
|
backgroundSpinner:Show();
|
|
end
|
|
|
|
local function hideCircularProgress()
|
|
foreground:Show();
|
|
background:Show();
|
|
foregroundSpinner:Hide();
|
|
backgroundSpinner:Hide();
|
|
end
|
|
|
|
if(data.orientation == "HORIZONTAL_INVERSE") then
|
|
hideCircularProgress();
|
|
orientHorizontalInverse();
|
|
elseif(data.orientation == "HORIZONTAL") then
|
|
hideCircularProgress();
|
|
orientHorizontal();
|
|
elseif(data.orientation == "VERTICAL_INVERSE") then
|
|
hideCircularProgress();
|
|
orientVerticalInverse();
|
|
elseif(data.orientation == "VERTICAL") then
|
|
hideCircularProgress();
|
|
orientVertical();
|
|
elseif(data.orientation == "CLOCKWISE") then
|
|
showCircularProgress();
|
|
orientCircular(true);
|
|
elseif(data.orientation == "ANTICLOCKWISE") then
|
|
showCircularProgress();
|
|
orientCircular(false);
|
|
end
|
|
|
|
region:SetValueOnTexture(0.667);
|
|
|
|
function region:Scale(scalex, scaley)
|
|
region.scalex = scalex;
|
|
region.scaley = scaley;
|
|
foreground:ClearAllPoints();
|
|
if(scalex < 0) then
|
|
region.mirror_h = not data.mirror;
|
|
scalex = scalex * -1;
|
|
else
|
|
region.mirror_h = data.mirror;
|
|
end
|
|
if(region.mirror_h) 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(scaley < 0) then
|
|
region.mirror_v = true;
|
|
scaley = scaley * -1;
|
|
if(data.orientation == "VERTICAL_INVERSE") then
|
|
foreground:SetPoint("TOP", region, "TOP");
|
|
elseif(data.orientation == "VERTICAL") then
|
|
foreground:SetPoint("BOTTOM", region, "BOTTOM");
|
|
end
|
|
else
|
|
region.mirror_v = nil;
|
|
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 * scalex);
|
|
region:SetHeight(region.height * scaley);
|
|
|
|
local scaleWedge = 1 / 1.4142 * (1 + (data.crop or 0.41));
|
|
foregroundSpinner:SetWidth(region.width * scaleWedge * scalex);
|
|
foregroundSpinner:SetHeight(region.height * scaleWedge * scaley);
|
|
backgroundSpinner:SetWidth((region.width + data.backgroundOffset * 2) * scaleWedge * scalex);
|
|
backgroundSpinner:SetHeight((region.height + data.backgroundOffset * 2) * scaleWedge * scaley);
|
|
|
|
if(data.orientation == "HORIZONTAL_INVERSE" or data.orientation == "HORIZONTAL") then
|
|
foreground:SetWidth(region.width * scalex * (region.progress or 1));
|
|
foreground:SetHeight(region.height * scaley);
|
|
else
|
|
foreground:SetWidth(region.width * scalex);
|
|
foreground:SetHeight(region.height * scaley * (region.progress or 1));
|
|
end
|
|
background:SetPoint("BOTTOMLEFT", region, "BOTTOMLEFT", -1 * scalex * data.backgroundOffset, -1 * scaley * data.backgroundOffset);
|
|
background:SetPoint("TOPRIGHT", region, "TOPRIGHT", scalex * data.backgroundOffset, scaley * data.backgroundOffset);
|
|
end
|
|
|
|
function region:Rotate(angle)
|
|
region.rotation = angle or 0;
|
|
region.cos_rotation = cos(region.rotation);
|
|
region.sin_rotation = sin(region.rotation);
|
|
region:SetValueOnTexture(region.progress);
|
|
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:UpdateTime()
|
|
local progress = 1;
|
|
if (self.duration ~= 0) then
|
|
local remaining = self.expirationTime - GetTime()
|
|
progress = remaining / self.duration
|
|
local inversed = not self.inverse ~= not region.inverseDirection
|
|
if(inversed) then
|
|
progress = 1 - progress;
|
|
end
|
|
end
|
|
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
if (region.useSmoothProgress) then
|
|
region.smoothProgress:SetSmoothedValue(progress);
|
|
else
|
|
region:SetValueOnTexture(progress);
|
|
end
|
|
|
|
if self.paused and self.FrameTick then
|
|
self.FrameTick = nil
|
|
self.subRegionEvents:RemoveSubscriber("FrameTick", region)
|
|
end
|
|
if not self.paused and not self.FrameTick then
|
|
self.FrameTick = FrameTick
|
|
self.subRegionEvents:AddSubscriber("FrameTick", region)
|
|
end
|
|
end
|
|
|
|
function region:UpdateValue()
|
|
local progress = 1
|
|
if(self.total > 0) then
|
|
progress = self.value / self.total;
|
|
if(region.inverseDirection) then
|
|
progress = 1 - progress;
|
|
end
|
|
end
|
|
progress = progress > 0.0001 and progress or 0.0001;
|
|
if (region.useSmoothProgress) then
|
|
region.smoothProgress:SetSmoothedValue(progress);
|
|
else
|
|
region:SetValueOnTexture(progress);
|
|
end
|
|
|
|
if self.FrameTick then
|
|
self.FrameTick = nil
|
|
self.subRegionEvents:RemoveSubscriber("FrameTick", region)
|
|
end
|
|
end
|
|
|
|
if region.useSmoothProgress then
|
|
region.PreShow = function()
|
|
region.smoothProgress:ResetSmoothedValue();
|
|
end
|
|
else
|
|
region.PreShow = nil
|
|
end
|
|
|
|
region.FrameTick = nil
|
|
function region:Update()
|
|
region:UpdateProgress()
|
|
local state = region.state
|
|
|
|
if state.texture then
|
|
region:SetTexture(state.texture)
|
|
end
|
|
end
|
|
|
|
function region:SetTexture(texture)
|
|
region.currentTexture = texture;
|
|
region.foreground:SetTexture(texture);
|
|
foregroundSpinner:SetTexture(texture);
|
|
if (data.sameTexture) then
|
|
background:SetTexture(texture);
|
|
backgroundSpinner:SetTexture(texture);
|
|
end
|
|
|
|
for _, extraTexture in ipairs(region.extraTextures) do
|
|
extraTexture:SetTexture(texture);
|
|
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);
|
|
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
|
|
|
|
Private.regionPrototype.modifyFinish(parent, region, data);
|
|
end
|
|
|
|
local function validate(data)
|
|
Private.EnforceSubregionExists(data, "subbackground")
|
|
end
|
|
|
|
Private.RegisterRegionType("progresstexture", create, modify, default, GetProperties, validate);
|