if not WeakAuras.IsLibsOK() then return end local AddonName = ... local Private = select(2, ...) local L = WeakAuras.L; local default = { progressSource = {-1, "" }, adjustedMax = "", adjustedMin = "", foregroundTexture = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\stopmotion", backgroundTexture = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\stopmotion", desaturateBackground = false, desaturateForeground = false, sameTexture = true, width = 128, height = 128, foregroundColor = {1, 1, 1, 1}, backgroundColor = {0.5, 0.5, 0.5, 0.5}, blendMode = "BLEND", mirror = false, selfPoint = "CENTER", anchorPoint = "CENTER", anchorFrameType = "SCREEN", xOffset = 0, yOffset = 0, frameStrata = 1, startPercent = 0, endPercent = 1, backgroundPercent = 1, frameRate = 15, animationType = "loop", inverse = false, customForegroundFrames = 0, customForegroundRows = 16, customForegroundColumns = 16, customBackgroundFrames = 0, customForegroundFileWidth = 0, customForegroundFileHeight = 0, customForegroundFrameWidth = 0, customForegroundFrameHeight = 0, customBackgroundRows = 16, customBackgroundColumns = 16, hideBackground = true }; 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, }, height = { display = L["Height"], setter = "SetRegionHeight", type = "number", min = 1, softMax = screenHeight, bigStep = 1 }, } Private.regionPrototype.AddProperties(properties, default); local function GetProperties(data) local result = CopyTable(properties) result.progressSource.values = Private.GetProgressSourcesForUi(data) return result end local function create(parent) local frame = CreateFrame("Frame", nil, UIParent) frame:SetMovable(true) frame:SetResizable(true) frame:SetMinResize(1, 1) frame.background = Private.StopMotionBase.create(frame, "BACKGROUND") frame.foreground = Private.StopMotionBase.create(frame, "ARTWORK") frame.regionType = "stopmotion" Private.regionPrototype.create(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.foreground:SetProgress(progress) Private.StopProfileAura(self.id) Private.StopProfileSystem("stopmotion") end, timed = function(self) if (not self.foreground.startTime) then return end Private.StartProfileSystem("stopmotion") Private.StartProfileAura(self.id) self.foreground:TimedUpdate() Private.StopProfileAura(self.id) Private.StopProfileSystem("stopmotion") end, } local function modify(parent, region, data) Private.regionPrototype.modify(parent, region, data) 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, }) 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 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 region.background:SetVisible(not data.hideBackground) region.background:SetDesaturated(data.desaturateBackground) region.foreground:SetDesaturated(data.desaturateForeground) region:SetWidth(data.width); region:SetHeight(data.height); region.width = data.width; region.height = data.height; region.scalex = 1; region.scaley = 1; function region:Scale(scalex, 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) region.color_r = r; region.color_g = g; region.color_b = b; region.color_a = a; if (r or g or b) then a = a or 1; end region.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) region.color_anim_r = r; region.color_anim_g = g; region.color_anim_b = b; region.color_anim_a = a; if (r or g or b) then a = a or 1; end region.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.foreground:SetStartTime(GetTime()) if region.FrameTick then region:FrameTick() end end 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 elseif data.animationType == "progress" then function region:Update() region:UpdateProgress() end function region:UpdateValue() local progress = 0; if (self.total ~= 0) then progress = self.value / self.total end self.foreground:SetProgress(progress) if self.FrameTick then self.FrameTick = nil self.subRegionEvents:RemoveSubscriber("FrameTick", self) end end function region:UpdateTime() 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) end self:FrameTick() end end end function region:SetRegionWidth(width) self.width = width self:Scale(self.scalex, self.scaley) end function region:SetRegionHeight(height) 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) Private.EnforceSubregionExists(data, "subbackground") end Private.RegisterRegionType("stopmotion", create, modify, default, GetProperties, validate);