You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
8.6 KiB

5 years ago
--========================================================--
-- Scorpio Cooldown Template --
-- --
-- Author : kurapica125@outlook.com --
-- Create Date : 2020/12/07 --
--========================================================--
--========================================================--
Scorpio "Scorpio.UI.CooldownTemplate" "1.0.0"
--========================================================--
----------------------------------------------
-- Data Type
----------------------------------------------
__Sealed__() struct "CooldownStatus" {
{ name = "start", type = Number },
{ name = "duration",type = Number },
}
----------------------------------------------
-- Template
----------------------------------------------
__Sealed__() __ChildProperty__(Frame, "CooldownLabel")
class "CooldownLabel" (function(_ENV)
inherit "FontString"
event "OnCooldownFinished"
--- Whether use auto color on the label based on the duration
property "AutoColor" { type = Boolean, default = true }
--- The alert second that used to notify the user
property "AlertSecond" { type = Number, default = 10 }
--- The color for duration over 1 day
property "DayColor" { type = ColorType, default = Color(0.4, 0.4, 0.4) }
--- The color for duration over 1 hour
property "HourColor" { type = ColorType, default = Color(0.6, 0.4, 0) }
--- The color for duration over 1 min
property "MinuteColor" { type = ColorType, default = Color(0.8, 0.6, 0) }
--- The color for duration over the alert second
property "SecondColor" { type = ColorType, default = Color(1, 0.82, 0) }
--- The shine color for duration less than the alert second
property "AlertInColor" { type = ColorType, default = Color(1, 0.82, 0.12) }
--- The shine color for duration less than the alert second
property "AlertOutColor" { type = ColorType, default = Color(1, 0.12, 0.12) }
--- The day suffix text
property "DaySuffix" { type = String, default = "d" }
--- The hour suffix text
property "HourSuffix" { type = String, default = "h" }
--- The miniute suffix text
property "MinuteSuffix" { type = String, default = "m" }
--- Set the cooldown status
__Async__()
function SetCooldown(self, start, duration)
self.TaskID = (self.TaskID or 0) + 1
local total = start and duration and (start + duration) or 0
local now = GetTime()
local task = self.TaskID
local processed = false
while total > now do
processed = true
local remain = total - now
if remain < self.AlertSecond then
if self.AutoColor then
self:SetText((remain - floor(remain) > 0.5 and self.AlertInColor or self.AlertOutColor) .. strformat("%.1f", remain))
else
self:SetText(strformat("%.1f", remain))
end
Delay(0.1)
elseif remain <= 60 then
if self.AutoColor then
self:SetText(self.SecondColor .. ceil(remain))
else
self:SetText(ceil(remain))
end
Delay(1)
elseif remain < 3600 then
if self.AutoColor then
self:SetText(self.MinuteColor .. ceil(remain / 60) .. self.MinuteSuffix)
else
self:SetText(ceil(remain / 60) .. self.MinuteSuffix)
end
remain = remain % 60
Delay(remain > 0 and remain or 60)
elseif (remain < 86400) then
if self.AutoColor then
self:SetText(self.HourColor .. ceil(remain / 3600) .. self.HourSuffix)
else
self:SetText(ceil(remain / 3600) .. self.HourSuffix)
end
remain = remain % 3600
Delay(remain > 0 and remain or 3600)
else
if self.AutoColor then
self:SetText(self.HourColor .. ceil(remain / 86400) .. self.DaySuffix)
else
self:SetText(ceil(remain / 86400) .. self.DaySuffix)
end
remain = remain % 86400
Delay(remain > 0 and remain or 86400)
end
if task ~= self.TaskID then return end
now = GetTime()
end
self:SetText("")
if processed then
OnCooldownFinished(self)
end
end
end)
__Sealed__() __ChildProperty__(Frame, "CooldownStatusBar")
class "CooldownStatusBar" (function(_ENV)
inherit "StatusBar"
event "OnCooldownFinished"
local function processCooldown(self, start, duration)
self:Show()
local task = self.TaskID
local now = GetTime()
local fin = start and duration and (start + duration) or 0
local reversed = self.Reverse
local processed = false
if duration > 0 and self.ShowSafeZone then
local safeZone = self:GetChild("SafeZone")
local _,_,_,latency = GetNetStats()
local pct = (latency or 0) / 1000 / duration
if pct > 1 then pct = 1 end
safeZone:ClearAllPoints()
safeZone:SetPoint("BOTTOM")
safeZone:SetPoint(reversed and "TOPLEFT" or "TOPRIGHT")
safeZone:SetWidth(pct * self:GetWidth())
end
if fin > now then
processed = true
self:SetMinMaxValues(0, duration)
while fin > now do
local remain = now - start
self:SetValue(reversed and (fin - now) or remain)
if remain > 10 then
Delay(max(0.1, remain / 100))
else
Next()
end
if task ~= self.TaskID then return end
now = GetTime()
end
end
-- Reset
if self.AutoHide then
self:Hide()
else
self:SetMinMaxValues(0, 100)
self:SetValue(self.AutoFullValue and 100 or 0)
end
if processed then
OnCooldownFinished(self)
end
end
--- Whether the status bar is reversed
property "Reverse" { type = Boolean }
--- Whether show the safe zone
property "ShowSafeZone" { type = Boolean, handler = function(self, val) self:GetChild("SafeZone"):SetShown(val or false) end }
--- Whether auto hide the status bar when cooldown finished
property "AutoHide" { type = Boolean, default = true }
--- Whether set to full value if not in cooldown
property "AutoFullValue" { type = Boolean, default = false }
function SetCooldown(self, start, duration)
self.TaskID = (self.TaskID or 0) + 1
if not self:IsShown() and duration <= 0 then return end
-- waiting the reverse settings to be applied at the same time
Next(processCooldown, self, start, duration)
end
__Template__{
SafeZone = Texture,
}
function __ctor(self)
self:GetChild("SafeZone"):SetShown(false)
end
end)
----------------------------------------------
-- Property
----------------------------------------------
--- The start and duration settings
UI.Property {
name = "Cooldown",
type = CooldownStatus,
require = { Cooldown, CooldownLabel, CooldownStatusBar },
set = function(self, val) self:SetCooldown(val.start or GetTime(), val.duration or 0) end,
}
----------------------------------------------
-- Default Style
----------------------------------------------
Style.UpdateSkin("Default", {
[Cooldown] = {
hideCountdownNumbers = true,
},
[CooldownLabel] = {
drawLayer = "ARTWORK",
fontObject = CombatTextFont,
textColor = Color.WHITE,
location = { Anchor("CENTER") },
},
[CooldownStatusBar] = {
SafeZone = {
drawLayer = "ARTWORK",
color = Color.WHITE,
}
},
})