From 22247adb2516ba70cc0949c56a72e3abc5c2ec48 Mon Sep 17 00:00:00 2001 From: Bunny67 Date: Sat, 1 Jan 2022 10:30:45 +0300 Subject: [PATCH] add Smooth Progress --- WeakAuras/Profiling.lua | 3 +- WeakAuras/RegionTypes/AuraBar.lua | 43 ++++++++-- WeakAuras/compat.lua | 92 +++++++++++++++++++++- WeakAurasOptions/RegionOptions/AuraBar.lua | 9 +++ 4 files changed, 140 insertions(+), 7 deletions(-) diff --git a/WeakAuras/Profiling.lua b/WeakAuras/Profiling.lua index c121ce0..c656247 100644 --- a/WeakAuras/Profiling.lua +++ b/WeakAuras/Profiling.lua @@ -473,6 +473,7 @@ function RealTimeProfilingWindow:GetBar(name) else local bar = CreateFrame("FRAME", nil, self.barsFrame) self.bars[name] = bar + WeakAuras.Mixin(bar, SmoothStatusBarMixin) bar.name = name bar.parent = self bar:SetSize(self.width, self.barHeight) @@ -522,7 +523,7 @@ function RealTimeProfilingWindow:GetBar(name) function bar:SetProgress(value) self.value = value - self:SetValue(value) + self:SetSmoothedValue(value) end function bar:SetPosition(pos) diff --git a/WeakAuras/RegionTypes/AuraBar.lua b/WeakAuras/RegionTypes/AuraBar.lua index 0e2d157..94cb545 100644 --- a/WeakAuras/RegionTypes/AuraBar.lua +++ b/WeakAuras/RegionTypes/AuraBar.lua @@ -816,7 +816,12 @@ local funcs = { progress = 1 - progress; end - self.bar:SetValue(progress); + if (self.smoothProgress) then + self.bar.targetValue = progress + self.bar:SetSmoothedValue(progress); + else + self.bar:SetValue(progress); + end end, SetTime = function(self, duration, expirationTime, inverse) local remaining = expirationTime - GetTime(); @@ -829,20 +834,39 @@ local funcs = { then progress = 1 - progress; end - self.bar:SetValue(progress); + if (self.smoothProgress) then + self.bar.targetValue = progress + self.bar:SetSmoothedValue(progress); + else + self.bar:SetValue(progress); + end end, SetInverse = function(self, inverse) if (self.inverseDirection == inverse) then return; end self.inverseDirection = inverse; - self.bar:SetValue(1 - self.bar:GetValue()); + if (self.smoothProgress) then + if (self.bar.targetValue) then + self.bar.targetValue = 1 - self.bar.targetValue + self.bar:SetSmoothedValue(self.bar.targetValue); + end + else + self.bar:SetValue(1 - self.bar:GetValue()); + end + self.bar:SetAdditionalBarsInverse(not self.bar:GetAdditionalBarsInverse()) self.subRegionEvents:Notify("InverseChanged") end, SetOrientation = function(self, orientation) self.orientation = orientation self:UpdateEffectiveOrientation() - self.bar:SetValue(self.bar:GetValue()); + if (self.smoothProgress) then + if self.bar.targetValue then + self.bar:SetSmoothedValue(self.bar.targetValue); + end + else + self.bar:SetValue(self.bar:GetValue()); + end end, SetIconVisible = function(self, iconVisible) @@ -965,6 +989,7 @@ local function create(parent) -- Create statusbar (inherit prototype) local bar = CreateFrame("FRAME", nil, region); + WeakAuras.Mixin(bar, SmoothStatusBarMixin); local fg = bar:CreateTexture(nil, "BORDER"); local bg = bar:CreateTexture(nil, "BACKGROUND"); bg:SetAllPoints(); @@ -1265,8 +1290,16 @@ local function modify(parent, region, data) region:UpdateEffectiveOrientation() end -- region:Scale(1.0, 1.0); + if data.smoothProgress then + region.PreShow = function() + region.bar:ResetSmoothedValue(); + end + else + region.PreShow = nil + end - -- Update internal bar alignment + region.smoothProgress = data.smoothProgress + --- Update internal bar alignment region.bar:Update(); WeakAuras.regionPrototype.modifyFinish(parent, region, data); diff --git a/WeakAuras/compat.lua b/WeakAuras/compat.lua index b5a007f..9b389c2 100644 --- a/WeakAuras/compat.lua +++ b/WeakAuras/compat.lua @@ -54,4 +54,94 @@ RAID_CLASS_COLORS.ROGUE.colorStr = "fffff569" RAID_CLASS_COLORS.DRUID.colorStr = "ffff7d0a" RAID_CLASS_COLORS.SHAMAN.colorStr = "ff0070de" RAID_CLASS_COLORS.WARRIOR.colorStr = "ffc79c6e" -RAID_CLASS_COLORS.DEATHKNIGHT.colorStr = "ffc41f3b" \ No newline at end of file +RAID_CLASS_COLORS.DEATHKNIGHT.colorStr = "ffc41f3b" + +if not SmoothStatusBarMixin then + function Lerp(startValue, endValue, amount) + return (1 - amount) * startValue + amount * endValue; + end + + function Clamp(value, min, max) + if value > max then + return max; + elseif value < min then + return min; + end + return value; + end + + function Saturate(value) + return Clamp(value, 0, 1); + end + + local TARGET_FRAME_PER_SEC = 60; + function DeltaLerp(startValue, endValue, amount, timeSec) + return Lerp(startValue, endValue, Saturate(amount * timeSec * TARGET_FRAME_PER_SEC)); + end + + function FrameDeltaLerp(startValue, endValue, amount, elapsed) + return DeltaLerp(startValue, endValue, amount, elapsed); + end + + local g_updatingBars = {}; + + local function IsCloseEnough(bar, newValue, targetValue) + local min, max = bar:GetMinMaxValues(); + local range = max - min; + if range > 0 then + return math.abs((newValue - targetValue) / range) < .00001; + end + + return true; + end + + local function ProcessSmoothStatusBars(self, elapsed) + for bar, targetValue in pairs(g_updatingBars) do + local effectiveTargetValue = Clamp(targetValue, bar:GetMinMaxValues()); + local newValue = FrameDeltaLerp(bar:GetValue(), effectiveTargetValue, .25, elapsed); + + if IsCloseEnough(bar, newValue, effectiveTargetValue) then + g_updatingBars[bar] = nil; + bar:SetValue(effectiveTargetValue); + else + bar:SetValue(newValue); + end + end + end + + CreateFrame("Frame"):SetScript("OnUpdate", ProcessSmoothStatusBars) + + SmoothStatusBarMixin = {}; + + function SmoothStatusBarMixin:ResetSmoothedValue(value) --If nil, tries to set to the last target value + local targetValue = g_updatingBars[self]; + if targetValue then + g_updatingBars[self] = nil; + self:SetValue(value or targetValue); + elseif value then + self:SetValue(value); + end + end + + function SmoothStatusBarMixin:SetSmoothedValue(value) + g_updatingBars[self] = value; + end + + function SmoothStatusBarMixin:SetMinMaxSmoothedValue(min, max) + self:SetMinMaxValues(min, max); + + local targetValue = g_updatingBars[self]; + if targetValue then + local ratio = 1; + if max ~= 0 and self.lastSmoothedMax and self.lastSmoothedMax ~= 0 then + ratio = max / self.lastSmoothedMax; + end + + g_updatingBars[self] = targetValue * ratio; + end + + self.lastSmoothedMin = min; + self.lastSmoothedMax = max; + end +end + diff --git a/WeakAurasOptions/RegionOptions/AuraBar.lua b/WeakAurasOptions/RegionOptions/AuraBar.lua index 9eb73ff..bf411d4 100644 --- a/WeakAurasOptions/RegionOptions/AuraBar.lua +++ b/WeakAurasOptions/RegionOptions/AuraBar.lua @@ -67,6 +67,13 @@ local function createOptions(id, data) name = L["Inverse"], order = 35 }, + smoothProgress = { + type = "toggle", + width = WeakAuras.normalWidth, + name = L["Smooth Progress"], + desc = L["Animates progress changes"], + order = 37 + }, useTooltip = { type = "toggle", width = WeakAuras.normalWidth, @@ -621,6 +628,7 @@ local templates = { height = 30, barColor = { 0, 1, 0, 1}, inverse = true, + smoothProgress = true, } }, { @@ -631,6 +639,7 @@ local templates = { barColor = { 0, 1, 0, 1}, orientation = "VERTICAL_INVERSE", inverse = true, + smoothProgress = true, } }, }