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.
bastion/libs/StdUi/StdUiUtil.lua

318 lines
7.0 KiB

--- @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);