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