From f9bf9c3c16ea18484e41b55004c490a4fbdf09cb Mon Sep 17 00:00:00 2001 From: NoM0Re Date: Sun, 26 Jan 2025 21:24:18 +0100 Subject: [PATCH] from retail --- WeakAuras/BaseRegions/StopMotion.lua | 355 ++++++++++++++ WeakAuras/Modernize.lua | 28 ++ WeakAuras/RegionTypes/AuraBar.lua | 15 +- WeakAuras/RegionTypes/Icon.lua | 11 +- WeakAuras/RegionTypes/Model.lua | 2 - WeakAuras/RegionTypes/RegionPrototype.lua | 64 ++- WeakAuras/RegionTypes/StopMotion.lua | 463 +++++------------- WeakAuras/SubRegionTypes/Border.lua | 9 +- WeakAuras/SubRegionTypes/Glow.lua | 18 +- WeakAuras/SubRegionTypes/StopMotion.lua | 277 +++++++++++ WeakAuras/SubRegionTypes/SubText.lua | 30 +- WeakAuras/SubRegionTypes/Tick.lua | 25 +- WeakAuras/Types.lua | 10 +- WeakAuras/WeakAuras.lua | 7 +- WeakAuras/WeakAuras.toc | 2 + WeakAurasOptions/CommonOptions.lua | 107 ++++ WeakAurasOptions/RegionOptions/AuraBar.lua | 20 +- WeakAurasOptions/RegionOptions/StopMotion.lua | 99 +--- WeakAurasOptions/SubRegionOptions/Border.lua | 8 +- WeakAurasOptions/SubRegionOptions/Glow.lua | 8 +- .../SubRegionOptions/StopMotion.lua | 350 +++++++++++++ .../SubRegionOptions/SubRegionCommon.lua | 37 +- WeakAurasOptions/SubRegionOptions/SubText.lua | 4 +- WeakAurasOptions/SubRegionOptions/Tick.lua | 17 +- WeakAurasOptions/WeakAurasOptions.toc | 1 + 25 files changed, 1467 insertions(+), 500 deletions(-) create mode 100644 WeakAuras/BaseRegions/StopMotion.lua create mode 100644 WeakAuras/SubRegionTypes/StopMotion.lua create mode 100644 WeakAurasOptions/SubRegionOptions/StopMotion.lua diff --git a/WeakAuras/BaseRegions/StopMotion.lua b/WeakAuras/BaseRegions/StopMotion.lua new file mode 100644 index 0000000..8358223 --- /dev/null +++ b/WeakAuras/BaseRegions/StopMotion.lua @@ -0,0 +1,355 @@ +if not WeakAuras.IsLibsOK() then return end + +local AddonName, Private = ... + +local L = WeakAuras.L +local texture_data = WeakAuras.StopMotion.texture_data + +Private.StopMotionBase = {} + +-- Helper method for Options +function Private.StopMotionBase.textureNameHasData(textureName) + if not textureName then + return false + end + local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]$" + local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]$" + local ok = textureName:lower():match(pattern) + if ok then return true end + local ok2 = textureName:match(pattern2) + if ok2 then + return true + else + return false + end +end + +local function setTile(texture, frame, rows, columns, frameScaleW, frameScaleH) + frame = frame - 1 + local row = floor(frame / columns) + local column = frame % columns + + local deltaX = frameScaleW / columns + local deltaY = frameScaleH / rows + + local left = deltaX * column + local right = left + deltaX + + local top = deltaY * row + local bottom = top + deltaY + pcall(function() texture:SetTexCoord(left, right, top, bottom) end) +end + +WeakAuras.setTile = setTile + +-- Helper method for Options +function Private.StopMotionBase.setTextureFunc(textureWidget, texturePath, textureName) + local data = texture_data[texturePath] + if not(data) then + local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]" + local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]" + local rows, columns, frames = texturePath:lower():match(pattern) + if rows then + data = { + count = tonumber(frames), + rows = tonumber(rows), + columns = tonumber(columns) + } + else + local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight = texturePath:match(pattern2) + if rows then + rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight + = tonumber(rows), tonumber(columns), tonumber(frames), tonumber(frameWidth), tonumber(frameHeight), + tonumber(fileWidth), tonumber(fileHeight) + local frameScaleW = 1 + local frameScaleH = 1 + if fileWidth > 0 and frameWidth > 0 then + frameScaleW = (frameWidth * columns) / fileWidth + end + if fileHeight > 0 and frameHeight > 0 then + frameScaleH = (frameHeight * rows) / fileHeight + end + data = { + count = frames, + rows = rows, + columns = columns, + frameScaleW = frameScaleW, + frameScaleH = frameScaleH + } + end + end + end + textureWidget.frameNr = 0 + if (data) then + if (data.rows and data.columns) then + -- Texture Atlas + textureWidget:SetTexture(texturePath, textureName) + + setTile(textureWidget, data.count, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1) + + textureWidget:SetOnUpdate(function(self, elapsed) + self.elapsed = (self.elapsed or 0) + elapsed + if(self.elapsed > 0.1) then + self.elapsed = self.elapsed - 0.1 + textureWidget.frameNr = textureWidget.frameNr + 1 + if (textureWidget.frameNr == data.count) then + textureWidget.frameNr = 1 + end + setTile(textureWidget, textureWidget.frameNr, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1) + end + end) + else + -- Numbered Textures + local texture = texturePath .. string.format("%03d", texture_data[texturePath].count) + textureWidget:SetTexture(texture, textureName) + textureWidget:SetTexCoord(0, 1, 0, 1) + + textureWidget:SetOnUpdate(function(self, elapsed) + self.elapsed = (self.elapsed or 0) + elapsed + if(self.elapsed > 0.1) then + self.elapsed = self.elapsed - 0.1 + textureWidget.frameNr = textureWidget.frameNr + 1 + if (textureWidget.frameNr == data.count) then + textureWidget.frameNr = 1 + end + local texture = texturePath .. string.format("%03d", textureWidget.frameNr) + textureWidget:SetTexture(texture, textureName) + end + end) + end + else + local texture = texturePath .. string.format("%03d", 1) + textureWidget:SetTexture(texture, textureName) + end +end + +local function SetTextureViaAtlas(self, texture) + self.texture:SetTexture(texture) +end + +local function SetFrameViaAtlas(self, texture, frame) + local frameScaleW = 1 + local frameScaleH = 1 + if self.fileWidth and self.frameWidth and self.fileWidth > 0 and self.frameWidth > 0 then + frameScaleW = (self.frameWidth * self.columns) / self.fileWidth + end + if self.fileHeight and self.frameHeight and self.fileHeight > 0 and self.frameHeight > 0 then + frameScaleH = (self.frameHeight * self.rows) / self.fileHeight + end + setTile(self.texture, frame, self.rows, self.columns, frameScaleW, frameScaleH) +end + +local function SetTextureViaFrames(self, texture) + self.texture:SetTexture(texture .. string.format("%03d", 0)) + self.texture:SetTexCoord(0, 1, 0, 1) +end + +local function SetFrameViaFrames(self, texture, frame) + self.texture:SetTexture(texture .. string.format("%03d", frame)) +end + +local funcs = { + SetDesaturated = function(self, b) + self.texture:SetDesaturated(b) + end, + SetColor = function(self, r, g, b, a) + self.texture:SetVertexColor(r, g, b, a) + end, + GetColor = function(self) + return self.texture:GetVertexColor() + end, + SetStartTime = function(self, time) + self.startTime = time + end, + TimedUpdate = function(self) + local timeSinceStart = (GetTime() - self.startTime) + local newCurrentFrame = floor(timeSinceStart * (self.frameRate or 15)) + if (newCurrentFrame == self.currentFrame) then + return + end + + self.currentFrame = newCurrentFrame + + local frames + local startFrame = self.startFrame + local endFrame = self.endFrame + local inverse = self.inverseDirection + if (endFrame >= startFrame) then + frames = endFrame - startFrame + 1 + else + frames = startFrame - endFrame + 1 + startFrame, endFrame = endFrame, startFrame + inverse = not inverse + end + + local frame = 0 + if (self.animationType == "loop") then + frame = (newCurrentFrame % frames) + startFrame + elseif (self.animationType == "bounce") then + local direction = floor(newCurrentFrame / frames) % 2 + if (direction == 0) then + frame = (newCurrentFrame % frames) + startFrame + else + frame = endFrame - (newCurrentFrame % frames) + end + elseif (self.animationType == "once") then + frame = newCurrentFrame + startFrame + if (frame > endFrame) then + frame = endFrame + end + end + if (inverse) then + frame = endFrame - frame + startFrame + end + + if (frame > endFrame) then + frame = endFrame + end + if (frame < startFrame) then + frame = startFrame + end + self:SetFrame(self.textureFile, frame) + end, + SetProgress = function(self, progress) + local frames + local startFrame = self.startFrame + local endFrame = self.endFrame + local inverse = self.inverseDirection + if (endFrame >= startFrame) then + frames = endFrame - startFrame + 1 + else + frames = startFrame - endFrame + 1 + startFrame, endFrame = endFrame, startFrame + inverse = not inverse + end + + local frame = floor( (frames - 1) * progress) + startFrame + + if (inverse) then + frame = endFrame - frame + startFrame + end + + if (frame > endFrame) then + frame = endFrame + end + if (frame < startFrame) then + frame = startFrame + end + self:SetFrame(self.textureFile, frame) + end, + ClearAllPoints = function(self) + self.texture:ClearAllPoints() + end, + SetAllPoints = function(self, ...) + self.texture:SetAllPoints(...) + end, + SetPoint = function(self, ...) + self.texture:SetPoint(...) + end, + SetSize = function(self, w, h) + self.texture:SetSize(w, h) + end, + SetVisible = function(self, b) + if b then + self.texture:Show() + else + self.texture:Hide() + end + end +} + +function Private.StopMotionBase.create(frame, drawLayer) + local stopMotion = {} + + local texture = frame:CreateTexture(nil, "ARTWORK") + stopMotion.texture = texture + texture:SetAllPoints(frame) + + for funcName, func in pairs(funcs) do + stopMotion[funcName] = func + end + + return stopMotion +end + +function Private.StopMotionBase.modify(stopMotion, options) + stopMotion.frameRate = options.frameRate + stopMotion.inverseDirection = options.inverseDirection + stopMotion.animationType = options.animationType + stopMotion.textureFile = options.texture + + local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]" + local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]" + + do -- setup texture + local tdata = texture_data[stopMotion.textureFile] + if (tdata) then + local lastFrame = tdata.count - 1 + stopMotion.lastFrame = lastFrame + stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1 + stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1 + stopMotion.rows = tdata.rows + stopMotion.columns = tdata.columns + stopMotion.fileWidth = 0 + stopMotion.fileHeight = 0 + stopMotion.frameWidth = 0 + stopMotion.frameHeight = 0 + else + local rows, columns, frames = stopMotion.textureFile:lower():match(pattern) + if rows then + local lastFrame = tonumber(frames) - 1 + stopMotion.lastFrame = lastFrame + stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1 + stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1 + stopMotion.rows = tonumber(rows) + stopMotion.columns = tonumber(columns) + stopMotion.fileWidth = 0 + stopMotion.fileHeight = 0 + stopMotion.frameWidth = 0 + stopMotion.frameHeight = 0 + else + local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight + = stopMotion.textureFile:match(pattern2) + if rows then + local lastFrame = tonumber(frames) - 1 + stopMotion.lastFrame = lastFrame + stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1 + stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1 + stopMotion.rows = tonumber(rows) + stopMotion.columns = tonumber(columns) + stopMotion.fileWidth = tonumber(fileWidth) + stopMotion.fileHeight = tonumber(fileHeight) + stopMotion.frameWidth = tonumber(frameWidth) + stopMotion.frameHeight = tonumber(frameHeight) + else + local lastFrame = (options.customFrames or 256) - 1 + stopMotion.lastFrame = lastFrame + stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1 + stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1 + stopMotion.rows = options.customRows + stopMotion.columns = options.customColumns + stopMotion.fileWidth = options.customFileWidth + stopMotion.fileHeight = options.customFileHeight + stopMotion.frameWidth = options.customFrameWidth + stopMotion.frameHeight = options.customFrameHeight + end + end + end + end + + if (stopMotion.rows and stopMotion.columns) then + stopMotion.SetBaseTexture = SetTextureViaAtlas + stopMotion.SetFrame = SetFrameViaAtlas + else + stopMotion.SetBaseTexture = SetTextureViaFrames + stopMotion.SetFrame = SetFrameViaFrames + end + + stopMotion:SetBaseTexture(options.texture) + if stopMotion.animationType == "background" then + stopMotion:SetFrame(options.texture, stopMotion.endFrame or 1) + else + stopMotion:SetFrame(options.texture, 1) + end + stopMotion.texture:SetBlendMode(options.blendMode) +end diff --git a/WeakAuras/Modernize.lua b/WeakAuras/Modernize.lua index 37808ef..54a6b91 100644 --- a/WeakAuras/Modernize.lua +++ b/WeakAuras/Modernize.lua @@ -1723,6 +1723,34 @@ function Private.Modernize(data, oldSnapshot) end end + if data.internalVersion < 80 then + -- Use common names for anchor areas/points so + -- that up/down of sub regions can adapt that + + local conversions = { + subborder = { + border_anchor = "anchor_area", + }, + subglow = { + glow_anchor = "anchor_area" + }, + subtext = { + text_anchorPoint = "anchor_point" + } + } + + if data.subRegions then + for index, subRegionData in ipairs(data.subRegions) do + if conversions[subRegionData.type] then + for oldKey, newKey in pairs(conversions[subRegionData.type]) do + subRegionData[newKey] = subRegionData[oldKey] + subRegionData[oldKey] = nil + end + end + end + end + end + data.internalVersion = max(data.internalVersion or 0, WeakAuras.InternalVersion()) end diff --git a/WeakAuras/RegionTypes/AuraBar.lua b/WeakAuras/RegionTypes/AuraBar.lua index 50de218..826c1dc 100644 --- a/WeakAuras/RegionTypes/AuraBar.lua +++ b/WeakAuras/RegionTypes/AuraBar.lua @@ -761,16 +761,21 @@ local function FrameTick(self) end local funcs = { - AnchorSubRegion = function(self, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset) + AnchorSubRegion = function(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + if anchorPoint:sub(1, 4) == "sub." then + Private.regionPrototype.AnchorSubRegion(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + return + end if anchorType == "area" then local anchor = self - if selfPoint == "bar" then + + if anchorPoint == "bar" then anchor = self - elseif selfPoint == "icon" then + elseif anchorPoint == "icon" then anchor = self.icon - elseif selfPoint == "fg" then + elseif anchorPoint == "fg" then anchor = self.bar.fgFrame - elseif selfPoint == "bg" then + elseif anchorPoint == "bg" then anchor = self.bar.bg end diff --git a/WeakAuras/RegionTypes/Icon.lua b/WeakAuras/RegionTypes/Icon.lua index 24cd933..86fa7e0 100644 --- a/WeakAuras/RegionTypes/Icon.lua +++ b/WeakAuras/RegionTypes/Icon.lua @@ -141,9 +141,16 @@ local function GetTexCoord(region, texWidth, aspectRatio, xOffset, yOffset) return unpack(region.currentCoord) end -local function AnchorSubRegion(self, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset) +local function AnchorSubRegion(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + if type(anchorPoint) == "string" and anchorPoint:sub(1, 4) == "sub." then + Private.regionPrototype.AnchorSubRegion(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + return + end + if anchorType == "area" then - Private.regionPrototype.AnchorSubRegion(selfPoint == "region" and self or self.icon, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset) + Private.regionPrototype.AnchorSubRegion(selfPoint == "region" and self or self.icon, + subRegion, anchorType, anchorPoint, + selfPoint, anchorXOffset, anchorYOffset) else subRegion:ClearAllPoints() anchorPoint = anchorPoint or "CENTER" diff --git a/WeakAuras/RegionTypes/Model.lua b/WeakAuras/RegionTypes/Model.lua index e8ced1e..3bd9c55 100644 --- a/WeakAuras/RegionTypes/Model.lua +++ b/WeakAuras/RegionTypes/Model.lua @@ -85,8 +85,6 @@ local function create(parent) region[k] = v end - region.AnchorSubRegion = Private.regionPrototype.AnchorSubRegion - -- Return complete region return region; end diff --git a/WeakAuras/RegionTypes/RegionPrototype.lua b/WeakAuras/RegionTypes/RegionPrototype.lua index 8eac24e..df9741c 100644 --- a/WeakAuras/RegionTypes/RegionPrototype.lua +++ b/WeakAuras/RegionTypes/RegionPrototype.lua @@ -20,25 +20,44 @@ end local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20; -function Private.GetAnchorsForData(parentData, type) - local result - if not parentData.controlledChildren then - if not Private.regionOptions[parentData.regionType] then +function Private.GetAnchorsForData(data, filter) + local result = {} + if not data.controlledChildren then + if not Private.regionOptions[data.regionType] then return end local anchors - if Private.regionOptions[parentData.regionType].getAnchors then - anchors = Private.regionOptions[parentData.regionType].getAnchors(parentData) + if Private.regionOptions[data.regionType].getAnchors then + anchors = Private.regionOptions[data.regionType].getAnchors(data) else anchors = Private.default_types_for_anchor end + for anchorId, anchorData in pairs(anchors) do - if anchorData.type == type then - result = result or {} + if anchorData.type == filter then result[anchorId] = anchorData.display end end + + local subElementTypeCounter = {} + for i, subRegion in ipairs(data.subRegions) do + subElementTypeCounter[subRegion.type] = (subElementTypeCounter[subRegion.type] or 0) + 1 + local getAnchors = Private.subRegionOptions[subRegion.type].getAnchors + if getAnchors then + local subRegionTypeData = Private.subRegionTypes[subRegion.type] + + local anchors = getAnchors(subRegion) + for key, anchorData in pairs(anchors) do + if anchorData.type == filter then + local subElementName = subRegionTypeData.displayName .. " " .. subElementTypeCounter[subRegion.type] + local anchorId = "sub." .. i .. "." .. key + result[anchorId] = {subElementName, anchorData.display} + end + end + end + end + end return result end @@ -607,16 +626,32 @@ local function Tick(self) Private.StopProfileAura(self.id) end -local function AnchorSubRegion(self, subRegion, anchorType, selfPoint, anchorPoint, anchorXOffset, anchorYOffset) - subRegion:ClearAllPoints() +local function ForwardAnchorToSubRegion(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + local nextdot = anchorPoint:find(".", 5, true) + local index = tonumber(anchorPoint:sub(5, nextdot - 1)) + local subElement = index and self.subRegions[index] or nil + if subElement then + local key = anchorPoint:sub(nextdot + 1) + if subElement.AnchorSubRegion then + subElement:AnchorSubRegion(subRegion, anchorType, key, selfPoint, anchorXOffset, anchorYOffset) + end + end +end +local function AnchorSubRegion(self, subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + if anchorPoint and anchorPoint:sub(1, 4) == "sub." then + self:ForwardAnchorToSubRegion(subRegion, anchorType, anchorPoint, selfPoint, anchorXOffset, anchorYOffset) + return + end if anchorType == "point" then + subRegion:ClearAllPoints() local xOffset = anchorXOffset or 0 local yOffset = anchorYOffset or 0 subRegion:SetPoint(Private.point_types[selfPoint] and selfPoint or "CENTER", self, Private.point_types[anchorPoint] and anchorPoint or "CENTER", xOffset, yOffset) else + subRegion:ClearAllPoints() anchorXOffset = anchorXOffset or 0 anchorYOffset = anchorYOffset or 0 subRegion:SetPoint("bottomleft", self, "bottomleft", -anchorXOffset, -anchorYOffset) @@ -669,8 +704,10 @@ function Private.regionPrototype.create(region) region.UpdateTick = UpdateTick region.Tick = Tick + region.subRegionEvents = Private.CreateSubscribableObject() region.AnchorSubRegion = AnchorSubRegion + region.ForwardAnchorToSubRegion = ForwardAnchorToSubRegion region.values = {} -- For SubText region:SetPoint("CENTER", UIParent, "CENTER") @@ -791,6 +828,13 @@ function Private.regionPrototype.modifyFinish(parent, region, data) tinsert(region.subRegions, subRegion) end end + + for index, subRegion in pairs(region.subRegions) do + if subRegion.Anchor then + subRegion:Anchor() + end + end + end region.subRegionEvents:SetOnSubscriptionStatusChanged("FrameTick", function() diff --git a/WeakAuras/RegionTypes/StopMotion.lua b/WeakAuras/RegionTypes/StopMotion.lua index 2bff0f3..8612457 100644 --- a/WeakAuras/RegionTypes/StopMotion.lua +++ b/WeakAuras/RegionTypes/StopMotion.lua @@ -1,7 +1,6 @@ if not WeakAuras.IsLibsOK() then return end local AddonName, Private = ... -local texture_data = WeakAuras.StopMotion.texture_data; local L = WeakAuras.L; local default = { @@ -96,162 +95,40 @@ local function GetProperties(data) end local function create(parent) - local frame = CreateFrame("Frame", nil, UIParent); - frame.regionType = "stopmotion" - frame:SetMovable(true); - frame:SetResizable(true); - frame:SetMinResize(1, 1); + local frame = CreateFrame("Frame", nil, UIParent) + frame:SetMovable(true) + frame:SetResizable(true) + frame:SetMinResize(1, 1) - local background = frame:CreateTexture(nil, "BACKGROUND"); - frame.background = background; - background:SetAllPoints(frame); + frame.background = Private.StopMotionBase.create(frame, "BACKGROUND") + frame.foreground = Private.StopMotionBase.create(frame, "ARTWORK") - local foreground = frame:CreateTexture(nil, "ARTWORK"); - frame.foreground = foreground; - foreground:SetAllPoints(frame); + frame.regionType = "stopmotion" + Private.regionPrototype.create(frame) - Private.regionPrototype.create(frame); - - return frame; -end - -local function SetTextureViaAtlas(self, texture) - self:SetTexture(texture); -end - -local function setTile(texture, frame, rows, columns, frameScaleW, frameScaleH) - frame = frame - 1; - local row = floor(frame / columns); - local column = frame % columns; - - local deltaX = frameScaleW / columns - local deltaY = frameScaleH / rows - - local left = deltaX * column; - local right = left + deltaX; - - local top = deltaY * row; - local bottom = top + deltaY; - pcall(function() texture:SetTexCoord(left, right, top, bottom) end) -end - -WeakAuras.setTile = setTile; - -local function SetFrameViaAtlas(self, texture, frame) - local frameScaleW = 1 - local frameScaleH = 1 - if self.fileWidth and self.frameWidth and self.fileWidth > 0 and self.frameWidth > 0 then - frameScaleW = (self.frameWidth * self.columns) / self.fileWidth - end - if self.fileHeight and self.frameHeight and self.fileHeight > 0 and self.frameHeight > 0 then - frameScaleH = (self.frameHeight * self.rows) / self.fileHeight - end - setTile(self, frame, self.rows, self.columns, frameScaleW, frameScaleH); -end - -local function SetTextureViaFrames(self, texture) - self:SetTexture(texture .. format("%03d", 0)); - self:SetTexCoord(0, 1, 0, 1); -end - -local function SetFrameViaFrames(self, texture, frame) - self:SetTexture(texture .. format("%03d", frame)); -end - -local function SetProgress(self, progress) - local frames - local startFrame = self.startFrame - local endFrame = self.endFrame - local inverse = self.inverseDirection - if (endFrame >= startFrame) then - frames = endFrame - startFrame + 1 - else - frames = startFrame - endFrame + 1 - startFrame, endFrame = endFrame, startFrame - inverse = not inverse - end - local frame = floor( (frames - 1) * progress) + startFrame - - if (inverse) then - frame = endFrame - frame + startFrame; - end - - if (frame > endFrame) then - frame = endFrame - end - if (frame < startFrame) then - frame = startFrame - end - self.foreground:SetFrame(self.foregroundTexture, frame); + return frame end local FrameTickFunctions = { progressTimer = function(self) Private.StartProfileSystem("stopmotion") Private.StartProfileAura(self.id) + local remaining = self.expirationTime - GetTime() local progress = 1 - (remaining / self.duration) - self:SetProgress(progress) + self.foreground:SetProgress(progress) Private.StopProfileAura(self.id) Private.StopProfileSystem("stopmotion") end, timed = function(self) - if (not self.startTime) then return end + if (not self.foreground.startTime) then return end Private.StartProfileSystem("stopmotion") Private.StartProfileAura(self.id) - local timeSinceStart = (GetTime() - self.startTime) - local newCurrentFrame = floor(timeSinceStart * (self.frameRate or 15)) - if (newCurrentFrame == self.currentFrame) then - Private.StopProfileAura(self.id) - Private.StopProfileSystem("stopmotion") - return - end - - self.currentFrame = newCurrentFrame - - local frames - local startFrame = self.startFrame - local endFrame = self.endFrame - local inverse = self.inverseDirection - if (endFrame >= startFrame) then - frames = endFrame - startFrame + 1 - else - frames = startFrame - endFrame + 1 - startFrame, endFrame = endFrame, startFrame - inverse = not inverse - end - - local frame = 0 - if (self.animationType == "loop") then - frame = (newCurrentFrame % frames) + startFrame - elseif (self.animationType == "bounce") then - local direction = floor(newCurrentFrame / frames) % 2 - if (direction == 0) then - frame = (newCurrentFrame % frames) + startFrame - else - frame = endFrame - (newCurrentFrame % frames) - end - elseif (self.animationType == "once") then - frame = newCurrentFrame + startFrame - if (frame > endFrame) then - frame = endFrame - end - end - if (inverse) then - frame = endFrame - frame + startFrame - end - - if (frame > endFrame) then - frame = endFrame - end - if (frame < startFrame) then - frame = startFrame - end - self.foreground:SetFrame(self.foregroundTexture, frame) + self.foreground:TimedUpdate() Private.StopProfileAura(self.id) Private.StopProfileSystem("stopmotion") @@ -259,167 +136,64 @@ local FrameTickFunctions = { } local function modify(parent, region, data) - Private.regionPrototype.modify(parent, region, data); - region.foreground = region.foreground or {} - region.background = region.background or {} - region.frameRate = data.frameRate - region.inverseDirection = data.inverse - region.animationType = data.animationType - region.foregroundTexture = data.foregroundTexture - region.FrameTick = nil - local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]" - local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]" + Private.regionPrototype.modify(parent, region, data) - do - local tdata = texture_data[data.foregroundTexture]; - if (tdata) then - local lastFrame = tdata.count - 1; - region.foreground.lastFrame = lastFrame - region.startFrame = floor( (data.startPercent or 0) * lastFrame) + 1; - region.endFrame = floor( (data.endPercent or 1) * lastFrame) + 1; - region.foreground.rows = tdata.rows; - region.foreground.columns = tdata.columns; - region.foreground.fileWidth = 0 - region.foreground.fileHeight = 0 - region.foreground.frameWidth = 0 - region.foreground.frameHeight = 0 - else - local rows, columns, frames = data.foregroundTexture:lower():match(pattern) - if rows then - local lastFrame = tonumber(frames) - 1; - region.foreground.lastFrame = lastFrame - region.startFrame = floor( (data.startPercent or 0) * lastFrame) + 1; - region.endFrame = floor( (data.endPercent or 1) * lastFrame) + 1; - region.foreground.rows = tonumber(rows) - region.foreground.columns = tonumber(columns) - region.foreground.fileWidth = 0 - region.foreground.fileHeight = 0 - region.foreground.frameWidth = 0 - region.foreground.frameHeight = 0 - else - local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight = data.foregroundTexture:match(pattern2) - if rows then - local lastFrame = tonumber(frames) - 1; - region.foreground.lastFrame = lastFrame - region.startFrame = floor( (data.startPercent or 0) * lastFrame) + 1; - region.endFrame = floor( (data.endPercent or 1) * lastFrame) + 1; - region.foreground.rows = tonumber(rows) - region.foreground.columns = tonumber(columns) - region.foreground.fileWidth = tonumber(fileWidth) - region.foreground.fileHeight = tonumber(fileHeight) - region.foreground.frameWidth = tonumber(frameWidth) - region.foreground.frameHeight = tonumber(frameHeight) - else - local lastFrame = (data.customForegroundFrames or 256) - 1; - region.foreground.lastFrame = lastFrame - region.startFrame = floor( (data.startPercent or 0) * lastFrame) + 1; - region.endFrame = floor( (data.endPercent or 1) * lastFrame) + 1; - region.foreground.rows = data.customForegroundRows; - region.foreground.columns = data.customForegroundColumns; - region.foreground.fileWidth = data.customForegroundFileWidth - region.foreground.fileHeight = data.customForegroundFileHeight - region.foreground.frameWidth = data.customForegroundFrameWidth - region.foreground.frameHeight = data.customForegroundFrameHeight - end - end - end - end + Private.StopMotionBase.modify(region.foreground, { + blendMode = data.blendMode, + -- Foreground Data + frameRate = data.frameRate, + inverseDirection = data.inverse, + animationType = data.animationType, + texture = data.foregroundTexture, + startPercent = data.startPercent, + endPercent = data.endPercent, + customFrames = data.customForegroundFrames, + customRows = data.customForegroundRows, + customColumns = data.customForegroundColumns, + customFileWidth = data.customForegroundFileWidth, + customFileHeight = data.customForegroundFileHeight, + customFrameWidth = data.customForegroundFrameWidth, + customFrameHeight = data.customForegroundFrameHeight, + }) - local backgroundTexture = data.sameTexture - and data.foregroundTexture - or data.backgroundTexture; - - do - if data.sameTexture then - region.backgroundFrame = floor( (data.backgroundPercent or 1) * region.foreground.lastFrame + 1); - region.background.rows = region.foreground.rows - region.background.columns = region.foreground.columns - region.background.fileWidth = region.foreground.fileWidth - region.background.fileHeight = region.foreground.fileHeight - region.background.frameWidth = region.foreground.frameWidth - region.background.frameHeight = region.foreground.frameHeight - else - local tdata = texture_data[data.backgroundTexture]; - if (tdata) then - local lastFrame = tdata.count - 1; - region.backgroundFrame = floor( (data.backgroundPercent or 1) * lastFrame + 1); - region.background.rows = tdata.rows; - region.background.columns = tdata.columns; - region.background.fileWidth = 0 - region.background.fileHeight = 0 - region.background.frameWidth = 0 - region.background.frameHeight = 0 - else - local rows, columns, frames = data.backgroundTexture:lower():match(pattern) - if rows then - local lastFrame = frames - 1; - region.backgroundFrame = floor( (data.backgroundPercent or 1) * lastFrame + 1); - region.background.rows = tonumber(rows) - region.background.columns = tonumber(columns) - region.background.fileWidth = 0 - region.background.fileHeight = 0 - region.background.frameWidth = 0 - region.background.frameHeight = 0 - else - local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight = data.backgroundTexture:match(pattern2) - if rows then - local lastFrame = frames - 1; - region.backgroundFrame = floor( (data.backgroundPercent or 1) * lastFrame + 1); - region.background.rows = tonumber(rows) - region.background.columns = tonumber(columns) - region.background.fileWidth = tonumber(fileWidth) - region.background.fileHeight = tonumber(fileHeight) - region.background.frameWidth = tonumber(frameWidth) - region.background.frameHeight = tonumber(frameHeight) - else - local lastFrame = (data.customBackgroundFrames or 256) - 1; - region.backgroundFrame = floor( (data.backgroundPercent or 1) * lastFrame + 1); - region.background.rows = data.customBackgroundRows; - region.background.columns = data.customBackgroundColumns; - region.background.fileWidth = data.customBackgroundFileWidth - region.background.fileHeight = data.customBackgroundFileHeight - region.background.frameWidth = data.customBackgroundFrameWidth - region.background.frameHeight = data.customBackgroundFrameHeight - end - end - end - end - end - - if (region.foreground.rows and region.foreground.columns) then - region.foreground.SetBaseTexture = SetTextureViaAtlas; - region.foreground.SetFrame = SetFrameViaAtlas; + if data.sameTexture then + Private.StopMotionBase.modify(region.background, { + blendMode = data.blendMode, + animationType = "background", + -- Background Data + texture = data.foregroundTexture, + startPercent = data.backgroundPercent, + endPercent = data.backgroundPercent, + customFrames = data.customForegroundFrames, + customRows = data.customForegroundRows, + customColumns = data.customForegroundColumns, + customFileWidth = data.customForegroundFileWidth, + customFileHeight = data.customForegroundFileHeight, + customFrameWidth = data.customForegroundFrameWidth, + customFrameHeight = data.customForegroundFrameHeight, + }) else - region.foreground.SetBaseTexture = SetTextureViaFrames; - region.foreground.SetFrame = SetFrameViaFrames; + Private.StopMotionBase.modify(region.background, { + blendMode = data.blendMode, + animationType = "background", + -- Background Data + texture = data.backgroundTexture, + startPercent = data.backgroundPercent, + endPercent = data.backgroundPercent, + customFrames = data.customBackgroundFrames, + customRows = data.customBackgroundRows, + customColumns = data.customBackgroundColumns, + customFileWidth = data.customBackgroundFileWidth, + customFileHeight = data.customBackgroundFileHeight, + customFrameWidth = data.customBackgroundFrameWidth, + customFrameHeight = data.customBackgroundFrameHeight, + }) end - if (region.background.rows and region.background.columns) then - region.background.SetBaseTexture = SetTextureViaAtlas; - region.background.SetFrame = SetFrameViaAtlas; - else - region.background.SetBaseTexture = SetTextureViaFrames; - region.background.SetFrame = SetFrameViaFrames; - end + region.background:SetVisible(not data.hideBackground) - - region.background:SetBaseTexture(backgroundTexture); - region.background:SetFrame(backgroundTexture, region.backgroundFrame or 1); region.background:SetDesaturated(data.desaturateBackground) - region.background:SetVertexColor(data.backgroundColor[1], data.backgroundColor[2], - data.backgroundColor[3], data.backgroundColor[4]) - region.background:SetBlendMode(data.blendMode); - - if (data.hideBackground) then - region.background:Hide(); - else - region.background:Show(); - end - - region.foreground:SetBaseTexture(data.foregroundTexture); - region.foreground:SetFrame(data.foregroundTexture, 1); - region.foreground:SetDesaturated(data.desaturateForeground); - region.foreground:SetBlendMode(data.blendMode); + region.foreground:SetDesaturated(data.desaturateForeground) region:SetWidth(data.width); region:SetHeight(data.height); @@ -429,22 +203,34 @@ local function modify(parent, region, data) region.scaley = 1; function region:Scale(scalex, scaley) - region.scalex = scalex; - region.scaley = scaley; - if(scalex < 0) then - region.mirror_h = true; - scalex = scalex * -1; - else - region.mirror_h = nil; - end - region:SetWidth(region.width * scalex); - if(scaley < 0) then - scaley = scaley * -1; - region.mirror_v = true; - else - region.mirror_v = nil; - end - region:SetHeight(region.height * scaley); + self.scalex = scalex + self.scaley = scaley + if(scalex < 0) then + self.mirror_h = true + scalex = scalex * -1 + else + self.mirror_h = nil + end + self:SetWidth(self.width * scalex) + if(scaley < 0) then + scaley = scaley * -1 + self.mirror_v = true + else + self.mirror_v = nil + end + self:SetHeight(self.height * scaley) + end + + -- Set colors + region.background:SetColor(data.backgroundColor[1], data.backgroundColor[2], + data.backgroundColor[3], data.backgroundColor[4]) + + function region:SetBackgroundColor(r, g, b, a) + self.background:SetColor(r, g, b, a) + end + + function region:GetColor() + return region.color_r, region.color_g, region.color_b, region.color_a end function region:Color(r, g, b, a) @@ -455,7 +241,7 @@ local function modify(parent, region, data) if (r or g or b) then a = a or 1; end - region.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); + region.foreground:SetColor(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) @@ -466,28 +252,24 @@ local function modify(parent, region, data) if (r or g or b) then a = a or 1; end - region.foreground:SetVertexColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a); - end - - function region:GetColor() - return region.color_r or data.color[1], region.color_g or data.color[2], - region.color_b or data.color[3], region.color_a or data.color[4]; + region.foreground:SetColor(r or region.color_r, g or region.color_g, b or region.color_b, a or region.color_a); end region:Color(data.foregroundColor[1], data.foregroundColor[2], data.foregroundColor[3], data.foregroundColor[4]); function region:PreShow() - region.startTime = GetTime(); + region.foreground:SetStartTime(GetTime()) if region.FrameTick then region:FrameTick() end end - region.SetProgress = SetProgress - + region.FrameTick = nil if data.animationType == "loop" or data.animationType == "bounce" or data.animationType == "once" then region.FrameTick = FrameTickFunctions.timed region.subRegionEvents:AddSubscriber("FrameTick", region, true) + region.UpdateValue = nil + region.UpdateTime = nil function region:Update() region:UpdateProgress() end @@ -501,7 +283,7 @@ local function modify(parent, region, data) if (self.total ~= 0) then progress = self.value / self.total end - self:SetProgress(progress) + self.foreground:SetProgress(progress) if self.FrameTick then self.FrameTick = nil self.subRegionEvents:RemoveSubscriber("FrameTick", self) @@ -509,13 +291,15 @@ local function modify(parent, region, data) end function region:UpdateTime() - if self.paused and self.FrameTick then - self.FrameTick = nil - self.subRegionEvents:RemoveSubscriber("FrameTick", self) - end - self.expirationTime = self.expirationTime - self.duration = self.duration - if not self.paused then + if self.paused then + if self.FrameTick then + self.FrameTick = nil + self.subRegionEvents:RemoveSubscriber("FrameTick", self) + end + local remaining = self.remaining + local progress = 1 - (remaining / self.duration) + self.foreground:SetProgress(progress) + else if not self.FrameTick then self.FrameTick = FrameTickFunctions.progressTimer self.subRegionEvents:AddSubscriber("FrameTick", self) @@ -523,31 +307,28 @@ local function modify(parent, region, data) self:FrameTick() end - end end - function region:SetForegroundDesaturated(b) - region.foreground:SetDesaturated(b); - end - - function region:SetBackgroundDesaturated(b) - region.background:SetDesaturated(b); - end - - function region:SetBackgroundColor(r, g, b, a) - region.background:SetVertexColor(r, g, b, a); - end - function region:SetRegionWidth(width) - region.width = width; - region:Scale(region.scalex, region.scaley); + self.width = width + self:Scale(self.scalex, self.scaley) end function region:SetRegionHeight(height) - region.height = height; - region:Scale(region.scalex, region.scaley); + self.height = height + self:Scale(self.scalex, self.scaley) end + + function region:SetForegroundDesaturated(b) + self.foreground:SetDesaturated(b) + end + + function region:SetBackgroundDesaturated(b) + self.background:SetDesaturated(b) + end + + Private.regionPrototype.modifyFinish(parent, region, data) end local function validate(data) diff --git a/WeakAuras/SubRegionTypes/Border.lua b/WeakAuras/SubRegionTypes/Border.lua index 0a82835..0cb487a 100644 --- a/WeakAuras/SubRegionTypes/Border.lua +++ b/WeakAuras/SubRegionTypes/Border.lua @@ -13,7 +13,7 @@ local default = function(parentType) border_size = 2, } if parentType == "aurabar" then - options["border_anchor"] = "bar" + options["anchor_area"] = "bar" end return options end @@ -48,8 +48,6 @@ end local function modify(parent, region, parentData, data, first) region:SetParent(parent) - parent:AnchorSubRegion(region, "area", parentData.regionType == "aurabar" and data.border_anchor, nil, data.border_offset, data.border_offset) - local edgeFile = SharedMedia:Fetch("border", data.border_edge) if edgeFile and edgeFile ~= "" then region:SetBackdrop({ @@ -76,6 +74,11 @@ local function modify(parent, region, parentData, data, first) end region:SetVisible(data.border_visible) + + region.Anchor = function() + parent:AnchorSubRegion(region, "area", parentData.regionType == "aurabar" and data.anchor_area or nil, + nil, data.border_offset, data.border_offset) + end end local function supports(regionType) diff --git a/WeakAuras/SubRegionTypes/Glow.lua b/WeakAuras/SubRegionTypes/Glow.lua index 5c21662..de447d1 100644 --- a/WeakAuras/SubRegionTypes/Glow.lua +++ b/WeakAuras/SubRegionTypes/Glow.lua @@ -22,7 +22,7 @@ local default = function(parentType) } if parentType == "aurabar" then options["glowType"] = "Pixel" - options["glow_anchor"] = "bar" + options["anchor_area"] = "bar" end return options end @@ -314,12 +314,6 @@ end local function modify(parent, region, parentData, data, first) region:SetParent(parent) region.parentRegionType = parentData.regionType - if parentData.regionType == "aurabar" then - parent:AnchorSubRegion(region, "area", data.glow_anchor) - else - parent:AnchorSubRegion(region, "area", data.glowType == "buttonOverlay" and "region") - end - region.parent = parent region.parentType = parentData.regionType @@ -338,6 +332,14 @@ local function modify(parent, region, parentData, data, first) region:SetVisible(data.glow) region:SetScript("OnSizeChanged", region.UpdateSize) + + region.Anchor = function() + if parentData.regionType == "aurabar" then + parent:AnchorSubRegion(region, "area", data.anchor_area) + else + parent:AnchorSubRegion(region, "area", (data.glowType == "buttonOverlay" or data.glowType == "Proc") and "region") + end + end end -- This is used by the templates to add glow @@ -357,7 +359,7 @@ function Private.getDefaultGlow(regionType) glowBorder = false, glowXOffset = 0, glowYOffset = 0, - glow_anchor = "bar" + anchor_area = "bar" } else return { diff --git a/WeakAuras/SubRegionTypes/StopMotion.lua b/WeakAuras/SubRegionTypes/StopMotion.lua new file mode 100644 index 0000000..0a8e332 --- /dev/null +++ b/WeakAuras/SubRegionTypes/StopMotion.lua @@ -0,0 +1,277 @@ +if not WeakAuras.IsLibsOK() then return end + +local AddonName, Private = ... + +local L = WeakAuras.L + +local default = function(parentType) + local defaults = { + stopmotionVisible = true, + barModelClip = true, + + stopmotionTexture = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\StopMotion", + stopmotionDesaturate = false, + stopmotionColor = {1, 1, 1, 1}, + stopmotionBlendMode = "BLEND", + startPercent = 0, + endPercent = 1, + + frameRate = 15, + animationType = "loop", + inverse = false, + customFrames = 0, + customRows = 16, + customColumns = 16, + customFileWidth = 0, + customFileHeight = 0, + customFrameWidth = 0, + customFrameHeight = 0, + + anchor_mode = "area", + self_point = "CENTER", + anchor_point = "CENTER", + width = 32, + height = 32, + scale = 1, + + progressSources = {-2, ""}, + } + + if IsAddOnLoaded("WeakAurasStopMotion") then + defaults.stopmotionTexture = "Interface\\AddOns\\WeakAurasStopMotion\\Textures\\IconOverlays\\ArcReactor" + defaults.frameRate = 30 + defaults.scale = 3 + end + + if parentType == "aurabar" then + defaults.anchor_area = "bar" + else + defaults.anchor_area = "ALL" + end + + return defaults +end + + +local properties = { + stopmotionVisible = { + display = L["Visibility"], + setter = "SetVisible", + type = "bool", + defaultProperty = true + }, + stopmotionDesaturate = { + display = L["Desaturate"], + setter = "SetDesaturated", + type = "bool", + }, + stopmotionColor = { + display = L["Color"], + setter = "SetColor", + type = "color" + }, +} + +local funcs = { + OnSizeChanged = function(self) + local w, h = self:GetSize() + self.stopMotion:SetSize(w * self.scale, h * self.scale) + end, + SetDesaturated = function(self, b) + self.stopMotion:SetDesaturated(b) + end, + SetColor = function(self, ...) + self.stopMotion:SetColor(...) + end, + +} + +local TimedFuncs = { + SetVisible = function(self, visible) + self.visible = visible + if visible then + self:Show() + self.stopMotion:SetStartTime(GetTime()) + self.FrameTick = function() + self.stopMotion:TimedUpdate() + end + self.parent.subRegionEvents:AddSubscriber("FrameTick", self) + else + self:Hide() + self.FrameTick = nil + self.parent.subRegionEvents:RemoveSubscriber("FrameTick", self) + end + end, + Update = function(self) end, +} + +local ProgressFuncs = { + UpdateFrameTick = function(self) + if self.visible and self.progressData.progressType == "timed" and not self.progressData.paused then + if not self.FrameTick then + self.FrameTick = self.UpdateFrame + + self.parent.subRegionEvents:AddSubscriber("FrameTick", self) + end + else + if self.FrameTick then + self.FrameTick = nil + self.parent.subRegionEvents:RemoveSubscriber("FrameTick", self) + end + end + end, + SetVisible = function(self, visible) + self.visible = visible + if visible then + self:Show() + else + self:Hide() + end + self:UpdateFrame() + self:UpdateFrameTick() + end, + UpdateFrame = function(self) + if self.visible then + local progressData = self.progressData + if progressData.progressType == "static" then + local progress = 0 + if progressData.total ~= 0 then + progress = progressData.value / progressData.total + end + self.stopMotion:SetProgress(progress) + elseif progressData.progressType == "timed" then + if progressData.paused then + local remaining = self.progressData.remaining + local progress = 1 - (remaining / self.progressData.duration) + self.stopMotion:SetProgress(progress) + else + local remaining = self.progressData.expirationTime - GetTime() + local progress = 1 - (remaining / self.progressData.duration) + self.stopMotion:SetProgress(progress) + end + end + end + end, + Update = function(self, state, states) + Private.UpdateProgressFrom(self.progressData, self.progressSource, {}, state, states, self.parent) + self:UpdateFrame() + self:UpdateFrameTick() + end, +} + +local function create() + local region = CreateFrame("Frame", nil, UIParent) + --region:SetFlattensRenderLayers(true) + + for k, v in pairs(funcs) do + region[k] = v + end + + region.stopMotion = Private.StopMotionBase.create(region, "ARTWORK") + region.progressData = {} + + return region +end + +local function onAcquire(subRegion) + subRegion:Show() +end + +local function onRelease(subRegion) + subRegion:Hide() +end + +local function modify(parent, region, parentData, data, first) + region.parent = parent + region:SetParent(parent) + region.scale = data.scale or 1 + region.Anchor = nil + + if parentData.regionType == "aurabar" + and data.anchor_mode == "area" + and data.anchor_area == "fg" + and data.barModelClip + then + -- Special anchoring for clipping ! + region:SetScript("OnSizeChanged", nil) + region:ClearAllPoints() + region:SetAllPoints(parent.bar.fgFrame) + region.stopMotion:ClearAllPoints() + region.stopMotion:SetAllPoints(region.parent.bar) + else + local arg1 = data.anchor_mode == "point" and data.anchor_point or data.anchor_area + local arg2 = data.anchor_mode == "point" and data.self_point or nil + + if data.anchor_mode == "area" and data.scale ~= 1 then + -- Extra Scale mode + region.stopMotion:ClearAllPoints() + region.stopMotion:SetPoint("CENTER", region, "CENTER") + region:SetScript("OnSizeChanged", region.OnSizeChanged) + region:OnSizeChanged() + else + if data.anchor_mode == "point" then + region:SetSize(data.width or 0, data.height or 0) + end + region.stopMotion:ClearAllPoints() + region.stopMotion:SetAllPoints(region) + region:SetScript("OnSizeChanged", nil) + end + + region.Anchor = function() + region:ClearAllPoints() + parent:AnchorSubRegion(region, data.anchor_mode, arg1, arg2, data.xOffset, data.yOffset) + if data.anchor_mode == "area" and data.scale ~= 1 then + region:OnSizeChanged() + end + end + end + + Private.StopMotionBase.modify(region.stopMotion, { + blendMode = data.stopmotionBlendMode, + frameRate = data.frameRate, + inverseDirection = data.inverse, + animationType = data.animationType, + texture = data.stopmotionTexture, + startPercent = data.startPercent, + endPercent = data.endPercent, + customFrames = data.customFrames, + customRows = data.customRows, + customColumns = data.customColumns, + customFileWidth = data.customFileWidth, + customFileHeight = data.customFileHeight, + customFrameWidth = data.customFrameWidth, + customFrameHeight = data.customFrameHeight, + }) + + region.progressSource = Private.AddProgressSourceMetaData(parentData, data.progressSources or {-2, ""}) + + region.FrameTick = nil + if data.animationType == "loop" or data.animationType == "bounce" or data.animationType == "once" then + region.Update = TimedFuncs.Update + region.SetVisible = TimedFuncs.SetVisible + region.UpdateFrameTick = nil + region.UpdateFrame = nil + + parent.subRegionEvents:RemoveSubscriber("Update", region) + else + region.Update = ProgressFuncs.Update + region.SetVisible = ProgressFuncs.SetVisible + region.UpdateFrameTick = ProgressFuncs.UpdateFrameTick + region.UpdateFrame = ProgressFuncs.UpdateFrame + + parent.subRegionEvents:AddSubscriber("Update", region) + end + + region:SetVisible(data.stopmotionVisible) + region:SetDesaturated(data.stopmotionDesaturate) +end + +local function supports(regionType) + return regionType == "texture" + or regionType == "progresstexture" + or regionType == "icon" + or regionType == "aurabar" + or regionType == "text" +end + +WeakAuras.RegisterSubRegionType("substopmotion", L["Stop Motion"], supports, create, modify, onAcquire, onRelease, default, nil, properties) diff --git a/WeakAuras/SubRegionTypes/SubText.lua b/WeakAuras/SubRegionTypes/SubText.lua index ba49f24..0814510 100644 --- a/WeakAuras/SubRegionTypes/SubText.lua +++ b/WeakAuras/SubRegionTypes/SubText.lua @@ -22,7 +22,7 @@ local default = function(parentType) text_justify = "CENTER", text_selfPoint = "AUTO", - text_anchorPoint = "CENTER", + anchor_point = "CENTER", anchorXOffset = 0, anchorYOffset = 0, @@ -46,7 +46,7 @@ local default = function(parentType) text_justify = "CENTER", text_selfPoint = "AUTO", - text_anchorPoint = parentType == "aurabar" and "INNER_RIGHT" or "BOTTOMLEFT", + anchor_point = parentType == "aurabar" and "INNER_RIGHT" or "BOTTOMLEFT", anchorXOffset = 0, anchorYOffset = 0, @@ -256,7 +256,7 @@ local function modify(parent, region, parentData, data, first) if text:GetFont() then text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(textStr)) end - region:UpdateAnchor() + region:Anchor() end end @@ -340,7 +340,7 @@ local function modify(parent, region, parentData, data, first) region.text:SetFont(fontPath, size < 33 and size or 33, data.text_fontType); end region.text:SetTextHeight(size) - region:UpdateAnchor(); + region:Anchor(); end function region:SetVisible(visible) @@ -367,7 +367,7 @@ local function modify(parent, region, parentData, data, first) local selfPoint = data.text_selfPoint if selfPoint == "AUTO" then if parentData.regionType == "icon" then - local anchorPoint = data.text_anchorPoint or "CENTER" + local anchorPoint = data.anchor_point or "CENTER" if anchorPoint:sub(1, 6) == "INNER_" then selfPoint = anchorPoint:sub(7) elseif anchorPoint:sub(1, 6) == "OUTER_" then @@ -377,7 +377,7 @@ local function modify(parent, region, parentData, data, first) selfPoint = "CENTER" end elseif parentData.regionType == "aurabar" then - selfPoint = data.text_anchorPoint or "CENTER" + selfPoint = data.anchor_point or "CENTER" if selfPoint:sub(1, 5) == "ICON_" then selfPoint = selfPoint:sub(6) elseif selfPoint:sub(1, 6) == "INNER_" then @@ -385,15 +385,16 @@ local function modify(parent, region, parentData, data, first) end selfPoint = Private.point_types[selfPoint] and selfPoint or "CENTER" else - selfPoint = Private.inverse_point_types[data.text_anchorPoint or "CENTER"] or "CENTER" + selfPoint = Private.inverse_point_types[data.anchor_point or "CENTER"] or "CENTER" end end region.text_anchorXOffset = data.text_anchorXOffset region.text_anchorYOffset = data.text_anchorYOffset - region.UpdateAnchor = function(self) - parent:AnchorSubRegion(text, "point", selfPoint, data.text_anchorPoint, self.text_anchorXOffset or 0, self.text_anchorYOffset or 0) + region.Anchor = function(self) + parent:AnchorSubRegion(text, "point", data.anchor_point, selfPoint, + self.text_anchorXOffset or 0, self.text_anchorYOffset or 0) end region.SetXOffset = function(self, xOffset) @@ -401,7 +402,7 @@ local function modify(parent, region, parentData, data, first) return end self.text_anchorXOffset = xOffset - self:UpdateAnchor() + self:Anchor() end region.SetYOffset = function(self, yOffset) @@ -409,12 +410,11 @@ local function modify(parent, region, parentData, data, first) return end self.text_anchorYOffset = yOffset - self:UpdateAnchor() + self:Anchor() end region:Color(data.text_color[1], data.text_color[2], data.text_color[3], data.text_color[4]); region:SetVisible(data.text_visible) - region:UpdateAnchor() end local function addDefaultsForNewAura(data) @@ -430,7 +430,7 @@ local function addDefaultsForNewAura(data) text_visible = true, text_selfPoint = "AUTO", - text_anchorPoint = "INNER_LEFT", + anchor_point = "INNER_LEFT", anchorXOffset = 0, anchorYOffset = 0, @@ -450,7 +450,7 @@ local function addDefaultsForNewAura(data) text_visible = true, text_selfPoint = "AUTO", - text_anchorPoint = "INNER_RIGHT", + anchor_point = "INNER_RIGHT", anchorXOffset = 0, anchorYOffset = 0, @@ -470,7 +470,7 @@ local function addDefaultsForNewAura(data) text_visible = true, text_selfPoint = "AUTO", - text_anchorPoint = "INNER_BOTTOMRIGHT", + anchor_point = "INNER_BOTTOMRIGHT", anchorXOffset = 0, anchorYOffset = 0, diff --git a/WeakAuras/SubRegionTypes/Tick.lua b/WeakAuras/SubRegionTypes/Tick.lua index 93c5244..a70d28d 100644 --- a/WeakAuras/SubRegionTypes/Tick.lua +++ b/WeakAuras/SubRegionTypes/Tick.lua @@ -443,6 +443,28 @@ local funcs = { end self.use_texture = use self:UpdateTexture() + end, + AnchorSubRegion = function(self, subRegion, anchorType, anchorPoint, subRegionPoint, anchorXOffset, anchorYOffset) + subRegion:ClearAllPoints() + if anchorType == "point" then + local xOffset = anchorXOffset or 0 + local yOffset = anchorYOffset or 0 + subRegionPoint = Private.point_types[subRegionPoint] and subRegionPoint or "CENTER" + local tickIndex = tonumber(anchorPoint:sub(6)) + local anchorTo = tickIndex and self.ticks[tickIndex] or nil + if anchorTo then + subRegion:SetPoint(subRegionPoint, anchorTo, "CENTER", xOffset, yOffset) + end + else + local tickIndex = tonumber(anchorPoint:sub(10)) + local anchorTo = tickIndex and self.ticks[tickIndex] or nil + local xOffset = anchorXOffset or 0 + local yOffset = anchorYOffset or 0 + if anchorTo then + subRegion:SetPoint("BOTTOMLEFT", anchorTo, "BOTTOMLEFT", -xOffset, -yOffset) + subRegion:SetPoint("TOPRIGHT", anchorTo, "TOPRIGHT", xOffset, yOffset) + end + end end } @@ -483,7 +505,7 @@ local function modify(parent, region, parentData, data, first) if region.ticks[i] == nil then local texture = region:CreateTexture() texture:SetDrawLayer("ARTWORK", 3) - texture:SetAllPoints(region) + texture:SetAllPoints() region.ticks[i] = texture end end @@ -520,6 +542,7 @@ local function modify(parent, region, parentData, data, first) region:SetTickRotation(data.tick_rotation) region:SetTickMirror(data.tick_mirror) + region:UpdateTickPlacement() region:UpdateTickSize() parent.subRegionEvents:AddSubscriber("Update", region) diff --git a/WeakAuras/Types.lua b/WeakAuras/Types.lua index 8b86f8f..e47a568 100644 --- a/WeakAuras/Types.lua +++ b/WeakAuras/Types.lua @@ -935,15 +935,13 @@ for k, v in pairs(Private.point_types) do end Private.default_types_for_anchor["ALL"] = { - display = L["Whole Area"], + display = L["Full Region"], type = "area" } -Private.aurabar_anchor_areas = { - icon = L["Icon"], - fg = L["Foreground"], - bg = L["Background"], - bar = L["Full Bar"], +Private.anchor_mode = { + area = L["Fill Area"], + point = L["Attach to Point"] } Private.inverse_point_types = { diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 8c2ba15..dcbaf88 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -1,6 +1,6 @@ local AddonName, Private = ... -local internalVersion = 79 +local internalVersion = 80 -- Lua APIs local insert = table.insert @@ -518,7 +518,7 @@ function Private.RegisterRegionOptions(name, createFunction, icon, displayName, end end -function WeakAuras.RegisterSubRegionOptions(name, createFunction, description) +function WeakAuras.RegisterSubRegionOptions(name, createFunction, description, getAnchors) if not(name) then error("Improper arguments to WeakAuras.RegisterSubRegionOptions - name is not defined", 2); elseif(type(name) ~= "string") then @@ -527,11 +527,14 @@ function WeakAuras.RegisterSubRegionOptions(name, createFunction, description) error("Improper arguments to WeakAuras.RegisterSubRegionOptions - creation function is not defined", 2); elseif(type(createFunction) ~= "function") then error("Improper arguments to WeakAuras.RegisterSubRegionOptions - creation function is not a function", 2); + elseif(getAnchors and type(getAnchors) ~= "function") then + error("Improper arguments to WeakAuras.RegisterSubRegionOptions - getAnchors function is not a function", 2); elseif(subRegionOptions[name]) then error("Improper arguments to WeakAuras.RegisterSubRegionOptions - region type \""..name.."\" already defined", 2); else subRegionOptions[name] = { create = createFunction, + getAnchors = getAnchors, description = description, }; end diff --git a/WeakAuras/WeakAuras.toc b/WeakAuras/WeakAuras.toc index 511ebca..2845ccd 100644 --- a/WeakAuras/WeakAuras.toc +++ b/WeakAuras/WeakAuras.toc @@ -62,6 +62,7 @@ RegionTypes\Icon.lua RegionTypes\Text.lua RegionTypes\Group.lua RegionTypes\DynamicGroup.lua +BaseRegions\StopMotion.lua RegionTypes\StopMotion.lua RegionTypes\Model.lua @@ -72,6 +73,7 @@ SubRegionTypes\Border.lua SubRegionTypes\Glow.lua SubRegionTypes\Tick.lua SubRegionTypes\Model.lua +SubRegionTypes\StopMotion.lua #Misc DiscordList.lua \ No newline at end of file diff --git a/WeakAurasOptions/CommonOptions.lua b/WeakAurasOptions/CommonOptions.lua index 1ac39d6..668fff0 100644 --- a/WeakAurasOptions/CommonOptions.lua +++ b/WeakAurasOptions/CommonOptions.lua @@ -1463,6 +1463,112 @@ local function PositionOptions(id, data, _, hideWidthHeight, disableSelfPoint, g return positionOptions; end +local function PositionOptionsForSubElement(data, options, startOrder, areaAnchors, pointAnchors) + options.anchor_mode = { + name = L["Anchor Mode"], + type = "select", + width = WeakAuras.normalWidth, + order = startOrder, + values = OptionsPrivate.Private.anchor_mode, + } + + options.anchor_area = { + name = L["Area"], + type = "select", + width = WeakAuras.normalWidth, + control = "WeakAurasTwoColumnDropdown", + order = startOrder + 0.1, + values = areaAnchors, + hidden = function() + return data.anchor_mode == "point" + end + } + + options.anchor_space = { + name = "", + type = "description", + order = startOrder + 0.2, + hidden = function() + return data.anchor_mode == "area" + end + } + + options.self_point = { + name = L["Anchor"], + type = "select", + width = WeakAuras.normalWidth, + control = "WeakAurasTwoColumnDropdown", + order = startOrder + 0.3, + values = OptionsPrivate.Private.point_types, + hidden = function() + return data.anchor_mode == "area" + end + } + + options.anchor_point = { + name = L["To Region's"], + type = "select", + width = WeakAuras.normalWidth, + control = "WeakAurasTwoColumnDropdown", + order = startOrder + 0.4, + values = pointAnchors, + hidden = function() + return data.anchor_mode == "area" + end + } + + options.width = { + name = L["Width"], + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + min = 0, + softMax = 200, + step = 1, + order = startOrder + 0.5, + hidden = function() + return data.anchor_mode == "area" + end + } + + options.height = { + name = L["Height"], + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + min = 0, + softMax = 200, + step = 1, + order = startOrder + 0.6, + hidden = function() + return data.anchor_mode == "area" + end + } + + options.xOffset = { + type = "range", + control = "WeakAurasSpinBox", + name = L["X Offset"], + order = startOrder + 0.7, + width = WeakAuras.normalWidth, + softMin = -200, + softMax = 200, + step = 1, + } + + options.yOffset = { + type = "range", + control = "WeakAurasSpinBox", + name = L["Y Offset"], + order = startOrder + 0.8, + width = WeakAuras.normalWidth, + softMin = -200, + softMax = 200, + step = 1, + } + +end + local function BorderOptions(id, data, showBackDropOptions, hiddenFunc, order) local borderOptions = { borderHeader = { @@ -1794,6 +1900,7 @@ OptionsPrivate.commonOptions.CreateSetAll = CreateSetAll OptionsPrivate.commonOptions.CreateExecuteAll = CreateExecuteAll OptionsPrivate.commonOptions.PositionOptions = PositionOptions +OptionsPrivate.commonOptions.PositionOptionsForSubElement = PositionOptionsForSubElement OptionsPrivate.commonOptions.ProgressOptions = ProgressOptions OptionsPrivate.commonOptions.BorderOptions = BorderOptions OptionsPrivate.commonOptions.AddCodeOption = AddCodeOption diff --git a/WeakAurasOptions/RegionOptions/AuraBar.lua b/WeakAurasOptions/RegionOptions/AuraBar.lua index d3a601b..60a7f5a 100644 --- a/WeakAurasOptions/RegionOptions/AuraBar.lua +++ b/WeakAurasOptions/RegionOptions/AuraBar.lua @@ -839,10 +839,26 @@ local anchorPoints = { display = L["Spark"], type = "point" }, - ALL = { - display = L["Whole Area"], + + bar = { + display = L["Full Bar"], type = "area" }, + + icon = { + display = L["Icon"], + type = "area" + }, + + fg = { + display = L["Foreground"], + type = "area" + }, + + bg = { + display = L["Background"], + type = "area" + } } local function GetAnchors(data) diff --git a/WeakAurasOptions/RegionOptions/StopMotion.lua b/WeakAurasOptions/RegionOptions/StopMotion.lua index 0504d73..0f963b0 100644 --- a/WeakAurasOptions/RegionOptions/StopMotion.lua +++ b/WeakAurasOptions/RegionOptions/StopMotion.lua @@ -6,101 +6,10 @@ local AddonName, OptionsPrivate = ... local texture_types = WeakAuras.StopMotion.texture_types; local texture_data = WeakAuras.StopMotion.texture_data; local animation_types = WeakAuras.StopMotion.animation_types; -local setTile = WeakAuras.setTile - -local function setTextureFunc(textureWidget, texturePath, textureName) - local data = texture_data[texturePath]; - if not(data) then - local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]" - local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]" - local rows, columns, frames = texturePath:lower():match(pattern) - if rows then - data = { - count = tonumber(frames), - rows = tonumber(rows), - columns = tonumber(columns) - } - else - local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight = texturePath:match(pattern2) - if rows then - rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight - = tonumber(rows), tonumber(columns), tonumber(frames), tonumber(frameWidth), tonumber(frameHeight), tonumber(fileWidth), tonumber(fileHeight) - local frameScaleW = 1 - local frameScaleH = 1 - if fileWidth > 0 and frameWidth > 0 then - frameScaleW = (frameWidth * columns) / fileWidth - end - if fileHeight > 0 and frameHeight > 0 then - frameScaleH = (frameHeight * rows) / fileHeight - end - data = { - count = frames, - rows = rows, - columns = columns, - frameScaleW = frameScaleW, - frameScaleH = frameScaleH - } - end - end - end - textureWidget.frameNr = 0; - if (data) then - if (data.rows and data.columns) then - -- Texture Atlas - textureWidget:SetTexture(texturePath, textureName); - - setTile(textureWidget, data.count, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1); - - textureWidget:SetOnUpdate(function(self, elapsed) - self.elapsed = (self.elapsed or 0) + elapsed - if(self.elapsed > 0.1) then - self.elapsed = self.elapsed - 0.1; - textureWidget.frameNr = textureWidget.frameNr + 1; - if (textureWidget.frameNr == data.count) then - textureWidget.frameNr = 1; - end - setTile(textureWidget, textureWidget.frameNr, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1); - end - end) - else - -- Numbered Textures - local texture = texturePath .. format("%03d", texture_data[texturePath].count) - textureWidget:SetTexture(texture, textureName) - textureWidget:SetTexCoord(0, 1, 0, 1); - - textureWidget:SetOnUpdate(function(self, elapsed) - self.elapsed = (self.elapsed or 0) + elapsed - if(self.elapsed > 0.1) then - self.elapsed = self.elapsed - 0.1; - textureWidget.frameNr = textureWidget.frameNr + 1; - if (textureWidget.frameNr == data.count) then - textureWidget.frameNr = 1; - end - local texture = texturePath .. format("%03d", textureWidget.frameNr) - textureWidget:SetTexture(texture, textureName); - end - end); - end - else - local texture = texturePath .. format("%03d", 1) - textureWidget:SetTexture(texture, textureName); - end -end - -local function textureNameHasData(textureName) - local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]$" - local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]$" - local ok = textureName:lower():match(pattern) - if ok then return true end - local ok2 = textureName:match(pattern2) - if ok2 then - return true - else - return false - end -end local function createOptions(id, data) + local textureNameHasData = OptionsPrivate.Private.StopMotionBase.textureNameHasData + local setTextureFunc = OptionsPrivate.Private.StopMotionBase.setTextureFunc local options = { __title = L["Stop Motion Settings"], __order = 1, @@ -691,11 +600,11 @@ local function modifyThumbnail(parent, region, data, fullModify, size) frameScaleH = (region.foreground.frameHeight * region.foreground.rows) / region.foreground.fileHeight end - setTile(region.texture, frame, region.foreground.rows, region.foreground.columns, frameScaleW, frameScaleH); + WeakAuras.setTile(region.texture, frame, region.foreground.rows, region.foreground.columns, frameScaleW, frameScaleH); region.SetValue = function(self, percent) local frame = floor(percent * (region.endFrame - region.startFrame) + region.startFrame); - setTile(self.texture, frame, region.foreground.rows, region.foreground.columns, frameScaleW, frameScaleH); + WeakAuras.setTile(self.texture, frame, region.foreground.rows, region.foreground.columns, frameScaleW, frameScaleH); end else region.texture:SetTexture(texture .. format("%03d", frame)); diff --git a/WeakAurasOptions/SubRegionOptions/Border.lua b/WeakAurasOptions/SubRegionOptions/Border.lua index fd12637..0025851 100644 --- a/WeakAurasOptions/SubRegionOptions/Border.lua +++ b/WeakAurasOptions/SubRegionOptions/Border.lua @@ -4,6 +4,10 @@ local AddonName, OptionsPrivate = ... local L = WeakAuras.L; local function createOptions(parentData, data, index, subIndex) + local areaAnchors = {} + for child in OptionsPrivate.Private.TraverseLeafsOrAura(parentData) do + WeakAuras.Mixin(areaAnchors, OptionsPrivate.Private.GetAnchorsForData(child, "area")) + end local options = { __title = L["Border %s"]:format(subIndex), __order = 1, @@ -48,12 +52,12 @@ local function createOptions(parentData, data, index, subIndex) softMax = 64, bigStep = 1, }, - border_anchor = { + anchor_area = { type = "select", width = WeakAuras.normalWidth, name = L["Border Anchor"], order = 7, - values = OptionsPrivate.Private.aurabar_anchor_areas, + values = areaAnchors, hidden = function() return parentData.regionType ~= "aurabar" end } } diff --git a/WeakAurasOptions/SubRegionOptions/Glow.lua b/WeakAurasOptions/SubRegionOptions/Glow.lua index 1eff8fc..3373658 100644 --- a/WeakAurasOptions/SubRegionOptions/Glow.lua +++ b/WeakAurasOptions/SubRegionOptions/Glow.lua @@ -6,6 +6,10 @@ local L = WeakAuras.L; local indentWidth = 0.15 local function createOptions(parentData, data, index, subIndex) + local areaAnchors = {} + for child in OptionsPrivate.Private.TraverseLeafsOrAura(parentData) do + WeakAuras.Mixin(areaAnchors, OptionsPrivate.Private.GetAnchorsForData(child, "area")) + end local hiddenGlowExtra = function() return OptionsPrivate.IsCollapsed("glow", "glow", "glowextra" .. index, true); @@ -27,12 +31,12 @@ local function createOptions(parentData, data, index, subIndex) order = 2, values = OptionsPrivate.Private.glow_types, }, - glow_anchor = { + anchor_area = { type = "select", width = WeakAuras.normalWidth, name = L["Glow Anchor"], order = 3, - values = OptionsPrivate.Private.aurabar_anchor_areas, + values = areaAnchors, hidden = function() return parentData.regionType ~= "aurabar" end }, glowExtraDescription = { diff --git a/WeakAurasOptions/SubRegionOptions/StopMotion.lua b/WeakAurasOptions/SubRegionOptions/StopMotion.lua new file mode 100644 index 0000000..a6d7382 --- /dev/null +++ b/WeakAurasOptions/SubRegionOptions/StopMotion.lua @@ -0,0 +1,350 @@ +if not WeakAuras.IsLibsOK() then return end +---@type string +local AddonName = ... +---@class OptionsPrivate +local OptionsPrivate = select(2, ...) + +local L = WeakAuras.L; + +local texture_types = WeakAuras.StopMotion.texture_types +local texture_data = WeakAuras.StopMotion.texture_data +local animation_types = WeakAuras.StopMotion.animation_types + +local function createOptions(parentData, data, index, subIndex) + + local pointAnchors = {} + local areaAnchors = {} + for child in OptionsPrivate.Private.TraverseLeafsOrAura(parentData) do + WeakAuras.Mixin(pointAnchors, OptionsPrivate.Private.GetAnchorsForData(child, "point")) + WeakAuras.Mixin(areaAnchors, OptionsPrivate.Private.GetAnchorsForData(child, "area")) + end + + local textureNameHasData = OptionsPrivate.Private.StopMotionBase.textureNameHasData + local setTextureFunc = OptionsPrivate.Private.StopMotionBase.setTextureFunc + local options = { + __title = L["Stop Motion %s"]:format(subIndex), + __order = 1, + stopmotionVisible = { + type = "toggle", + width = WeakAuras.doubleWidth, + name = L["Show Stop Motion"], + order = 1, + }, + stopmotionTexture = { + type = "input", + width = WeakAuras.doubleWidth - 0.15, + name = L["Texture"], + order = 2, + }, + chooseTexture = { + type = "execute", + width = 0.15, + name = L["Choose"], + order = 3, + func = function() + local path = { "subRegions", index } + local paths = {} + for child in OptionsPrivate.Private.TraverseLeafsOrAura(parentData) do + paths[child.id] = path + end + OptionsPrivate.OpenTexturePicker(parentData, paths, { + texture = "stopmotionTexture", + color = "stopmotionColor", + blendMode = "stopmotionBlendMode" + }, texture_types, setTextureFunc) + end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\browse", + }, + stopmotionColor = { + type = "color", + width = WeakAuras.normalWidth, + name = L["Color"], + hasAlpha = true, + order = 4 + }, + stopmotionDesaturate = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Desaturate"], + order = 5, + }, + customRows = { + type = "input", + width = WeakAuras.doubleWidth / 3, + name = L["Rows"], + validate = WeakAuras.ValidateNumeric, + get = function() + return data.customRows and tostring(data.customRows) or ""; + end, + set = function(info, v) + data.customRows = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 6, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customColumns = { + type = "input", + width = WeakAuras.doubleWidth / 3, + name = L["Columns"], + validate = WeakAuras.ValidateNumeric, + get = function() + return data.customColumns and tostring(data.customColumns) or ""; + end, + set = function(info, v) + data.customColumns = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 7, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customFrames = { + type = "input", + width = WeakAuras.doubleWidth / 3, + name = L["Frame Count"], + validate = WeakAuras.ValidateNumeric, + get = function() + return data.customFrames and tostring(data.customFrames) or ""; + end, + set = function(info, v) + data.customFrames = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 8, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customFileWidth = { + type = "input", + width = WeakAuras.normalWidth / 2, + name = L["File Width"], + desc = L["Must be a power of 2"], + validate = function(info, val) + if val ~= nil and val ~= "" and (not tonumber(val) or tonumber(val) >= 2^31 or math.frexp(val) ~= 0.5) then + return false; + end + return true + end, + get = function() + return data.customFileWidth and tostring(data.customFileWidth) or ""; + end, + set = function(info, v) + data.customFileWidth = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 9, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customFileHeight = { + type = "input", + width = WeakAuras.normalWidth / 2, + name = L["File Height"], + desc = L["Must be a power of 2"], + validate = function(info, val) + if val ~= nil and val ~= "" and (not tonumber(val) or tonumber(val) >= 2^31 or math.frexp(val) ~= 0.5) then + return false; + end + return true + end, + get = function() + return data.customFileHeight and tostring(data.customFileHeight) or ""; + end, + set = function(info, v) + data.customFileHeight = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 10, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customFrameWidth = { + type = "input", + width = WeakAuras.normalWidth / 2, + name = L["Frame Width"], + validate = WeakAuras.ValidateNumeric, + desc = L["Can set to 0 if Columns * Width equal File Width"], + get = function() + return data.customFrameWidth and tostring(data.customFrameWidth) or ""; + end, + set = function(info, v) + data.customFrameWidth = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 11, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + customFrameHeight = { + type = "input", + width = WeakAuras.normalWidth / 2, + name = L["Frame Height"], + validate = WeakAuras.ValidateNumeric, + desc = L["Can set to 0 if Rows * Height equal File Height"], + get = function() + return data.customFrameHeight and tostring(data.customFrameHeight) or ""; + end, + set = function(info, v) + data.customFrameHeight = v and tonumber(v) or 0 + WeakAuras.Add(data); + WeakAuras.UpdateThumbnail(data); + end, + order = 12, + hidden = function() + return texture_data[data.stopmotionTexture] or textureNameHasData(data.stopmotionTexture) + end + }, + stopmotionBlendMode = { + type = "select", + width = WeakAuras.normalWidth, + name = L["Blend Mode"], + order = 13, + values = OptionsPrivate.Private.blend_types + }, + animationType = { + type = "select", + width = WeakAuras.normalWidth, + name = L["Animation Mode"], + order = 14, + values = animation_types + }, + + progress_source = { + type = "select", + width = WeakAuras.normalWidth, + name = L["Progress Source"], + order = 15, + control = "WeakAurasTwoColumnDropdown", + values = OptionsPrivate.Private.GetProgressSourcesForUi(parentData, true), + get = function(info) + return OptionsPrivate.Private.GetProgressValueConstant(data.progressSources or {-2, ""}) + end, + set = function(info, value) + if value then + data.progressSources = data.progressSources or {} + -- Copy only trigger + property + data.progressSources[1] = value[1] + data.progressSources[2] = value[2] + else + data.progressSources = nil + end + WeakAuras.Add(parentData) + end, + hidden = function() + return not(data.animationType == "progress") + end + }, + + progress_source_space = { + type = "description", + name = "", + order = 16, + width = WeakAuras.normalWidth, + hidden = function() + return not(data.animationType == "progress") + end + }, + + startPercent = { + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + name = L["Animation Start"], + min = 0, + max = 1, + --bigStep = 0.01, + order = 17, + isPercent = true + }, + endPercent = { + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + name = L["Animation End"], + min = 0, + max = 1, + --bigStep = 0.01, + order = 18, + isPercent = true + }, + + inverse = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Inverse"], + order = 19 + }, + + frameRate = { + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + name = L["Frame Rate"], + min = 3, + max = 120, + step = 1, + bigStep = 3, + order = 20, + disabled = function() return data.animationType == "progress" end; + }, + + -- Anchor settings added below + + barModelClip = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Clipped by Foreground"], + order = 27, + hidden = function() + return not (parentData.regionType == "aurabar" + and data.anchor_mode == "area" + and data.anchor_area == "fg") + end + }, + + scale = { + type = "range", + control = "WeakAurasSpinBox", + width = WeakAuras.normalWidth, + name = L["Scale Factor"], + order = 28, + softMin = 0.5, + softMax = 3, + step = 0.1, + hidden = function() + if parentData.regionType == "aurabar" + and data.anchorMode == "area" + and data.anchor_area == "fg" + and data.barModelClip + then + return true + end + return data.anchor_mode ~= "area" + end + }, + } + + OptionsPrivate.commonOptions.PositionOptionsForSubElement(data, options, 21, areaAnchors, pointAnchors) + OptionsPrivate.AddUpDownDeleteDuplicate(options, parentData, index, "substopmotion") + + return options +end + + WeakAuras.RegisterSubRegionOptions("substopmotion", createOptions, L["Shows a Stop Moption"]); diff --git a/WeakAurasOptions/SubRegionOptions/SubRegionCommon.lua b/WeakAurasOptions/SubRegionOptions/SubRegionCommon.lua index 76e9486..6cd7b89 100644 --- a/WeakAurasOptions/SubRegionOptions/SubRegionCommon.lua +++ b/WeakAurasOptions/SubRegionOptions/SubRegionCommon.lua @@ -23,6 +23,37 @@ local function AdjustConditions(data, replacements) end end +local function ReplacePrefix(hay, replacements) + for old, new in pairs(replacements) do + if hay:sub(1, #old) == old then + return new .. hay:sub(#old + 1) + end + end +end + +local function AdjustAnchors(data, replacements) + if not data.subRegions then + return + end + + for _, subRegionData in ipairs(data.subRegions) do + local anchor_area = subRegionData.anchor_area + if anchor_area then + local replaced = ReplacePrefix(anchor_area, replacements) + if replaced then + subRegionData.anchor_area = replaced + end + end + local anchor_point = subRegionData.anchor_point + if anchor_point then + local replaced = ReplacePrefix(anchor_point, replacements) + if replaced then + subRegionData.anchor_point = replaced + end + end + end +end + function OptionsPrivate.DeleteSubRegion(data, index, regionType) if not data.subRegions then return @@ -39,6 +70,7 @@ function OptionsPrivate.DeleteSubRegion(data, index, regionType) end AdjustConditions(data, replacements); + AdjustAnchors(data, replacements) WeakAuras.Add(data) OptionsPrivate.ClearOptions(data.id) @@ -58,6 +90,7 @@ function OptionsPrivate.MoveSubRegionUp(data, index, regionType) } AdjustConditions(data, replacements); + AdjustAnchors(data, replacements) WeakAuras.Add(data) OptionsPrivate.ClearOptions(data.id) @@ -77,6 +110,7 @@ function OptionsPrivate.MoveSubRegionDown(data, index, regionType) } AdjustConditions(data, replacements); + AdjustAnchors(data, replacements) WeakAuras.Add(data) OptionsPrivate.ClearOptions(data.id) @@ -95,7 +129,8 @@ function OptionsPrivate.DuplicateSubRegion(data, index, regionType) for i = index + 1, #data.subRegions do replacements["sub." .. i .. "."] = "sub." .. (i + 1) .. "." end - AdjustConditions(data, replacements); + AdjustConditions(data, replacements) + AdjustAnchors(data, replacements) WeakAuras.Add(data) OptionsPrivate.ClearOptions(data.id) diff --git a/WeakAurasOptions/SubRegionOptions/SubText.lua b/WeakAurasOptions/SubRegionOptions/SubText.lua index 491ecac..17cffd1 100644 --- a/WeakAurasOptions/SubRegionOptions/SubText.lua +++ b/WeakAurasOptions/SubRegionOptions/SubText.lua @@ -302,7 +302,7 @@ local function createOptions(parentData, data, index, subIndex) control = "WeakAurasExpandSmall", name = function() local selfPoint = data.text_selfPoint ~= "AUTO" and self_point_types[data.text_selfPoint] - local anchorPoint = anchors[data.text_anchorPoint or "CENTER"] or anchors["CENTER"] + local anchorPoint = anchors[data.anchor_point or "CENTER"] or anchors["CENTER"] local xOffset = data.text_anchorXOffset or 0 local yOffset = data.text_anchorYOffset or 0 @@ -364,7 +364,7 @@ local function createOptions(parentData, data, index, subIndex) hidden = hiddenFunction } - options.text_anchorPoint = { + options.anchor_point = { type = "select", width = WeakAuras.normalWidth, name = function() diff --git a/WeakAurasOptions/SubRegionOptions/Tick.lua b/WeakAurasOptions/SubRegionOptions/Tick.lua index d2fb900..9f7d1f2 100644 --- a/WeakAurasOptions/SubRegionOptions/Tick.lua +++ b/WeakAurasOptions/SubRegionOptions/Tick.lua @@ -315,4 +315,19 @@ local function createOptions(parentData, data, index, subIndex) return options end -WeakAuras.RegisterSubRegionOptions("subtick", createOptions, L["Places a tick on the bar"]); +local getAnchors = function(data) + local anchors = {} + for i in ipairs(data.tick_placements) do + anchors["tick."..i] = { + display = L["Tick Center %s"]:format(i), + type = "point" + } + anchors["tickarea."..i] = { + display = L["Tick Area %s"]:format(i), + type = "area" + } + end + return anchors +end + +WeakAuras.RegisterSubRegionOptions("subtick", createOptions, L["Places a tick on the bar"], getAnchors) diff --git a/WeakAurasOptions/WeakAurasOptions.toc b/WeakAurasOptions/WeakAurasOptions.toc index ab47efc..83057e9 100644 --- a/WeakAurasOptions/WeakAurasOptions.toc +++ b/WeakAurasOptions/WeakAurasOptions.toc @@ -37,6 +37,7 @@ SubRegionOptions\Border.lua SubRegionOptions\Glow.lua SubRegionOptions\Tick.lua SubRegionOptions\Model.lua +SubRegionOptions\StopMotion.lua Cache.lua