forked from Bastion/Bastion
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.
319 lines
7.0 KiB
319 lines
7.0 KiB
2 years ago
|
--- @type StdUi
|
||
|
local StdUi = LibStub and LibStub('StdUi', true);
|
||
|
if not StdUi then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local module, version = 'Util', 11;
|
||
|
if not StdUi:UpgradeNeeded(module, version) then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local TableGetN = table.getn;
|
||
|
local TableInsert = tinsert;
|
||
|
local TableSort = table.sort;
|
||
|
|
||
|
--- @param frame Frame
|
||
|
function StdUi:MarkAsValid(frame, valid)
|
||
|
if not frame.SetBackdrop then
|
||
|
Mixin(frame, BackdropTemplateMixin)
|
||
|
end
|
||
|
if not valid then
|
||
|
frame:SetBackdropBorderColor(1, 0, 0, 1);
|
||
|
frame.origBackdropBorderColor = { frame:GetBackdropBorderColor() };
|
||
|
else
|
||
|
frame:SetBackdropBorderColor(
|
||
|
self.config.backdrop.border.r,
|
||
|
self.config.backdrop.border.g,
|
||
|
self.config.backdrop.border.b,
|
||
|
self.config.backdrop.border.a
|
||
|
);
|
||
|
frame.origBackdropBorderColor = { frame:GetBackdropBorderColor() };
|
||
|
end
|
||
|
end
|
||
|
|
||
|
StdUi.Util = {
|
||
|
--- @param self EditBox
|
||
|
editBoxValidator = function(self)
|
||
|
self.value = self:GetText();
|
||
|
|
||
|
self.stdUi:MarkAsValid(self, true);
|
||
|
return true;
|
||
|
end,
|
||
|
|
||
|
--- @param self EditBox
|
||
|
moneyBoxValidator = function(self)
|
||
|
local text = self:GetText();
|
||
|
text = text:trim();
|
||
|
local total, gold, silver, copper, isValid = StdUi.Util.parseMoney(text);
|
||
|
|
||
|
if not isValid or total == 0 then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
self:SetText(StdUi.Util.formatMoney(total));
|
||
|
self.value = total;
|
||
|
|
||
|
self.stdUi:MarkAsValid(self, true);
|
||
|
return true;
|
||
|
end,
|
||
|
|
||
|
--- @param self EditBox
|
||
|
moneyBoxValidatorExC = function(self)
|
||
|
local text = self:GetText();
|
||
|
text = text:trim();
|
||
|
local total, gold, silver, copper, isValid = StdUi.Util.parseMoney(text);
|
||
|
|
||
|
if not isValid or total == 0 or (copper and tonumber(copper) > 0) then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
self:SetText(StdUi.Util.formatMoney(total, true));
|
||
|
self.value = total;
|
||
|
|
||
|
self.stdUi:MarkAsValid(self, true);
|
||
|
return true;
|
||
|
end,
|
||
|
|
||
|
--- @param self EditBox
|
||
|
numericBoxValidator = function(self)
|
||
|
local text = self:GetText();
|
||
|
text = text:trim();
|
||
|
|
||
|
local value = tonumber(text);
|
||
|
|
||
|
if value == nil then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
if self.maxValue and self.maxValue < value then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
if self.minValue and self.minValue > value then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
self.value = value;
|
||
|
|
||
|
self.stdUi:MarkAsValid(self, true);
|
||
|
|
||
|
return true;
|
||
|
end,
|
||
|
|
||
|
--- @param self EditBox
|
||
|
spellValidator = function(self)
|
||
|
local text = self:GetText();
|
||
|
text = text:trim();
|
||
|
local name, _, icon, _, _, _, spellId = GetSpellInfo(text);
|
||
|
|
||
|
if not name then
|
||
|
self.stdUi:MarkAsValid(self, false);
|
||
|
return false;
|
||
|
end
|
||
|
|
||
|
self:SetText(name);
|
||
|
self.value = spellId;
|
||
|
self.icon:SetTexture(icon);
|
||
|
|
||
|
self.stdUi:MarkAsValid(self, true);
|
||
|
return true;
|
||
|
end,
|
||
|
|
||
|
parseMoney = function(text)
|
||
|
text = StdUi.Util.stripColors(text);
|
||
|
local total = 0;
|
||
|
local cFound, _, copper = string.find(text, '(%d+)c$');
|
||
|
if cFound then
|
||
|
text = string.gsub(text, '(%d+)c$', '');
|
||
|
text = text:trim();
|
||
|
total = tonumber(copper);
|
||
|
end
|
||
|
|
||
|
local sFound, _, silver = string.find(text, '(%d+)s$');
|
||
|
if sFound then
|
||
|
text = string.gsub(text, '(%d+)s$', '');
|
||
|
text = text:trim();
|
||
|
total = total + tonumber(silver) * 100;
|
||
|
end
|
||
|
|
||
|
local gFound, _, gold = string.find(text, '(%d+)g$');
|
||
|
if gFound then
|
||
|
text = string.gsub(text, '(%d+)g$', '');
|
||
|
text = text:trim();
|
||
|
total = total + tonumber(gold) * 100 * 100;
|
||
|
end
|
||
|
|
||
|
local left = tonumber(text:len());
|
||
|
local isValid = (text:len() == 0 and total > 0);
|
||
|
|
||
|
return total, gold, silver, copper, isValid;
|
||
|
end,
|
||
|
|
||
|
formatMoney = function(money, excludeCopper)
|
||
|
if type(money) ~= 'number' then
|
||
|
return money;
|
||
|
end
|
||
|
|
||
|
money = tonumber(money);
|
||
|
local goldColor = '|cfffff209';
|
||
|
local silverColor = '|cff7b7b7a';
|
||
|
local copperColor = '|cffac7248';
|
||
|
|
||
|
local gold = floor(money / COPPER_PER_GOLD);
|
||
|
local silver = floor((money - (gold * COPPER_PER_GOLD)) / COPPER_PER_SILVER);
|
||
|
local copper = floor(money % COPPER_PER_SILVER);
|
||
|
|
||
|
local output = '';
|
||
|
|
||
|
if gold > 0 then
|
||
|
output = format('%s%i%s ', goldColor, gold, '|rg');
|
||
|
end
|
||
|
|
||
|
if gold > 0 or silver > 0 then
|
||
|
output = format('%s%s%02i%s ', output, silverColor, silver, '|rs');
|
||
|
end
|
||
|
|
||
|
if not excludeCopper then
|
||
|
output = format('%s%s%02i%s ', output, copperColor, copper, '|rc');
|
||
|
end
|
||
|
|
||
|
return output:trim();
|
||
|
end,
|
||
|
|
||
|
formatTime = function(totalTime)
|
||
|
local days = floor(totalTime/86400)
|
||
|
local hours = floor(mod(totalTime, 86400)/3600)
|
||
|
local minutes = floor(mod(totalTime,3600)/60)
|
||
|
local seconds = floor(mod(totalTime,60))
|
||
|
|
||
|
if (days > 0) then
|
||
|
return format("%dd %02dh %02dm %02ds",days,hours,minutes,seconds)
|
||
|
elseif (hours > 0) then
|
||
|
return format("%02dh %02dm %02ds",hours,minutes,seconds)
|
||
|
elseif (minutes > 0) then
|
||
|
return format("%02dm %02ds",minutes,seconds)
|
||
|
elseif (seconds > 0) then
|
||
|
return format("%02ds", seconds)
|
||
|
end
|
||
|
end,
|
||
|
|
||
|
stripColors = function(text)
|
||
|
text = string.gsub(text, '|c%x%x%x%x%x%x%x%x', '');
|
||
|
text = string.gsub(text, '|r', '');
|
||
|
return text;
|
||
|
end,
|
||
|
|
||
|
WrapTextInColor = function(text, r, g, b, a)
|
||
|
local hex = string.format(
|
||
|
'%02x%02x%02x%02x',
|
||
|
Clamp(a * 255, 0, 255),
|
||
|
Clamp(r * 255, 0, 255),
|
||
|
Clamp(g * 255, 0, 255),
|
||
|
Clamp(b * 255, 0, 255)
|
||
|
);
|
||
|
|
||
|
return WrapTextInColorCode(text, hex);
|
||
|
end,
|
||
|
|
||
|
tableCount = function(tab)
|
||
|
local n = #tab;
|
||
|
|
||
|
if n == 0 then
|
||
|
for _ in pairs(tab) do
|
||
|
n = n + 1;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return n;
|
||
|
end,
|
||
|
|
||
|
tableMerge = function(default, new)
|
||
|
local result = {};
|
||
|
for k, v in pairs(default) do
|
||
|
if type(v) == 'table' then
|
||
|
if new[k] then
|
||
|
result[k] = StdUi.Util.tableMerge(v, new[k]);
|
||
|
else
|
||
|
result[k] = v;
|
||
|
end
|
||
|
else
|
||
|
result[k] = new[k] or default[k];
|
||
|
end
|
||
|
end
|
||
|
|
||
|
for k, v in pairs(new) do
|
||
|
if not result[k] then
|
||
|
result[k] = v;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return result;
|
||
|
end,
|
||
|
|
||
|
stringSplit = function(separator, input, limit)
|
||
|
return { strsplit(separator, input, limit) };
|
||
|
end,
|
||
|
|
||
|
--- Ordered pairs
|
||
|
|
||
|
__genOrderedIndex = function(t)
|
||
|
local orderedIndex = {};
|
||
|
|
||
|
for key in pairs(t) do
|
||
|
TableInsert(orderedIndex, key)
|
||
|
end
|
||
|
|
||
|
TableSort(orderedIndex, function(a, b)
|
||
|
if not t[a].order or not t[b].order then
|
||
|
return a < b;
|
||
|
end
|
||
|
|
||
|
return t[a].order < t[b].order;
|
||
|
end);
|
||
|
|
||
|
return orderedIndex;
|
||
|
end,
|
||
|
|
||
|
orderedNext = function(t, state)
|
||
|
local key;
|
||
|
|
||
|
if state == nil then
|
||
|
-- the first time, generate the index
|
||
|
t.__orderedIndex = StdUi.Util.__genOrderedIndex(t);
|
||
|
key = t.__orderedIndex[1];
|
||
|
else
|
||
|
-- fetch the next value
|
||
|
for i = 1, TableGetN(t.__orderedIndex) do
|
||
|
if t.__orderedIndex[i] == state then
|
||
|
key = t.__orderedIndex[i + 1];
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if key then
|
||
|
return key, t[key];
|
||
|
end
|
||
|
|
||
|
-- no more value to return, cleanup
|
||
|
t.__orderedIndex = nil;
|
||
|
return
|
||
|
end,
|
||
|
|
||
|
orderedPairs = function(t)
|
||
|
return StdUi.Util.orderedNext, t, nil;
|
||
|
end,
|
||
|
|
||
|
roundPrecision = function(value, precision)
|
||
|
local multiplier = 10 ^ (precision or 0);
|
||
|
return math.floor(value * multiplier + 0.5) / multiplier;
|
||
|
end
|
||
|
};
|
||
|
|
||
|
StdUi:RegisterModule(module, version);
|