mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-03 17:36:56 +00:00
Mirror timers: bars fill from duration objects, drop the OnUpdate
A breath, fatigue or feign death bar fills from a duration object that spans the bar at the timer's rate, and a text binding writes the m:ss countdown. MirrorTimer_Show and MIRROR_TIMER_PAUSE resync it from GetMirrorTimerProgress; a paused bar holds its value.
This commit is contained in:
@@ -3,20 +3,53 @@ pfUI:RegisterModule("mirrortimers", function ()
|
||||
local fontsize = tonumber(C.global.font_size)
|
||||
local height = fontsize * 1.3
|
||||
|
||||
-- The value of a mirror timer moves by `scale` per second: breath drains at
|
||||
-- -1, and refills faster than that. A running bar fills from a duration
|
||||
-- object that spans the whole bar at that rate, and its text binding shows
|
||||
-- the value as m:ss. A paused bar holds its value.
|
||||
local function Sync(frame)
|
||||
local value = GetMirrorTimerProgress(frame.timer) / 1000
|
||||
local max, scale = frame.maxvalue, frame.scale
|
||||
local label = frame.label:GetText() or ""
|
||||
|
||||
if frame.paused or scale == 0 then
|
||||
frame.statusbar:SetMinMaxValues(0, max)
|
||||
frame.statusbar:SetValue(value)
|
||||
frame.binding:Disable()
|
||||
frame.text:SetFormattedText("%s (%d:%02d)", label, value / 60, value % 60)
|
||||
return
|
||||
end
|
||||
|
||||
-- the shown value is the seconds of the duration times the rate
|
||||
local rate = math.abs(scale)
|
||||
local property
|
||||
if scale < 0 then
|
||||
frame.duration:SetTimeFromEnd(GetTime() + value / rate, max / rate)
|
||||
frame.statusbar:SetTimerDuration(frame.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
property = Enum.DurationTextBindingProperty.RemainingDuration
|
||||
else
|
||||
frame.duration:SetTimeFromEnd(GetTime() + (max - value) / rate, max / rate)
|
||||
frame.statusbar:SetTimerDuration(frame.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
property = Enum.DurationTextBindingProperty.ElapsedDuration
|
||||
end
|
||||
|
||||
local Down = Enum.NumericRuleFormatRounding.Down
|
||||
frame.clock:SetBreakpoints({
|
||||
{ threshold = 0, format = "%d:%02d", components = {
|
||||
{ div = 60 / rate, step = 1, rounding = Down },
|
||||
{ div = 1 / rate, mod = 60, step = 1, rounding = Down },
|
||||
} },
|
||||
})
|
||||
frame.binding:SetTextFormat(label .. " ({})", { { property = property, formatter = frame.clock } })
|
||||
frame.binding:Enable()
|
||||
end
|
||||
|
||||
for i = 1, MIRRORTIMER_NUMTIMERS do
|
||||
local frame = _G["MirrorTimer"..i]
|
||||
frame:GetRegions():Hide()
|
||||
frame:SetWidth(200)
|
||||
frame:SetHeight(height)
|
||||
frame:SetScript("OnUpdate", function()
|
||||
if this.paused or not this.timer then return end
|
||||
MirrorTimerFrame_OnUpdate(this, arg1)
|
||||
|
||||
local text = this.label:GetText()
|
||||
if text and this.value then
|
||||
this.text:SetText(format("%s (%d:%02d)", text, this.value/60, this.value - math.floor(this.value/60)*60))
|
||||
end
|
||||
end)
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("TOP", UIParent, "TOP", 0, -120-(i-1)*(height + 10))
|
||||
@@ -38,5 +71,34 @@ pfUI:RegisterModule("mirrortimers", function ()
|
||||
frame.text = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.text:SetFont(font, fontsize, "OUTLINE")
|
||||
frame.text:SetPoint("CENTER", frame.statusbar, "CENTER", 0, 0)
|
||||
|
||||
frame.duration = C_DurationUtil.CreateDuration()
|
||||
frame.clock = C_StringUtil.CreateNumericRuleFormatter()
|
||||
frame.binding = C_DurationUtil.CreateDurationTextBinding()
|
||||
frame.binding:SetFontString(frame.text)
|
||||
frame.binding:SetDuration(frame.duration)
|
||||
|
||||
-- the stock handler has already set the pause state
|
||||
frame:HookScript("OnEvent", function()
|
||||
if event == "MIRROR_TIMER_PAUSE" and this:IsShown() and arg1 == this.timer then
|
||||
Sync(this)
|
||||
end
|
||||
end)
|
||||
|
||||
frame:HookScript("OnHide", function()
|
||||
this.binding:Disable()
|
||||
end)
|
||||
end
|
||||
|
||||
-- the stock function picks the bar and sets its timer, scale and pause state
|
||||
hooksecurefunc("MirrorTimer_Show", function(timer, _, maxvalue)
|
||||
for i = 1, MIRRORTIMER_NUMTIMERS do
|
||||
local frame = _G["MirrorTimer"..i]
|
||||
if frame:IsShown() and frame.timer == timer then
|
||||
frame.maxvalue = maxvalue / 1000
|
||||
Sync(frame)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user