diff --git a/Constants.lua b/Constants.lua index 1f3bd565..913be60e 100644 --- a/Constants.lua +++ b/Constants.lua @@ -10,6 +10,7 @@ local constants = { ADDON_METADATA_VERSION_KEY = "Version", DEBUG_COLOR = "F17934", ERROR_COLOR = "ff4040", + WARNING_COLOR = "ffd100", RELEASE_POPUP_VERSION = "v0.8.3", VERSION_TAG_BETA = "beta", @@ -122,7 +123,7 @@ local constants = { -- Runtime timing and debug limits LAYOUT_COMBAT_END_DELAY = 0.1, LAYOUT_ENTERING_WORLD_DELAY = 0.4, - LAYOUT_STORM_COUNT = 20, + LAYOUT_STORM_COUNT = 60, LAYOUT_STORM_WINDOW = 2, LAYOUT_ZONE_CHANGE_DELAY = 0.1, LIFECYCLE_SECOND_PASS_DELAY = 0.05, diff --git a/ECM.lua b/ECM.lua index dfe9aa31..a6cd239c 100644 --- a/ECM.lua +++ b/ECM.lua @@ -174,7 +174,7 @@ function ns.ErrorLog(module, message, data) local messageStr = ns.ToString(message) local payload = makeErrorData(module, nil, data) local dataStr = ns.ToString(payload) - local coloredPrefix = "|cff" .. C.ERROR_COLOR .. "[" .. L["ADDON_ABRV"] .. " Error" + local coloredPrefix = "|cff" .. C.WARNING_COLOR .. "[" .. L["ADDON_ABRV"] .. " Warning" .. (module and (" " .. module) or "") .. "]|r " print(coloredPrefix .. messageStr .. "\n" .. dataStr) diff --git a/EnhancedCooldownManager.code-workspace b/EnhancedCooldownManager.code-workspace index d18834a6..f6a1f25d 100644 --- a/EnhancedCooldownManager.code-workspace +++ b/EnhancedCooldownManager.code-workspace @@ -20,7 +20,7 @@ }, "Lua.workspace.library": [ "~\\scoop\\apps\\luarocks\\current\\rocks\\share\\lua\\5.4\\busted", - "~\\.vscode\\extensions\\ketho.wow-api-0.22.2\\Annotations\\Core" + "~\\.vscode\\extensions\\ketho.wow-api-0.22.3\\Annotations\\Core" ], "Lua.workspace.ignoreDir": [ "Tests", @@ -85,7 +85,18 @@ "ChatFontNormal", "GRAY_FONT_COLOR", "coroutine", - "canaccesstable" + "canaccesstable", + "ADD", + "REMOVE", + "BuffBarCooldownViewer", + "UISpecialFrames", + "ScrollUtil", + "CreateScrollBoxListLinearView", + "CreateDataProvider", + "GameTooltip_Hide", + "SettingsPanel", + "SettingsSliderControlMixin", + "CreateSettingsListSectionHeaderInitializer" ], "Lua.diagnostics.disable": [ "assign-type-mismatch" diff --git a/EnhancedCooldownManager.toc b/EnhancedCooldownManager.toc index f1957b88..ae52e737 100644 --- a/EnhancedCooldownManager.toc +++ b/EnhancedCooldownManager.toc @@ -22,7 +22,7 @@ Libs\LibDeflate\lib.xml Libs\LibEditMode\embed.xml Libs\LibSharedMedia-3.0\lib.xml Libs\LibSettingsBuilder\embed.xml -Libs\LibLSMSettingsWidgets\LibLSMSettingsWidgets.xml +Libs\LibLSMSettingsWidgets\LibLSMSettingsWidgets.lua Constants.lua Locales\en.lua diff --git a/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.lua b/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.lua index 8607e8a9..0b4b8a0c 100644 --- a/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.lua +++ b/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.lua @@ -1,19 +1,16 @@ --- LibLSMSettingsWidgets: LibSharedMedia picker widgets for the WoW Settings API. --- Provides font and texture picker templates with live previews. +-- Enhanced Cooldown Manager addon for World of Warcraft +-- Author: Argium +-- Licensed under the GNU General Public License v3.0 -local MAJOR, MINOR = "LibLSMSettingsWidgets-1.0", 2 +-- LibLSMSettingsWidgets: LibSharedMedia picker widgets for LibSettingsBuilder rows. + +local MAJOR, MINOR = "LibLSMSettingsWidgets-1.0", 3 local lib = LibStub:NewLibrary(MAJOR, MINOR) if not lib then return end local LSM = LibStub("LibSharedMedia-3.0") -lib.FONT_PICKER_TEMPLATE = "LibLSMSettingsWidgets_FontPickerTemplate" -lib.TEXTURE_PICKER_TEMPLATE = "LibLSMSettingsWidgets_TexturePickerTemplate" - --------------------------------------------------------------------------------- --- Media value helpers --------------------------------------------------------------------------------- - +local FONT_PREVIEW_TEXT = "AaBbCcDd 1234" local mediaCache = {} local function invalidateMediaCache() @@ -42,179 +39,221 @@ local function getSortedMediaNames(mediaType, fallback) return sorted end -function lib.GetFontValues() - local names = getSortedMediaNames("font", "Expressway") +local function getMediaValues(mediaType, fallback) local values = {} - for _, name in ipairs(names) do + for _, name in ipairs(getSortedMediaNames(mediaType, fallback)) do values[name] = name end return values end -function lib.GetStatusbarValues() - local names = getSortedMediaNames("statusbar", "Blizzard") - local values = {} - for _, name in ipairs(names) do - values[name] = name - end - return values +function lib.GetFontValues() + return getMediaValues("font", "Expressway") end --------------------------------------------------------------------------------- --- Shared picker helpers --------------------------------------------------------------------------------- - -local function setPickerEnabled(self, enabled) - self.DropDown:SetEnabled(enabled) - self.DropDown:EnableMouse(enabled) - self.DropDownHost:SetEnabled(enabled) - self.DropDownHost:EnableMouse(enabled) - self.Preview[enabled and "Show" or "Hide"](self.Preview) +function lib.GetStatusbarValues() + return getMediaValues("statusbar", "Blizzard") end -local function createDropDown(self) - local host = CreateFrame("Frame", nil, self, "SettingsDropdownWithButtonsTemplate") - host.DecrementButton:Hide() - host.IncrementButton:Hide() +local function createDropDown(frame) + local host = CreateFrame("Frame", nil, frame, "SettingsDropdownWithButtonsTemplate") + if host.DecrementButton then + host.DecrementButton:Hide() + end + if host.IncrementButton then + host.IncrementButton:Hide() + end local dropdown = host.Dropdown or host - dropdown:SetPoint("LEFT", self.Text, "RIGHT", 10, 0) dropdown:SetWidth(200) - self.DropDownHost = host - return dropdown + return host, dropdown end -local function initPicker(self, initializer) - SettingsListElementMixin.Init(self, initializer) - - local data = initializer:GetData() or {} - self.setting = data.setting or (initializer.GetSetting and initializer:GetSetting()) or nil - - if data.name and self.Text then - self.Text:SetText(data.name) +local function ensurePicker(frame, kind) + local picker = frame._lsmwPicker + if not picker then + local host, dropdown = createDropDown(frame) + picker = { host = host, dropdown = dropdown } + frame._lsmwPicker = picker end - self:SetupDropdown() - self:UpdatePreview() + if picker.kind ~= kind then + if picker.preview then + picker.preview:Hide() + end - local frame = self - local oldSetEnabled = initializer.SetEnabled - initializer.SetEnabled = function(init, enabled) - if oldSetEnabled then - oldSetEnabled(init, enabled) + if kind == "font" then + picker.preview = picker.fontPreview or frame:CreateFontString(nil, "OVERLAY") + picker.fontPreview = picker.preview + picker.preview:SetFontObject(GameFontHighlight) + picker.preview:SetJustifyH("LEFT") + else + picker.preview = picker.texturePreview or frame:CreateTexture(nil, "ARTWORK") + picker.texturePreview = picker.preview + picker.preview:SetSize(120, 16) + picker.preview:SetVertexColor(0.4, 0.6, 0.9, 1) end - frame:SetEnabled(enabled) + picker.kind = kind end -end -local function setupMediaDropdown(self, mediaType, fallback) - local setting = self.setting - local picker = self + return picker +end - if not setting then return end +local function setPickerEnabled(frame, enabled) + local picker = frame._lsmwPicker + if not picker then return end - self.DropDown:SetupMenu(function(_, rootDescription) - rootDescription:SetScrollMode(200) + picker.dropdown:SetEnabled(enabled) + picker.dropdown:EnableMouse(enabled) + picker.host:SetEnabled(enabled) + picker.host:EnableMouse(enabled) + picker.preview[enabled and "Show" or "Hide"](picker.preview) +end - local sorted = getSortedMediaNames(mediaType, fallback) +local function configurePickerInitializer(initializer) + if initializer._lsmwHasEnabledBridge then return end - for _, name in ipairs(sorted) do - rootDescription:CreateRadio(name, - function() return setting:GetValue() == name end, - function() - setting:SetValue(name) - picker:UpdatePreview() - end) + initializer._lsmwEnabled = true + initializer._lsmwHasEnabledBridge = true + initializer.SetEnabled = function(controlInitializer, enabled) + controlInitializer._lsmwEnabled = enabled + local frame = controlInitializer._lsbActiveFrame + if frame and (not frame._lsbInitializer or frame._lsbInitializer == controlInitializer) then + setPickerEnabled(frame, enabled) end - end) + end end ---- Updates the dropdown label and fetches the media path for the current value. ----@return string|nil currentName ----@return string|nil mediaPath -local function updateDropdownText(self, mediaType) - if not self.setting then return nil, nil end - - local currentName = self.setting:GetValue() - local mediaPath = LSM:Fetch(mediaType, currentName) +local function anchorPicker(frame, picker) + if frame.Text then + frame.Text:ClearAllPoints() + frame.Text:SetPoint("LEFT", frame, "LEFT", 37, 0) + frame.Text:SetPoint("RIGHT", frame, "CENTER", -85, 0) + frame.Text:SetJustifyV("MIDDLE") + frame.Text:Show() + end - if self.DropDown and self.DropDown.OverrideText then - self.DropDown:OverrideText(currentName or "") + picker.host:ClearAllPoints() + if frame.Text then + picker.host:SetPoint("LEFT", frame.Text, "RIGHT", 10, 0) + else + picker.host:SetPoint("LEFT", frame, "CENTER", -80, 0) end + picker.host:Show() - return currentName, mediaPath + picker.preview:ClearAllPoints() + picker.preview:SetPoint("LEFT", picker.dropdown, "RIGHT", 10, 0) + picker.preview:SetPoint("RIGHT", frame, "RIGHT", -20, 0) + picker.preview:Show() end --------------------------------------------------------------------------------- --- Font Picker Mixin --------------------------------------------------------------------------------- +local function updateDropdownText(picker, setting, mediaType) + local currentName = setting and setting.GetValue and setting:GetValue() or nil -LibLSMSettingsWidgets_FontPickerMixin = {} + if picker.dropdown.OverrideText then + picker.dropdown:OverrideText(currentName or "") + end -function LibLSMSettingsWidgets_FontPickerMixin:OnLoad() - SettingsListElementMixin.OnLoad(self) + if not currentName then + return nil, nil + end - self.DropDown = createDropDown(self) - self.Preview = self:CreateFontString(nil, "OVERLAY") - self.Preview:SetFontObject(GameFontHighlight) - self.Preview:SetPoint("LEFT", self.DropDown, "RIGHT", 10, 0) - self.Preview:SetPoint("RIGHT", self, "RIGHT", -20, 0) - self.Preview:SetJustifyH("LEFT") - self.Preview:SetText("AaBbCcDd 1234") + return currentName, LSM:Fetch(mediaType, currentName) end -LibLSMSettingsWidgets_FontPickerMixin.CreateDropDown = createDropDown -LibLSMSettingsWidgets_FontPickerMixin.Init = initPicker -LibLSMSettingsWidgets_FontPickerMixin.SetEnabled = setPickerEnabled +local function updateFontPreview(picker, setting) + local _, fontPath = updateDropdownText(picker, setting, "font") + if fontPath then + picker.preview:SetFont(fontPath, 14, "") + picker.preview:SetText(FONT_PREVIEW_TEXT) + else + picker.preview:SetFontObject(GameFontHighlight) + picker.preview:SetText("") + end +end -function LibLSMSettingsWidgets_FontPickerMixin:SetupDropdown() - setupMediaDropdown(self, "font", "Expressway") +local function updateTexturePreview(picker, setting) + local _, texturePath = updateDropdownText(picker, setting, "statusbar") + picker.preview:SetTexture(texturePath) end -function LibLSMSettingsWidgets_FontPickerMixin:UpdatePreview() - local _, fontPath = updateDropdownText(self, "font") - if self.Preview then - if fontPath then - self.Preview:SetFont(fontPath, 14, "") - self.Preview:SetText("AaBbCcDd 1234") - else - self.Preview:SetFontObject(GameFontHighlight) - self.Preview:SetText("") +local function setupMediaDropdown(frame, picker, setting, mediaType, fallback, updatePreview) + if not setting then return end + + picker.dropdown:SetupMenu(function(_, rootDescription) + rootDescription:SetScrollMode(200) + + for _, name in ipairs(getSortedMediaNames(mediaType, fallback)) do + rootDescription:CreateRadio(name, + function() return setting:GetValue() == name end, + function() + setting:SetValue(name) + updatePreview(picker, setting) + if frame.RefreshDropdownText then + frame:RefreshDropdownText() + end + end) end - end + end) end --------------------------------------------------------------------------------- --- Texture Picker Mixin --------------------------------------------------------------------------------- +local function applyPickerRow(frame, data, initializer, kind, mediaType, fallback, updatePreview) + configurePickerInitializer(initializer) + initializer._lsbActiveFrame = frame -LibLSMSettingsWidgets_TexturePickerMixin = {} + local picker = ensurePicker(frame, kind) + local setting = data.setting -function LibLSMSettingsWidgets_TexturePickerMixin:OnLoad() - SettingsListElementMixin.OnLoad(self) + frame._lsmwPickerSetting = setting + if frame.Text then + frame.Text:SetText(data.name or "") + end - self.DropDown = createDropDown(self) - self.Preview = self:CreateTexture(nil, "ARTWORK") - self.Preview:SetPoint("LEFT", self.DropDown, "RIGHT", 10, 0) - self.Preview:SetSize(120, 16) - self.Preview:SetVertexColor(0.4, 0.6, 0.9, 1) + anchorPicker(frame, picker) + setupMediaDropdown(frame, picker, setting, mediaType, fallback, updatePreview) + updatePreview(picker, setting) + setPickerEnabled(frame, initializer._lsmwEnabled ~= false) end -LibLSMSettingsWidgets_TexturePickerMixin.CreateDropDown = createDropDown -LibLSMSettingsWidgets_TexturePickerMixin.Init = initPicker -LibLSMSettingsWidgets_TexturePickerMixin.SetEnabled = setPickerEnabled +function lib.ApplyFontPickerRow(frame, data, initializer) + applyPickerRow(frame, data, initializer, "font", "font", "Expressway", updateFontPreview) +end -function LibLSMSettingsWidgets_TexturePickerMixin:SetupDropdown() - setupMediaDropdown(self, "statusbar", "Blizzard") +function lib.ApplyTexturePickerRow(frame, data, initializer) + applyPickerRow(frame, data, initializer, "texture", "statusbar", "Blizzard", updateTexturePreview) end -function LibLSMSettingsWidgets_TexturePickerMixin:UpdatePreview() - local _, texturePath = updateDropdownText(self, "statusbar") - if self.Preview then - if texturePath then - self.Preview:SetTexture(texturePath) - else - self.Preview:SetTexture(nil) - end +function lib.ResetPickerRow(frame) + local picker = frame._lsmwPicker + if not picker then return end + + picker.host:Hide() + if picker.fontPreview then + picker.fontPreview:Hide() + end + if picker.texturePreview then + picker.texturePreview:Hide() end + frame._lsmwPickerSetting = nil end + +function lib.Register(settingsBuilder) + if not settingsBuilder or not settingsBuilder.RegisterRowType then return end + + settingsBuilder:RegisterRowType("font", { + varType = "string", + defaultValue = "", + extent = 26, + applyFrame = lib.ApplyFontPickerRow, + resetFrame = lib.ResetPickerRow, + }) + settingsBuilder:RegisterRowType("texture", { + varType = "string", + defaultValue = "", + extent = 26, + applyFrame = lib.ApplyTexturePickerRow, + resetFrame = lib.ResetPickerRow, + }) +end + +lib.Register(LibStub("LibSettingsBuilder-1.0", true)) diff --git a/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.xml b/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.xml deleted file mode 100644 index ebf294c2..00000000 --- a/Libs/LibLSMSettingsWidgets/LibLSMSettingsWidgets.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -