From 49c430dc5c5a1d5cd0afe6f806751e6de33d9c3f Mon Sep 17 00:00:00 2001 From: Buds Date: Sat, 20 Jan 2024 09:15:35 +0100 Subject: [PATCH] Add status icon system for display buttons --- .luacheckrc | 1 + WeakAuras/AuraWarnings.lua | 43 ++++- .../AceGUIWidget-WeakAurasDisplayButton.lua | 163 +++++++++++++----- WeakAurasOptions/OptionsFrames/Update.lua | 2 + WeakAurasOptions/WeakAurasOptions.lua | 46 ++++- 5 files changed, 201 insertions(+), 54 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index a3c83574a4..6242af1fe5 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1556,6 +1556,7 @@ globals = { "CreateFont", "CreateForbiddenFrame", "CreateFrame", + "CreateFramePool", "CreateMacro", "CreateNewRaidProfile", "CursorCanGoInSlot", diff --git a/WeakAuras/AuraWarnings.lua b/WeakAuras/AuraWarnings.lua index b72ee944a3..c1b4f22709 100644 --- a/WeakAuras/AuraWarnings.lua +++ b/WeakAuras/AuraWarnings.lua @@ -74,8 +74,8 @@ local icons = { info = [[Interface/friendsframe/informationicon.blp]], sound = [[chatframe-button-icon-voicechat]], tts = [[chatframe-button-icon-tts]], - warning = [[Interface/buttons/adventureguidemicrobuttonalert.blp]], - error = [[Interface/DialogFrame/UI-Dialog-Icon-AlertNew]] + warning = [[services-icon-warning]], + error = [[Interface/HELPFRAME/HelpIcon-Bug]] } --- @type table @@ -150,3 +150,42 @@ function Private.AuraWarnings.FormatWarnings(uid) result = AddMessages(result, messagePerSeverity["info"], icons["info"], mixedSeverity) return icons[maxSeverity], titles[maxSeverity], result end + +function Private.AuraWarnings.GetAllWarnings(uid) + local results = {} + local thisWarnings + local data = Private.GetDataByUID(uid) + if data.regionType == "group" or data.regionType == "dynamicgroup" then + thisWarnings = {} + for child in Private.TraverseLeafs(data) do + local childWarnings = warnings[child.uid] + if childWarnings then + for key, warning in pairs(childWarnings) do + if not thisWarnings[key] then + thisWarnings[key] = { + severity = warning.severity, + message = warning.message, + auraId = child.id + } + end + end + end + end + else + thisWarnings = CopyTable(warnings[uid]) + local auraId = Private.UIDtoID(uid) + for key in pairs(thisWarnings) do + thisWarnings[key].auraId = auraId + end + end + for key, warning in pairs(thisWarnings) do + results[warning.severity] = { + icon = icons[warning.severity], + prio = 5 + severityLevel[warning.severity], + title = warning.severity, + message = warning.message, + auraId = warning.auraId + } + end + return results +end diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasDisplayButton.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasDisplayButton.lua index 9d7e4d0cf0..516ebe26f2 100644 --- a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasDisplayButton.lua +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasDisplayButton.lua @@ -275,6 +275,8 @@ local function ensure(t, k, v) return t and k and v and t[k] == v end +local statusIconPool = CreateFramePool("Button") + --[[ Actions ]]-- local Actions = { @@ -307,6 +309,7 @@ local Actions = { WeakAuras.ClearAndUpdateOptions(group.data.id) WeakAuras.ClearAndUpdateOptions(source.data.id) group.callbacks.UpdateExpandButton(); + group:UpdateParentWarning() group:ReloadTooltip() else WeakAuras.Add(source.data) @@ -337,6 +340,7 @@ local Actions = { WeakAuras.ClearAndUpdateOptions(parent.id); local group = OptionsPrivate.GetDisplayButton(parent.id) group.callbacks.UpdateExpandButton(); + group:UpdateParentWarning() group:ReloadTooltip() else error("Display thinks it is a member of a group which does not control it") @@ -558,6 +562,7 @@ local methods = { WeakAuras.Add(self.data); OptionsPrivate.Private.AddParents(self.data) self.callbacks.UpdateExpandButton(); + self:UpdateParentWarning(); OptionsPrivate.StopGrouping(); OptionsPrivate.ClearOptions(self.data.id); WeakAuras.FillOptions(); @@ -633,10 +638,12 @@ local methods = { local button = OptionsPrivate.GetDisplayButton(newGroup.id) button.callbacks.UpdateExpandButton() + button:UpdateParentWarning() for old, new in pairs(mapping) do local button = OptionsPrivate.GetDisplayButton(new.id) button.callbacks.UpdateExpandButton() + button:UpdateParentWarning() end OptionsPrivate.SortDisplayButtons(nil, true) @@ -781,6 +788,7 @@ local methods = { if not(newid == oldid) then WeakAuras.Rename(self.data, newid); end + self:UpdateParentWarning() end function self.callbacks.OnDragStart() @@ -915,12 +923,10 @@ local methods = { func = function() LibDD:CloseDropDownMenus() end }); if(self.data.controlledChildren) then - self.loaded:Hide(); self.expand:Show(); self.callbacks.UpdateExpandButton(); self:SetOnExpandCollapse(function() OptionsPrivate.SortDisplayButtons(nil, true) end); else - self.loaded:Show(); self.expand:Hide(); end self.group:Show(); @@ -1133,7 +1139,7 @@ local methods = { self.frame:SetScript("OnClick", nil) self.view:Hide() self.expand:Hide() - self.loaded:Hide() + self.statusIcons:Hide() Hide_Tooltip() if picked then self.frame:EnableKeyboard(true) @@ -1225,10 +1231,9 @@ local methods = { self.frame:SetScript("OnClick", self.callbacks.OnClickNormal) self.frame:EnableKeyboard(false); -- disables self.callbacks.OnKeyDown self.view:Show() + self.statusIcons:Show() if self.data.controlledChildren then self.expand:Show() - else - self.loaded:Show() end self:Enable() @@ -1369,27 +1374,95 @@ local methods = { self:Collapse(); end end, - ["UpdateWarning"] = function(self) - local icon, title, warningText = OptionsPrivate.Private.AuraWarnings.FormatWarnings(self.data.uid) - if warningText then - self.warning:Show() - if C_Texture.GetAtlasInfo(icon) then - self.warning:SetNormalAtlas(icon) - else - self.warning:SetNormalTexture(icon) + ["UpdateStatusIcon"] = function(self, key, prio, icon, title, tooltip, onClick, color) + local iconButton + for _, button in ipairs(self.statusIcons.buttons) do + if button.key == key then + iconButton = button + break end - self.warning:SetScript("OnEnter", function() + end + if not iconButton then + iconButton = statusIconPool:Acquire() + tinsert(self.statusIcons.buttons, iconButton) + iconButton:SetParent(self.statusIcons) + iconButton.key = key + iconButton:SetSize(16, 16) + end + iconButton.prio = prio + if C_Texture.GetAtlasInfo(icon) then + iconButton:SetNormalAtlas(icon) + else + iconButton:SetNormalTexture(icon) + end + if title then + iconButton:SetScript("OnEnter", function() Show_Tooltip( self.frame, title, - warningText + tooltip ) end) - self.warning:SetScript("OnClick", function() - WeakAuras.PickDisplay(self.data.id, "information") - end) + iconButton:SetScript("OnLeave", Hide_Tooltip) + else + iconButton:SetScript("OnEnter", nil) + end + if color then + iconButton:GetNormalTexture():SetVertexColor(unpack(color)) else - self.warning:Hide() + iconButton:GetNormalTexture():SetVertexColor(1, 1, 1, 1) + end + iconButton:SetScript("OnClick", onClick) + iconButton:Show() + end, + ["ClearStatusIcon"] = function(self, key) + for index, button in ipairs(self.statusIcons.buttons) do + if button.key == key then + statusIconPool:Release(button) + table.remove(self.statusIcons.buttons, index) + return + end + end + end, + ["SortStatusIcons"] = function(self) + table.sort(self.statusIcons.buttons, function(a, b) + return a.prio < b.prio + end) + local lastAnchor = self.statusIcons + if self:IsGroup() then + self.statusIcons:SetWidth(17) + else + self.statusIcons:SetWidth(1) + end + for _, button in ipairs(self.statusIcons.buttons) do + button:ClearAllPoints() + button:SetPoint("BOTTOMLEFT", lastAnchor, "BOTTOMRIGHT", 4, 0) + lastAnchor = button + end + end, + ["UpdateWarning"] = function(self) + local warnings = OptionsPrivate.Private.AuraWarnings.GetAllWarnings(self.data.uid) + local warningTypes = {"info", "sound", "tts", "warning", "error"} + for _, key in ipairs(warningTypes) do + self:ClearStatusIcon(key) + end + if warnings then + for severity, warning in pairs(warnings) do + local onClick = function() + WeakAuras.PickDisplay(warning.auraId, "information") + end + self:UpdateStatusIcon(severity, warning.prio, warning.icon, warning.title, warning.message, onClick) + end + end + self:SortStatusIcons() + end, + ["UpdateParentWarning"] = function(self) + self:UpdateWarning() + for parent in OptionsPrivate.Private.TraverseParents(self.data) do + local parentButton = OptionsPrivate.GetDisplayButton(parent.id) + if parentButton then + parentButton:UpdateWarning() + end end end, ["SetGroupOrder"] = function(self, order, max) @@ -1418,10 +1491,13 @@ local methods = { ["GetGroupOrder"] = function(self) return self.frame.dgrouporder; end, - ["SetLoaded"] = function(self, color, title, description) - self.loaded.title = title; - self.loaded.desc = description; - self.loaded:GetNormalTexture():SetVertexColor(unpack(color)) + ["ClearLoaded"] = function(self) + self:ClearStatusIcon("load") + self:SortStatusIcons() + end, + ["SetLoaded"] = function(self, prio, color, title, description) + self:UpdateStatusIcon("load", prio, "Interface\\AddOns\\WeakAuras\\Media\\Textures\\loaded", title, description, nil, color) + self:SortStatusIcons() end, ["IsLoaded"] = function(self) return OptionsPrivate.Private.loaded[self.data.id] == true @@ -1550,8 +1626,10 @@ local methods = { self.view:Disable(); self.group:Disable(); self.ungroup:Disable(); - self.loaded:Disable(); self.expand:Disable(); + for _, button in ipairs(self.statusIcons.buttons) do + button:Disable(); + end self:UpdateUpDownButtons() end, ["Enable"] = function(self) @@ -1560,7 +1638,9 @@ local methods = { self.view:Enable(); self.group:Enable(); self.ungroup:Enable(); - self.loaded:Enable(); + for _, button in ipairs(self.statusIcons.buttons) do + button:Enable(); + end self:UpdateUpDownButtons() if not(self.expand.disabled) then self.expand:Enable(); @@ -1584,6 +1664,10 @@ local methods = { --self.frame:EnableMouse(false); self.frame:ClearAllPoints(); self.frame:Hide(); + for _, button in ipairs(self.statusIcons.buttons) do + statusIconPool:Release(button) + end + wipe(self.statusIcons.buttons) self.frame = nil; self.data = nil; end, @@ -1729,19 +1813,6 @@ local function Constructor() view.visibility = 0; - local loaded = CreateFrame("Button", nil, button); - button.loaded = loaded; - loaded:SetWidth(16); - loaded:SetHeight(16); - loaded:SetPoint("BOTTOM", button, "BOTTOM"); - loaded:SetPoint("LEFT", icon, "RIGHT", 0, 0); - loaded:SetNormalTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\loaded"); - loaded:GetNormalTexture():SetVertexColor(0, 0, 0, 0) -- transparent - loaded.title = L["Loaded"]; - loaded.desc = L["This display is currently loaded"]; - loaded:SetScript("OnEnter", function() Show_Tooltip(button, loaded.title, loaded.desc) end); - loaded:SetScript("OnLeave", Hide_Tooltip); - local renamebox = CreateFrame("EditBox", nil, button, "InputBoxTemplate"); renamebox:SetHeight(14); renamebox:SetPoint("TOP", button, "TOP"); @@ -1851,13 +1922,12 @@ local function Constructor() expand:SetScript("OnEnter", function() Show_Tooltip(button, expand.title, expand.desc) end); expand:SetScript("OnLeave", Hide_Tooltip); - local warning = CreateFrame("Button", nil, button); - button.warning = warning - warning:SetWidth(16) - warning:SetHeight(16) - warning:SetPoint("RIGHT", button, "RIGHT", -60, 0) - warning:SetScript("OnLeave", Hide_Tooltip) - warning:Hide() + local statusIcons = CreateFrame("Frame", nil, button); + button.statusIcons = statusIcons + statusIcons:SetPoint("BOTTOM", button, "BOTTOM", 0, 1); + statusIcons:SetPoint("LEFT", icon, "RIGHT"); + statusIcons:SetSize(1,1) + statusIcons.buttons = {} local widget = { frame = button, @@ -1869,10 +1939,9 @@ local function Constructor() ungroup = ungroup, upgroup = upgroup, downgroup = downgroup, - loaded = loaded, background = background, expand = expand, - warning = warning, + statusIcons = statusIcons, type = Type, offset = offset } diff --git a/WeakAurasOptions/OptionsFrames/Update.lua b/WeakAurasOptions/OptionsFrames/Update.lua index 51b7eec2a1..0da911af73 100644 --- a/WeakAurasOptions/OptionsFrames/Update.lua +++ b/WeakAurasOptions/OptionsFrames/Update.lua @@ -1996,6 +1996,7 @@ local methods = { button:SetGroupOrder(nil, nil) end button.callbacks.UpdateExpandButton() + button:UpdateParentWarning() WeakAuras.UpdateGroupOrders(data) WeakAuras.UpdateThumbnail(data) WeakAuras.ClearAndUpdateOptions(data.id) @@ -2057,6 +2058,7 @@ local methods = { button:SetGroupOrder(nil, nil) end button.callbacks.UpdateExpandButton() + button:UpdateParentWarning() WeakAuras.UpdateGroupOrders(data) WeakAuras.UpdateThumbnail(data) WeakAuras.ClearAndUpdateOptions(data.id) diff --git a/WeakAurasOptions/WeakAurasOptions.lua b/WeakAurasOptions/WeakAurasOptions.lua index c068c16bfd..8ae9cbb63f 100644 --- a/WeakAurasOptions/WeakAurasOptions.lua +++ b/WeakAurasOptions/WeakAurasOptions.lua @@ -101,6 +101,7 @@ function OptionsPrivate.DuplicateAura(data, newParent, massEdit, targetIndex) if not massEdit then local button = OptionsPrivate.GetDisplayButton(parentData.id) button.callbacks.UpdateExpandButton() + button:UpdateParentWarning() end OptionsPrivate.ClearOptions(parentData.id) end @@ -287,6 +288,7 @@ local function CreateNewGroupFromSelection(regionType, resetChildPositions) parentButton.callbacks.UpdateExpandButton(); parentButton:Expand(); parentButton:ReloadTooltip(); + parentButton:UpdateParentWarning(); else WeakAuras.Add(data); WeakAuras.NewDisplayButton(data); @@ -308,6 +310,7 @@ local function CreateNewGroupFromSelection(regionType, resetChildPositions) local oldParentButton = OptionsPrivate.GetDisplayButton(oldParent) oldParentButton.callbacks.UpdateExpandButton(); oldParentButton:ReloadTooltip() + oldParentButton:UpdateParentWarning() end tinsert(data.controlledChildren, childId); @@ -326,6 +329,7 @@ local function CreateNewGroupFromSelection(regionType, resetChildPositions) local button = OptionsPrivate.GetDisplayButton(data.id); button.callbacks.UpdateExpandButton(); + button:UpdateParentWarning() OptionsPrivate.SortDisplayButtons(); button:Expand(); @@ -579,6 +583,13 @@ function WeakAuras.ToggleOptions(msg, Private) -- The button does not yet exists if a new aura is created displayButtons[id]:UpdateWarning() end + local data = Private.GetDataByUID(uid) + if data and data.parent then + local button = OptionsPrivate.GetDisplayButton(data.parent); + if button then + button:UpdateParentWarning() + end + end end) OptionsPrivate.Private.callbacks:RegisterCallback("ScanForLoads", AfterScanForLoads) @@ -786,6 +797,7 @@ function OptionsPrivate.DeleteAuras(auras, parents) parentButton:SetNormalTooltip() WeakAuras.Add(parentData) WeakAuras.ClearAndUpdateOptions(parentData.id) + parentButton:UpdateParentWarning() frame.loadProgress:SetText(L["Finishing..."]) coroutine.yield() end @@ -1132,12 +1144,35 @@ function OptionsPrivate.SortDisplayButtons(filter, overrideReset, id) local visible = {} for id, child in pairs(displayButtons) do - if OptionsPrivate.Private.loaded[id] == true then - child:SetLoaded({0, 0.68, 0.30, 1}, L["Loaded"], L["This display is currently loaded"]) - elseif OptionsPrivate.Private.loaded[id] == false then - child:SetLoaded({0.96, 0.82, 0.16, 1}, L["Standby"], L["This display is on standby, it will be loaded when needed."]) + if child.data.controlledChildren then + local hasLoaded, hasStandBy, hasNotLoaded = 0, 0, 0 + for leaf in OptionsPrivate.Private.TraverseLeafs(child.data) do + local id = leaf.id + if OptionsPrivate.Private.loaded[id] == true then + hasLoaded = hasLoaded + 1 + elseif OptionsPrivate.Private.loaded[id] == false then + hasStandBy = hasStandBy + 1 + else + hasNotLoaded = hasNotLoaded + 1 + end + end + if hasLoaded > 0 then + child:SetLoaded(1, {0, 0.68, 0.30, 1}, L["Loaded"], L["%d displays loaded"]:format(hasLoaded)) + elseif hasStandBy > 0 then + child:SetLoaded(2, {0.96, 0.82, 0.16, 1}, L["Standby"], L["%d displays on standby"]:format(hasStandBy)) + elseif hasNotLoaded > 0 then + child:SetLoaded(3, {0.6, 0.6, 0.6, 1}, L["Not Loaded"], L["%d displays not loaded"]:format(hasNotLoaded)) + else + child:ClearLoaded() + end else - child:SetLoaded({0.6, 0.6, 0.6, 1}, L["Not Loaded"],L["This display is not currently loaded"]) + if OptionsPrivate.Private.loaded[id] == true then + child:SetLoaded(1, {0, 0.68, 0.30, 1}, L["Loaded"], L["This display is currently loaded"]) + elseif OptionsPrivate.Private.loaded[id] == false then + child:SetLoaded(2, {0.96, 0.82, 0.16, 1}, L["Standby"], L["This display is on standby, it will be loaded when needed."]) + else + child:SetLoaded(3, {0.6, 0.6, 0.6, 1}, L["Not Loaded"], L["This display is not currently loaded"]) + end end if useTextFilter then @@ -1766,6 +1801,7 @@ function WeakAuras.NewAura(sourceData, regionType, targetId) WeakAuras.UpdateGroupOrders(group.data); OptionsPrivate.ClearOptions(group.data.id); group.callbacks.UpdateExpandButton(); + group:UpdateParentWarning(); group:Expand(); group:ReloadTooltip(); OptionsPrivate.PickAndEditDisplay(data.id);