From 8f93bae7a9a12276411210491776427d8a5c41d3 Mon Sep 17 00:00:00 2001 From: JeffyLikesApples Date: Fri, 23 Feb 2024 02:59:58 -0600 Subject: [PATCH] Updates --- DiesalComm-1.0/DiesalComm-1.0.lua | 340 ++++++++++++------------- DiesalGUI-2.0/Objects/Branch.lua | 1 + DiesalGUI-2.0/Objects/ComboBoxItem.lua | 2 +- DiesalGUI-2.0/Objects/ObjectBase.lua | 4 +- DiesalMenu-2.0/Objects/MenuItem.lua | 3 + DiesalStyle-2.0/DiesalStyle-2.0.lua | 172 +++++-------- 6 files changed, 242 insertions(+), 280 deletions(-) diff --git a/DiesalComm-1.0/DiesalComm-1.0.lua b/DiesalComm-1.0/DiesalComm-1.0.lua index 8a006c3..a49e80f 100644 --- a/DiesalComm-1.0/DiesalComm-1.0.lua +++ b/DiesalComm-1.0/DiesalComm-1.0.lua @@ -1,8 +1,9 @@ +---@diagnostic disable: inject-field, undefined-field, undefined-global --- allows you to send messages of unlimited length over the addon comm channels. -- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\ -- **ChatThrottleLib** is of course being used to avoid being disconnected by the server. --- **DiesalComm** can be embeded into your addon, either explicitly by calling DiesalComm:Embed(MyAddon) or by +-- **DiesalComm** can be embeded into your addon, either explicitly by calling DiesalComm:Embed(MyAddon) or by -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object -- and can be accessed directly, without having to explicitly call AceComm itself.\\ -- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you @@ -15,7 +16,9 @@ -- ~~| Initialize library |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local MAJOR, MINOR = "DiesalComm-1.0", 1 local DiesalComm, oldminor = LibStub:NewLibrary(MAJOR, MINOR) -if not DiesalComm then return end +if not DiesalComm then + return +end local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0") local CTL = assert(ChatThrottleLib, "DiesalComm-1.0 requires ChatThrottleLib") @@ -28,45 +31,42 @@ local error, assert = error, assert -- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local Ambiguate = Ambiguate -- ~~| DiesalComm Values |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DiesalComm.embeds = DiesalComm.embeds or {} -DiesalComm.msg_spool = DiesalComm.msg_spool or {} +DiesalComm.embeds = DiesalComm.embeds or {} +DiesalComm.msg_spool = DiesalComm.msg_spool or {} -local COMM_MODES = {'single','first','next','last'} +local COMM_MODES = { "single", "first", "next", "last" } local HEADER_SIZE = 14 -local HEADER_FORMAT = '%[%x%x:%x%x%x%x:%x%x%x%x%]' +local HEADER_FORMAT = "%[%x%x:%x%x%x%x:%x%x%x%x%]" local MAX_CHUNK_SIZE = 240 - --- Register for Addon Traffic on a specified prefix -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters -- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived" function DiesalComm:RegisterComm(prefix, method) - if method == nil then method = "OnCommReceived" end - if #prefix > 15 then error("AceComm:RegisterComm(prefix,method): prefix length is limited to 15 characters") end - RegisterAddonMessagePrefix(prefix) - - return DiesalComm.RegisterCallback(self, prefix, method) + if method == nil then + method = "OnCommReceived" + end + if #prefix > 15 then + error("AceComm:RegisterComm(prefix,method): prefix length is limited to 15 characters") + end + RegisterAddonMessagePrefix(prefix) + + return DiesalComm.RegisterCallback(self, prefix, method) end - - -local function formatValue(num,len) - num = format('%X',num) - for i = 1, len - #num do - num = "0"..num - end - return num +local function formatValue(num, len) + num = format("%X", num) + for i = 1, len - #num do + num = "0" .. num + end + return num end - -local function encodeHeader(mode, chunk ,totalChunks ) - return '['..formatValue(mode,2)..':'..formatValue(chunk,4)..':'..formatValue(totalChunks,4)..']' -end -local function decodeHeader() - - +local function encodeHeader(mode, chunk, totalChunks) + return "[" .. formatValue(mode, 2) .. ":" .. formatValue(chunk, 4) .. ":" .. formatValue(totalChunks, 4) .. "]" end +local function decodeHeader() end --- Send a message over the Addon Channel -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent) @@ -77,164 +77,161 @@ end -- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified. -- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL". function AceComm:SendCommMessage(prefix, text, channel, target, callbackFn, callbackArg, prio) - prio = prio or "NORMAL" - if type(prefix)~="string" and type(text)~="string" and type(channel)~="string" and (target==nil or type(target)~="string") and (prio~="BULK" or prio~="NORMAL" or prio~="ALERT") then - error('Usage: SendCommMessage(addon, "prefix", "text", "channel"[, "target"[, callbackFn, callbackarg[, "prio"]]])', 2) - end - - local textlen = #text - local ctlCallback = callbackFn and function(sent) return callbackFn(callbackArg, sent, textlen) end or nil - - - - if textlen <= MAX_CHUNK_SIZE then -- fits all in one message - text = '[0:0000:0000]'..text - CTL:SendAddonMessage(prio, prefix, text, channel, target, nil, ctlCallback, textlen) - else - -- first part - local chunk = strsub(text, 1, maxtextlen) - CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen) - - -- continuation - local pos = 1+maxtextlen - - while pos+maxtextlen <= textlen do - chunk = strsub(text, pos, pos+maxtextlen-1) - CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1) - pos = pos + maxtextlen - end - - -- final part - chunk = strsub(text, pos) - CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen) - end + prio = prio or "NORMAL" + if + type(prefix) ~= "string" + and type(text) ~= "string" + and type(channel) ~= "string" + and (target == nil or type(target) ~= "string") + and (prio ~= "BULK" or prio ~= "NORMAL" or prio ~= "ALERT") + then + error('Usage: SendCommMessage(addon, "prefix", "text", "channel"[, "target"[, callbackFn, callbackarg[, "prio"]]])', 2) + end + + local textlen = #text + local ctlCallback = callbackFn and function(sent) + return callbackFn(callbackArg, sent, textlen) + end or nil + + if textlen <= MAX_CHUNK_SIZE then -- fits all in one message + text = "[0:0000:0000]" .. text + CTL:SendAddonMessage(prio, prefix, text, channel, target, nil, ctlCallback, textlen) + else + -- first part + local chunk = strsub(text, 1, maxtextlen) + CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST .. chunk, distribution, target, queueName, ctlCallback, maxtextlen) + + -- continuation + local pos = 1 + maxtextlen + + while pos + maxtextlen <= textlen do + chunk = strsub(text, pos, pos + maxtextlen - 1) + CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT .. chunk, distribution, target, queueName, ctlCallback, pos + maxtextlen - 1) + pos = pos + maxtextlen + end + + -- final part + chunk = strsub(text, pos) + CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST .. chunk, distribution, target, queueName, ctlCallback, textlen) + end end - ---------------------------------------- -- Message receiving ---------------------------------------- do - local compost = setmetatable({}, {__mode = "k"}) - local function new() - local t = next(compost) - if t then - compost[t]=nil - for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten - t[i]=nil - end - return t - end - - return {} - end - - local function lostdatawarning(prefix,sender,where) - DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")") - end - - function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender) - local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender - local spool = AceComm.multipart_spool - - --[[ - if spool[key] then + local compost = setmetatable({}, { __mode = "k" }) + local function new() + local t = next(compost) + if t then + compost[t] = nil + for i = #t, 3, -1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten + t[i] = nil + end + return t + end + + return {} + end + + local function lostdatawarning(prefix, sender, where) + DEFAULT_CHAT_FRAME:AddMessage(MAJOR .. ": Warning: lost network data regarding '" .. tostring(prefix) .. "' from '" .. tostring(sender) .. "' (in " .. where .. ")") + end + + function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender) + local key = prefix .. "\t" .. distribution .. "\t" .. sender -- a unique stream is defined by the prefix + distribution + sender + local spool = AceComm.multipart_spool + + --[[ + if spool[key] then lostdatawarning(prefix,sender,"First") -- continue and overwrite end --]] - - spool[key] = message -- plain string for now - end - - function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender) - local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender - local spool = AceComm.multipart_spool - local olddata = spool[key] - - if not olddata then - --lostdatawarning(prefix,sender,"Next") - return - end - if type(olddata)~="table" then - -- ... but what we have is not a table. So make it one. (Pull a composted one if available) - local t = new() - t[1] = olddata -- add old data as first string - t[2] = message -- and new message as second string - spool[key] = t -- and put the table in the spool instead of the old string - else - tinsert(olddata, message) - end - end - - function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender) - local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender - local spool = AceComm.multipart_spool - local olddata = spool[key] - - if not olddata then - --lostdatawarning(prefix,sender,"End") - return - end - - spool[key] = nil - - if type(olddata) == "table" then - -- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat - tinsert(olddata, message) - AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender) - compost[olddata] = true - else - -- if we've only received a "first", the spooled data will still only be a string - AceComm.callbacks:Fire(prefix, olddata..message, distribution, sender) - end - end + spool[key] = message -- plain string for now + end + + function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender) + local key = prefix .. "\t" .. distribution .. "\t" .. sender -- a unique stream is defined by the prefix + distribution + sender + local spool = AceComm.multipart_spool + local olddata = spool[key] + + if not olddata then + --lostdatawarning(prefix,sender,"Next") + return + end + + if type(olddata) ~= "table" then + -- ... but what we have is not a table. So make it one. (Pull a composted one if available) + local t = new() + t[1] = olddata -- add old data as first string + t[2] = message -- and new message as second string + spool[key] = t -- and put the table in the spool instead of the old string + else + tinsert(olddata, message) + end + end + + function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender) + local key = prefix .. "\t" .. distribution .. "\t" .. sender -- a unique stream is defined by the prefix + distribution + sender + local spool = AceComm.multipart_spool + local olddata = spool[key] + + if not olddata then + --lostdatawarning(prefix,sender,"End") + return + end + + spool[key] = nil + + if type(olddata) == "table" then + -- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat + tinsert(olddata, message) + AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender) + compost[olddata] = true + else + -- if we've only received a "first", the spooled data will still only be a string + AceComm.callbacks:Fire(prefix, olddata .. message, distribution, sender) + end + end end - - - - - ---------------------------------------- -- Embed CallbackHandler ---------------------------------------- if not AceComm.callbacks then - AceComm.callbacks = CallbackHandler:New(AceComm, - "_RegisterComm", - "UnregisterComm", - "UnregisterAllComm") + AceComm.callbacks = CallbackHandler:New(AceComm, "_RegisterComm", "UnregisterComm", "UnregisterAllComm") end AceComm.callbacks.OnUsed = nil AceComm.callbacks.OnUnused = nil local function OnEvent(self, event, prefix, message, distribution, sender) - if event == "CHAT_MSG_ADDON" then - sender = Ambiguate(sender, "none") - local control, rest = match(message, "^([\001-\009])(.*)") - if control then - if control==MSG_MULTI_FIRST then - AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender) - elseif control==MSG_MULTI_NEXT then - AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender) - elseif control==MSG_MULTI_LAST then - AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender) - elseif control==MSG_ESCAPE then - AceComm.callbacks:Fire(prefix, rest, distribution, sender) - else - -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!) - end - else - -- single part: fire it off immediately and let CallbackHandler decide if it's registered or not - AceComm.callbacks:Fire(prefix, message, distribution, sender) - end - else - assert(false, "Received "..tostring(event).." event?!") - end + if event == "CHAT_MSG_ADDON" then + sender = Ambiguate(sender, "none") + local control, rest = match(message, "^([\001-\009])(.*)") + if control then + if control == MSG_MULTI_FIRST then + AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender) + elseif control == MSG_MULTI_NEXT then + AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender) + elseif control == MSG_MULTI_LAST then + AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender) + elseif control == MSG_ESCAPE then + AceComm.callbacks:Fire(prefix, rest, distribution, sender) + else + -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!) + end + else + -- single part: fire it off immediately and let CallbackHandler decide if it's registered or not + AceComm.callbacks:Fire(prefix, message, distribution, sender) + end + else + assert(false, "Received " .. tostring(event) .. " event?!") + end end AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame") @@ -242,33 +239,32 @@ AceComm.frame:SetScript("OnEvent", OnEvent) AceComm.frame:UnregisterAllEvents() AceComm.frame:RegisterEvent("CHAT_MSG_ADDON") - ---------------------------------------- -- Base library stuff ---------------------------------------- local mixins = { - "RegisterComm", - "UnregisterComm", - "UnregisterAllComm", - "SendCommMessage", + "RegisterComm", + "UnregisterComm", + "UnregisterAllComm", + "SendCommMessage", } -- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:.. -- @param target target object to embed AceComm-3.0 in function AceComm:Embed(target) - for k, v in pairs(mixins) do - target[v] = self[v] - end - self.embeds[target] = true - return target + for k, v in pairs(mixins) do + target[v] = self[v] + end + self.embeds[target] = true + return target end function AceComm:OnEmbedDisable(target) - target:UnregisterAllComm() + target:UnregisterAllComm() end -- Update embeds for target, v in pairs(AceComm.embeds) do - AceComm:Embed(target) + AceComm:Embed(target) end diff --git a/DiesalGUI-2.0/Objects/Branch.lua b/DiesalGUI-2.0/Objects/Branch.lua index af4203d..a57e8ac 100644 --- a/DiesalGUI-2.0/Objects/Branch.lua +++ b/DiesalGUI-2.0/Objects/Branch.lua @@ -312,6 +312,7 @@ local function Constructor() local icon = self:CreateRegion("Texture", "icon", button) DiesalStyle:StyleTexture(icon, { + type = "texture", position = { 0, nil, 2, nil }, height = 16, width = 16, diff --git a/DiesalGUI-2.0/Objects/ComboBoxItem.lua b/DiesalGUI-2.0/Objects/ComboBoxItem.lua index eac5a03..a00655c 100644 --- a/DiesalGUI-2.0/Objects/ComboBoxItem.lua +++ b/DiesalGUI-2.0/Objects/ComboBoxItem.lua @@ -116,7 +116,6 @@ local function Constructor() frame:SetScript("OnEnter", function(this) end) frame:SetScript("OnLeave", function(this) end) - ---@type Diesal.GUI.Region.FontString local text = self:CreateRegion("FontString", "text", frame) text:SetPoint("TOPLEFT", 12, -2) text:SetPoint("BOTTOMRIGHT", 0, 0) @@ -126,6 +125,7 @@ local function Constructor() local check = self:CreateRegion("Texture", "check", frame) --[[ @as Texture ]] DiesalStyle:StyleTexture(check, { + type = "texture", position = { 2, nil, 0, nil }, height = 16, width = 16, diff --git a/DiesalGUI-2.0/Objects/ObjectBase.lua b/DiesalGUI-2.0/Objects/ObjectBase.lua index f50524d..c1d7f62 100644 --- a/DiesalGUI-2.0/Objects/ObjectBase.lua +++ b/DiesalGUI-2.0/Objects/ObjectBase.lua @@ -170,7 +170,7 @@ local ObjectBase = { ---@return RT CreateRegion = function(self, regionType, regionName, parentRegion, defaultFontObject, ...) if regionType == "FontString" then - ---@type Diesal.GUI.Region.FontString + ---@class Diesal.GUI.Region.FontString local fontString = parentRegion:CreateFontString() fontString.defaultFontObject = defaultFontObject or _G.DiesalFontNormal fontString:SetFont(fontString.defaultFontObject:GetFont()) @@ -434,7 +434,7 @@ DiesalGUI.ObjectBase = ObjectBase ---@class Diesal.GUI.ObjectBase.Settings ---@field parent Frame ----@field parentObject Diesal.Object +---@field parentObject Diesal.Object? ---@field height number ---@field width number diff --git a/DiesalMenu-2.0/Objects/MenuItem.lua b/DiesalMenu-2.0/Objects/MenuItem.lua index 42e9d18..1c8ee7b 100644 --- a/DiesalMenu-2.0/Objects/MenuItem.lua +++ b/DiesalMenu-2.0/Objects/MenuItem.lua @@ -120,6 +120,7 @@ local methods = { subMenu:Show() end, } +---@alias DiesalMenuItem Diesal.Menu.MenuItem -- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local function Constructor() ---@class Diesal.Menu.MenuItem : Diesal.GUI.ObjectBase @@ -162,6 +163,7 @@ local function Constructor() local check = self:CreateRegion("Texture", "check", frame) DiesalStyle:StyleTexture(check, { + type = "texture", position = { 1, nil, 0, nil }, height = 16, width = 16, @@ -169,6 +171,7 @@ local function Constructor() }) local arrow = self:CreateRegion("Texture", "arrow", frame) DiesalStyle:StyleTexture(arrow, { + type = "texture", position = { nil, 2, -1, nil }, height = 16, width = 16, diff --git a/DiesalStyle-2.0/DiesalStyle-2.0.lua b/DiesalStyle-2.0/DiesalStyle-2.0.lua index 07c096f..d695de5 100644 --- a/DiesalStyle-2.0/DiesalStyle-2.0.lua +++ b/DiesalStyle-2.0/DiesalStyle-2.0.lua @@ -34,6 +34,7 @@ DiesalStyle.Formatters = DiesalStyle.Formatters or {} -- ~~| DiesalStyle UpValues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local AddonName = ... +---@type table local ReleasedTextures = DiesalStyle.ReleasedTextures local TextureFrame = DiesalStyle.TextureFrame local Media = DiesalStyle.Media @@ -42,6 +43,7 @@ local Formatters = DiesalStyle.Formatters -- ~~| Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local OUTLINES = { "_LEFT", "_RIGHT", "_TOP", "_BOTTOM" } +---@diagnostic disable-next-line: undefined-global local MEDIA_PATH = MEDIA_PATH or type(AddonName) == "table" and string.format("Interface\\AddOns\\Media\\") or AddonName == "DiesalLibs" and string.format("Interface\\AddOns\\%s\\%s\\Media\\", AddonName, MAJOR) @@ -70,14 +72,14 @@ local function getMedia(mediaType, name) end local function newTexture() - local newTexture = next(ReleasedTextures) - if not newTexture then - newTexture = TextureFrame:CreateTexture() + local nt = next(ReleasedTextures) + if not nt then + nt = TextureFrame:CreateTexture() --[[@as Diesal.Style.Texture]] else - newTexture:Show() - ReleasedTextures[newTexture] = nil + nt:Show() + ReleasedTextures[nt] = nil end - return newTexture + return nt end local function releaseTexture(texture) @@ -114,8 +116,7 @@ local function GetBlizzColorValues(value) if type(value) == "table" and #value >= 3 then return value[1] / 255, value[2] / 255, value[3] / 255 elseif type(value) == "string" then - return tonumber(sub(value, 1, 2), 16) / 255, tonumber(sub(value, 3, 4), 16) / 255, - tonumber(sub(value, 5, 6), 16) / 255 + return tonumber(sub(value, 1, 2), 16) / 255, tonumber(sub(value, 3, 4), 16) / 255, tonumber(sub(value, 5, 6), 16) / 255 end end @@ -177,22 +178,17 @@ end local function setColor(texture, r, g, b, a) local status, err = pcall(texture.SetColorTexture, texture, r, g, b, a) if not status then - errorhandler( - 'error in "' .. (texture.style.name or "texture") .. '" ' .. texture.style.mode .. " or alpha setting", r, g, - b, - a) + errorhandler('error in "' .. (texture.style.name or "texture") .. '" ' .. texture.style.mode .. " or alpha setting", r, g, b, a) end end local function setGradient(texture, orientation, r1, g1, b1, a1, r2, g2, b2, a2) - local status, err = pcall(texture.SetGradient, texture, orientation, CreateColor(r1, g1, b1, a1), - CreateColor(r2, g2, b2, a2)) + local status, err = pcall(texture.SetGradient, texture, orientation, CreateColor(r1, g1, b1, a1), CreateColor(r2, g2, b2, a2)) if not status then - errorhandler('error in "' .. - (texture.style.name or "texture") .. '" ' .. texture.style.mode .. " or alpha setting.") + errorhandler('error in "' .. (texture.style.name or "texture") .. '" ' .. texture.style.mode .. " or alpha setting.") end end -- ~~| Media |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -do -- | Set Colors |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +do -- | Set Colors |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do -- google material colors Colors.red_50 = "fde0dc" Colors.red_100 = "f9bdbb" @@ -462,24 +458,18 @@ do -- | Set Colors |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Colors.UI_200 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.07) -- level 3 Colors.UI_300 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.12) - Colors.UI_300_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.12), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.11) } + Colors.UI_300_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.12), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.11) } Colors.UI_350 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.15) - Colors.UI_350_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.17), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.14) } + Colors.UI_350_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.17), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.14) } -- level 4 Colors.UI_400 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.20) - Colors.UI_400_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.20), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.17) } - Colors.UI_450_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.24), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.20) } + Colors.UI_400_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.20), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.17) } + Colors.UI_450_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.24), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.20) } -- level 5 Colors.UI_500 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.29) - Colors.UI_500_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.29), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.26) } + Colors.UI_500_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.29), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.26) } - Colors.UI_600_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.35), HSL(Colors.UI_Hue, Colors.UI_Saturation, - 0.32) } + Colors.UI_600_GR = { HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.35), HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.32) } -- font Colors -35 Colors.UI_F450 = HSL(Colors.UI_Hue, Colors.UI_Saturation, 0.75) @@ -4152,9 +4142,7 @@ do -- Set Material Icons end ---@param iconName string - ---@param iconType? "regular" | "outlined" | "round" | "sharp" | "twotone" - function DiesalStyle.MaterialIcon(iconName, iconType) - iconType = iconType or "regular" + function DiesalStyle.MaterialIcon(iconName) if MaterialIcons.bytes[iconName] then return utf8(MaterialIcons.bytes[iconName]) end @@ -4200,10 +4188,8 @@ do -- Set Icons ---@param key string ---@param table table local function checkType(prefix, key, table) - assert(type(key) == "string", - string.format("key %d for %s not a string.", prefixInfo[prefix].count, prefixInfo[prefix].prefix)) - assert(type(table) == "table", - string.format("value %d for %s is not a table.", prefixInfo[prefix].count, prefixInfo[prefix].prefix)) + assert(type(key) == "string", string.format("key %d for %s not a string.", prefixInfo[prefix].count, prefixInfo[prefix].prefix)) + assert(type(table) == "table", string.format("value %d for %s is not a table.", prefixInfo[prefix].count, prefixInfo[prefix].prefix)) end for p1, p1Table in pairs(iconsToAdd) do @@ -4217,21 +4203,15 @@ do -- Set Icons local filePrefixes = string.format("%s%s%s", p1, p2, p3) Icons[p1][p2][p3] = Icons[p1][p2][p3] or {} for iconSize, fileDimTable in pairs(p3Table) do - assert(type(iconSize) == "number", - string.format("icon size key %d for %s is not a number.", prefixInfo[3].iconSize, - filePrefixes)) + assert(type(iconSize) == "number", string.format("icon size key %d for %s is not a number.", prefixInfo[3].iconSize, filePrefixes)) filePrefixes = string.format("%s[%d]", filePrefixes, iconSize) Icons[p1][p2][p3][iconSize] = Icons[p1][p2][p3][iconSize] or {} for fileDimKey, iconColumns in pairs(fileDimTable) do - assert(type(fileDimKey == "string"), - string.format("file dimensions key for file %d in %s is not a string.", - prefixInfo[3].file, filePrefixes)) + assert(type(fileDimKey == "string"), string.format("file dimensions key for file %d in %s is not a string.", prefixInfo[3].file, filePrefixes)) local fileDims = strsplittable("x", fileDimKey, 2) - assert(type(tonumber(fileDims[1])) == "number", - string.format("could not obtain width from %s in %s", fileDimKey, filePrefixes)) - assert(type(tonumber(fileDims[2])) == "number", - string.format("could not obtain height from %s in %s", fileDimKey, filePrefixes)) + assert(type(tonumber(fileDims[1])) == "number", string.format("could not obtain width from %s in %s", fileDimKey, filePrefixes)) + assert(type(tonumber(fileDims[2])) == "number", string.format("could not obtain height from %s in %s", fileDimKey, filePrefixes)) Icons[p1][p2][p3][iconSize][fileDimKey] = Icons[p1][p2][p3][iconSize][fileDimKey] or {} filePrefixes = string.format("%s[%s]", filePrefixes, fileDimKey) @@ -4247,18 +4227,14 @@ do -- Set Icons local rowCount = 0 for column, rows in pairs(iconColumns) do columnCount = columnCount + 1 - assert(type(column) == "number", - string.format("column %d key in %s is not a number.", columnCount, filePrefixes)) - assert(type(rows) == "table", - string.format("column %d value in %s is not a table.", columnCount, filePrefixes)) + assert(type(column) == "number", string.format("column %d key in %s is not a number.", columnCount, filePrefixes)) + assert(type(rows) == "table", string.format("column %d value in %s is not a table.", columnCount, filePrefixes)) local filePrefixesColumn = string.format("%s[%d]", filePrefixes, column) iconsFileTable[column] = iconsFileTable[column] or {} for row, icon in pairs(rows) do rowCount = rowCount + 1 - assert(type(row) == "number", - string.format("row %d key in %s is not a number.", rowCount, filePrefixesColumn)) - assert(type(icon) == "string", - string.format("row %d value in %s is not a string.", rowCount, filePrefixesColumn)) + assert(type(row) == "number", string.format("row %d key in %s is not a number.", rowCount, filePrefixesColumn)) + assert(type(icon) == "string", string.format("row %d value in %s is not a string.", rowCount, filePrefixesColumn)) local filePrefixesColumnRow = string.format("%s[%d]", filePrefixesColumn, row) local iconName = icon @@ -4301,8 +4277,7 @@ do -- Set Icons ---@param iconTable DiesalStyle.Icon local function CreateIconStyle(iconTable) - local fileName = string.format("%s%s%s", iconTable.file.prefix[1], iconTable.file.prefix[2], - iconTable.file.prefix[3]) + local fileName = string.format("%s%s%s", iconTable.file.prefix[1], iconTable.file.prefix[2], iconTable.file.prefix[3]) local iconSize = iconTable.file.size.icon fileName = fileName .. (iconSize ~= 16 and iconSize or "") @@ -4677,10 +4652,8 @@ function DiesalStyle:StyleTexture(texture, style) texture.style.alpha = formatAlpha(style.alpha) or texture.style.alpha or { 1, 1 } -- gradient if texture.style.gradient then - texture.style.gradient.orientation = style.gradient_orientation or texture.style.gradient.orientation or - DEFAULT_GRADIENT_ORIENTATION - texture.style.gradient.color = style.gradient_color or texture.style.gradient.color or - { DEFAULT_COLOR, DEFAULT_COLOR } + texture.style.gradient.orientation = style.gradient_orientation or texture.style.gradient.orientation or DEFAULT_GRADIENT_ORIENTATION + texture.style.gradient.color = style.gradient_color or texture.style.gradient.color or { DEFAULT_COLOR, DEFAULT_COLOR } end -- image if texture.style.image then @@ -4716,8 +4689,7 @@ function DiesalStyle:StyleTexture(texture, style) end if style.debug then - print(texture:GetHeight(), texture.style.position[1], texture.style.position[2], texture.style.position[3], - texture.style.position[4]) + print(texture:GetHeight(), texture.style.position[1], texture.style.position[2], texture.style.position[3], texture.style.position[4]) end -- [1] Texture > [2] gradient > [3] color if texture.style.image then -- [1] Texture @@ -4725,12 +4697,10 @@ function DiesalStyle:StyleTexture(texture, style) texture.style.mode = "image" -- clear any old settings setGradient(texture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) -- clear gradient - texture:SetColorTexture(1, 1, 1, 1) -- clear color + texture:SetColorTexture(1, 1, 1, 1) -- clear color -- apply settings - texture:SetTexCoord(texture.style.image.coords[1], texture.style.image.coords[2], texture.style.image.coords[3], - texture.style.image.coords[4]) - texture:SetTexture(texture.style.image.file, texture.style.image.tiling and texture.style.image.tiling[1], - texture.style.image.tiling and texture.style.image.tiling[2]) + texture:SetTexCoord(texture.style.image.coords[1], texture.style.image.coords[2], texture.style.image.coords[3], texture.style.image.coords[4]) + texture:SetTexture(texture.style.image.file, texture.style.image.tiling and texture.style.image.tiling[1], texture.style.image.tiling and texture.style.image.tiling[2]) texture:SetHorizTile(texture.style.image.tiling[1] and true) texture:SetVertTile(texture.style.image.tiling[2] and true) local r, g, b = GetBlizzColorValues(texture.style.image.color) @@ -4739,22 +4709,18 @@ function DiesalStyle:StyleTexture(texture, style) -- set mode texture.style.mode = "gradient" -- clear any old settings - texture:SetTexture() -- clear image + texture:SetTexture() -- clear image texture:SetColorTexture(1, 1, 1, 1) -- clear color -- apply settings - local r1, g1, b1 = GetBlizzColorValues(texture.style.gradient.color - [texture.style.gradient.orientation == "HORIZONTAL" and 1 or 2]) - local r2, g2, b2 = GetBlizzColorValues(texture.style.gradient.color - [texture.style.gradient.orientation == "HORIZONTAL" and 2 or 1]) - local a1, a2 = - texture.style.alpha[texture.style.gradient.orientation == "HORIZONTAL" and 1 or 2], - texture.style.alpha[texture.style.gradient.orientation == "HORIZONTAL" and 2 or 1] + local r1, g1, b1 = GetBlizzColorValues(texture.style.gradient.color[texture.style.gradient.orientation == "HORIZONTAL" and 1 or 2]) + local r2, g2, b2 = GetBlizzColorValues(texture.style.gradient.color[texture.style.gradient.orientation == "HORIZONTAL" and 2 or 1]) + local a1, a2 = texture.style.alpha[texture.style.gradient.orientation == "HORIZONTAL" and 1 or 2], texture.style.alpha[texture.style.gradient.orientation == "HORIZONTAL" and 2 or 1] setGradient(texture, texture.style.gradient.orientation, r1, g1, b1, a1, r2, g2, b2, a2) elseif texture.style.color then -- [3] color -- set mode texture.style.mode = "color" -- clear any old settings - texture:SetTexture() -- clear image + texture:SetTexture() -- clear image setGradient(texture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) -- clear gradient -- apply settings local r, g, b = GetBlizzColorValues(texture.style.color) @@ -4763,9 +4729,9 @@ function DiesalStyle:StyleTexture(texture, style) -- set mode texture.style.mode = "none!" -- clear the texture - texture:SetTexture() -- clear image + texture:SetTexture() -- clear image setGradient(texture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient - texture:SetColorTexture(0, 0, 0, 0) -- clear color + texture:SetColorTexture(0, 0, 0, 0) -- clear color end end @@ -4794,8 +4760,7 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT color = style.gradient[2] and style.gradient[3] and { style.gradient[2], style.gradient[3] }, } end - style.gradient_orientation = style.gradient_orientation and - style.gradient_orientation:upper() --formatOrientation(style.gradient_orientation) -- fuck you + style.gradient_orientation = style.gradient_orientation and style.gradient_orientation:upper() --formatOrientation(style.gradient_orientation) -- fuck you if not texture.style.gradient and (style.gradient_orientation or style.gradient_alpha or style.gradient_color) then texture.style.gradient = {} end @@ -4808,10 +4773,8 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT texture.style.alpha = formatAlpha(style.alpha) or texture.style.alpha or { 1, 1 } -- gradient if texture.style.gradient then - texture.style.gradient.orientation = style.gradient_orientation or texture.style.gradient.orientation or - DEFAULT_GRADIENT_ORIENTATION - texture.style.gradient.color = style.gradient_color or texture.style.gradient.color or - { DEFAULT_COLOR, DEFAULT_COLOR } + texture.style.gradient.orientation = style.gradient_orientation or texture.style.gradient.orientation or DEFAULT_GRADIENT_ORIENTATION + texture.style.gradient.color = style.gradient_color or texture.style.gradient.color or { DEFAULT_COLOR, DEFAULT_COLOR } end -- | Apply Settings |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -4892,11 +4855,11 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT -- set mode texture.style.mode = "gradient" -- clear any old settings - leftTexture:SetTexture() -- clear image + leftTexture:SetTexture() -- clear image -- leftTexture:SetAlpha(1) -- reset alpha - rightTexture:SetTexture() -- clear image + rightTexture:SetTexture() -- clear image -- rightTexture:SetAlpha(1) -- reset alpha - topTexture:SetTexture() -- clear image + topTexture:SetTexture() -- clear image -- topTexture:SetAlpha(1) -- reset alpha bottomTexture:SetTexture() -- clear image -- bottomTexture:SetAlpha(1) -- reset alpha @@ -4907,7 +4870,7 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT -- clear settings setGradient(leftTexture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) setGradient(rightTexture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) - topTexture:SetColorTexture(1, 1, 1, 1) -- clear color + topTexture:SetColorTexture(1, 1, 1, 1) -- clear color bottomTexture:SetColorTexture(1, 1, 1, 1) -- clear color -- aply settings @@ -4921,7 +4884,7 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT setGradient(bottomTexture, "HORIZONTAL", r1, g1, b1, a1, r2, g2, b2, a2) elseif texture.style.gradient.orientation == "VERTICAL" then -- clear settings - leftTexture:SetColorTexture(1, 1, 1, 1) -- clear color + leftTexture:SetColorTexture(1, 1, 1, 1) -- clear color rightTexture:SetColorTexture(1, 1, 1, 1) -- clear color setGradient(topTexture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) setGradient(bottomTexture, "HORIZONTAL", 1, 1, 1, 1, 1, 1, 1, 1) @@ -4958,18 +4921,18 @@ function DiesalStyle:StyleOutline(leftTexture, rightTexture, topTexture, bottomT -- set mode texture.style.mode = "none!" -- clear the texture - leftTexture:SetTexture() -- clear image - setGradient(leftTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient - leftTexture:SetColorTexture(0, 0, 0, 0) -- clear color - rightTexture:SetTexture() -- clear image - setGradient(rightTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient - rightTexture:SetColorTexture(0, 0, 0, 0) -- clear color - topTexture:SetTexture() -- clear image - setGradient(topTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient - topTexture:SetColorTexture(0, 0, 0, 0) -- clear color - bottomTexture:SetTexture() -- clear image + leftTexture:SetTexture() -- clear image + setGradient(leftTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient + leftTexture:SetColorTexture(0, 0, 0, 0) -- clear color + rightTexture:SetTexture() -- clear image + setGradient(rightTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient + rightTexture:SetColorTexture(0, 0, 0, 0) -- clear color + topTexture:SetTexture() -- clear image + setGradient(topTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient + topTexture:SetColorTexture(0, 0, 0, 0) -- clear color + bottomTexture:SetTexture() -- clear image setGradient(bottomTexture, "HORIZONTAL", 0, 0, 0, 0, 0, 0, 0, 0) -- clear gradient - bottomTexture:SetColorTexture(0, 0, 0, 0) -- clear color + bottomTexture:SetColorTexture(0, 0, 0, 0) -- clear color end end @@ -4990,8 +4953,7 @@ end ---@param frame Frame ---@param style Diesal.Style.ShadowStyle function DiesalStyle:StyleShadow(object, frame, style) - object.shadow = object.shadow or - CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") --CreateFrame("Frame",nil,frame) + object.shadow = object.shadow or CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") --CreateFrame("Frame",nil,frame) object.shadow:Show() if not object.shadow.style or style.clear then object.shadow.style = {} @@ -4999,8 +4961,7 @@ function DiesalStyle:StyleShadow(object, frame, style) local shadowStyle = object.shadow.style -- ~~ Format New Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local red, green, blue = DiesalTools.GetColor(style.color) - local offset = style.offset and type(style.offset) == "number" and - { style.offset, style.offset, style.offset, style.offset } or style.offset + local offset = style.offset and type(style.offset) == "number" and { style.offset, style.offset, style.offset, style.offset } or style.offset -- Setting ~~~~~~~~~~~~~~~~~~~~~~~ New Setting ~~~~~~~~~~~~~~~ Old Setting ~~~~~~~~~~~~~~~~~ Default ~~~~~~~~~~~~~~~~~~ shadowStyle.edgeFile = style.edgeFile or shadowStyle.edgeFile or getMedia("border", "shadow") shadowStyle.edgeSize = style.edgeSize or shadowStyle.edgeSize or 28 @@ -5146,7 +5107,7 @@ function DiesalStyle:UpdateObjectStyle(object, name, style) local textures = {} for i = 1, #OUTLINES do local texture = object.textures[name .. OUTLINES[i]] - if not texture then + if type(texture) == "nil" then texture = newTexture() object.textures[name .. OUTLINES[i]] = texture end @@ -5157,6 +5118,7 @@ function DiesalStyle:UpdateObjectStyle(object, name, style) return end if styleType == "Shadow" then + ---@cast object Diesal.Style.ShadowObject DiesalStyle:StyleShadow(object, frame, style --[[ @as Diesal.Style.ShadowStyle ]]) return end