2176 lines
86 KiB
Lua
2176 lines
86 KiB
Lua
-- Modules/Tracker/TrackerOptions.lua
|
|
|
|
local ADDON_NAME = "HailMaryGuildTools"
|
|
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
|
if not HMGT then return end
|
|
if not HMGT_Config or not HMGT_Config.RegisterOptionsProvider then return end
|
|
|
|
local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME)
|
|
local LSM = LibStub("LibSharedMedia-3.0", true)
|
|
local AceConfigRegistry = LibStub("AceConfigRegistry-3.0", true)
|
|
|
|
local trackerOptionsGroup
|
|
local trackedSpellsOptionsGroup
|
|
local RefreshTrackerOptionArgs
|
|
local RefreshTrackedSpellsOptionArgs
|
|
|
|
local ANCHOR_POINT_VALUES = {
|
|
TOPLEFT = "TOPLEFT", TOP = "TOP", TOPRIGHT = "TOPRIGHT",
|
|
LEFT = "LEFT", CENTER = "CENTER", RIGHT = "RIGHT",
|
|
BOTTOMLEFT = "BOTTOMLEFT", BOTTOM = "BOTTOM", BOTTOMRIGHT = "BOTTOMRIGHT",
|
|
}
|
|
|
|
local FONT_OUTLINE_VALUES = {
|
|
[""] = L["OPT_OUTLINE_NONE"] or "None",
|
|
OUTLINE = L["OPT_OUTLINE_NORMAL"] or "Outline",
|
|
THICKOUTLINE = L["OPT_OUTLINE_THICK"] or "Thick Outline",
|
|
MONOCHROME = L["OPT_OUTLINE_MONO"] or "Monochrome",
|
|
}
|
|
|
|
local ROLE_FILTER_VALUES = {
|
|
ALL = L["OPT_ROLE_FILTER_ALL"] or "All",
|
|
TANK = L["OPT_ROLE_FILTER_TANK"] or "Tank",
|
|
HEALER = L["OPT_ROLE_FILTER_HEALER"] or "Healer",
|
|
DAMAGER = L["OPT_ROLE_FILTER_DAMAGER"] or "Damage",
|
|
}
|
|
|
|
local function NotifyOptionsChanged()
|
|
if AceConfigRegistry and type(AceConfigRegistry.NotifyChange) == "function" then
|
|
AceConfigRegistry:NotifyChange(ADDON_NAME)
|
|
end
|
|
end
|
|
|
|
local function TriggerTrackerUpdate(rebuildArgs)
|
|
if rebuildArgs then
|
|
if RefreshTrackerOptionArgs then
|
|
RefreshTrackerOptionArgs()
|
|
end
|
|
if RefreshTrackedSpellsOptionArgs then
|
|
RefreshTrackedSpellsOptionArgs()
|
|
end
|
|
end
|
|
HMGT:TriggerTrackerUpdate()
|
|
NotifyOptionsChanged()
|
|
end
|
|
|
|
local function RefreshAnchors(rebuildArgs)
|
|
if rebuildArgs and RefreshTrackerOptionArgs then
|
|
RefreshTrackerOptionArgs()
|
|
end
|
|
HMGT:RefreshFrameAnchors(true)
|
|
NotifyOptionsChanged()
|
|
end
|
|
|
|
local function CopyGroup(group, overrides)
|
|
if type(group) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local out = {}
|
|
for key, value in pairs(group) do
|
|
out[key] = value
|
|
end
|
|
for key, value in pairs(overrides or {}) do
|
|
out[key] = value
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function GetSortedTrackers()
|
|
local trackers = {}
|
|
for _, tracker in ipairs(HMGT:GetTrackerConfigs()) do
|
|
trackers[#trackers + 1] = tracker
|
|
end
|
|
table.sort(trackers, function(a, b)
|
|
local aId = tonumber(a and a.id) or 0
|
|
local bId = tonumber(b and b.id) or 0
|
|
if aId ~= bId then
|
|
return aId < bId
|
|
end
|
|
return tostring(a and a.name or "") < tostring(b and b.name or "")
|
|
end)
|
|
return trackers
|
|
end
|
|
|
|
local function GetTrackerSettings(trackerId)
|
|
return HMGT:GetTrackerConfigById(trackerId)
|
|
end
|
|
|
|
local function GetTrackerLabel(tracker)
|
|
if type(tracker) ~= "table" then
|
|
return L["OPT_TRACKER"] or "Tracker"
|
|
end
|
|
local name = tostring(tracker.name or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|
if name ~= "" then
|
|
return name
|
|
end
|
|
return string.format("%s %d", L["OPT_TRACKER"] or "Tracker", tonumber(tracker.id) or 0)
|
|
end
|
|
|
|
local function GetTrackerCategoryValues()
|
|
if HMGT_SpellData and type(HMGT_SpellData.GetTrackerCategoryValues) == "function" then
|
|
return HMGT_SpellData.GetTrackerCategoryValues()
|
|
end
|
|
return {
|
|
interrupt = L["CAT_interrupt"] or "Interrupts",
|
|
defensive = L["CAT_defensive"] or "Defensive Cooldowns",
|
|
offensive = L["CAT_offensive"] or "Offensive Cooldowns",
|
|
cc = L["CAT_cc"] or "Crowd Control",
|
|
raid = L["CAT_raid"] or "Raid Cooldowns",
|
|
}
|
|
end
|
|
|
|
local function GetCategoryLabel(category)
|
|
return GetTrackerCategoryValues()[tostring(category or "")] or tostring(category or "utility")
|
|
end
|
|
|
|
local function GetTrackerCategoriesSummary(tracker)
|
|
local labels = {}
|
|
for _, category in ipairs((tracker and tracker.categories) or {}) do
|
|
labels[#labels + 1] = GetCategoryLabel(category)
|
|
end
|
|
if #labels == 0 then
|
|
return "No categories selected."
|
|
end
|
|
return table.concat(labels, ", ")
|
|
end
|
|
|
|
local function IsPartyAttachMode(tracker)
|
|
return type(tracker) == "table"
|
|
and tracker.trackerType == "group"
|
|
and tracker.attachToPartyFrame == true
|
|
end
|
|
|
|
local function IsGroupTracker(tracker)
|
|
return type(tracker) == "table" and tracker.trackerType == "group"
|
|
end
|
|
|
|
local TRACKER_TYPE_VALUES = {
|
|
normal = L["OPT_TRACKER_TYPE_NORMAL"] or "Normal tracker",
|
|
group = L["OPT_TRACKER_TYPE_GROUP"] or "Group-based tracker",
|
|
}
|
|
|
|
local function GetTrackerVisibilitySummary(tracker)
|
|
local parts = {}
|
|
if tracker.showInSolo ~= false then parts[#parts + 1] = L["OPT_SHOW_SOLO"] or "Solo" end
|
|
if tracker.showInGroup ~= false then parts[#parts + 1] = L["OPT_SHOW_GROUP"] or "Group" end
|
|
if tracker.showInRaid ~= false then parts[#parts + 1] = L["OPT_SHOW_RAID"] or "Raid" end
|
|
if #parts == 0 then
|
|
return L["OPT_VISIBILITY_NONE"] or "Hidden everywhere"
|
|
end
|
|
return table.concat(parts, ", ")
|
|
end
|
|
|
|
local function GetTrackerSummaryText(tracker)
|
|
if type(tracker) ~= "table" then
|
|
return L["OPT_TRACKERS_EMPTY"] or "No tracker selected."
|
|
end
|
|
|
|
local modeLabel
|
|
if tracker.testMode then
|
|
modeLabel = L["OPT_TEST_MODE"] or "Test mode"
|
|
elseif tracker.demoMode then
|
|
modeLabel = L["OPT_DEMO_MODE"] or "Demo mode"
|
|
elseif tracker.enabled ~= false then
|
|
modeLabel = L["OPT_ENABLED"] or "Enabled"
|
|
else
|
|
modeLabel = L["OPT_DISABLED"] or "Disabled"
|
|
end
|
|
|
|
local display = tracker.showBar and (L["OPT_DISPLAY_BAR"] or "Progress bars") or (L["OPT_DISPLAY_ICON"] or "Icons")
|
|
|
|
return table.concat({
|
|
string.format("|cffffd100%s|r: %s", L["OPT_TRACKER_TYPE"] or "Tracker type", TRACKER_TYPE_VALUES[tracker.trackerType or "normal"] or (L["OPT_TRACKER_TYPE_NORMAL"] or "Normal tracker")),
|
|
string.format("|cffffd100%s|r: %s", L["OPT_TRACKER_CATEGORIES"] or "Categories", GetTrackerCategoriesSummary(tracker)),
|
|
string.format("|cffffd100%s|r: %s", L["OPT_STATUS_MODE"] or "Mode", modeLabel),
|
|
string.format("|cffffd100%s|r: %s", L["OPT_STATUS_DISPLAY"] or "Display", display),
|
|
string.format("|cffffd100%s|r: %s", L["OPT_STATUS_VISIBILITY"] or "Visibility", GetTrackerVisibilitySummary(tracker)),
|
|
}, "\n")
|
|
end
|
|
|
|
local function NormalizeSearchText(value)
|
|
local text = tostring(value or ""):lower()
|
|
text = text:gsub("^%s+", "")
|
|
text = text:gsub("%s+$", "")
|
|
return text
|
|
end
|
|
|
|
local function LocalizedClassName(classToken)
|
|
return (LOCALIZED_CLASS_NAMES_MALE and LOCALIZED_CLASS_NAMES_MALE[classToken])
|
|
or (LOCALIZED_CLASS_NAMES_FEMALE and LOCALIZED_CLASS_NAMES_FEMALE[classToken])
|
|
or classToken
|
|
end
|
|
|
|
local function GetSpellNameById(spellId)
|
|
local sid = tonumber(spellId)
|
|
if not sid or sid <= 0 then return nil end
|
|
if C_Spell and type(C_Spell.GetSpellName) == "function" then
|
|
local ok, name = pcall(C_Spell.GetSpellName, sid)
|
|
if ok and type(name) == "string" and name ~= "" then
|
|
return name
|
|
end
|
|
end
|
|
if type(GetSpellInfo) == "function" then
|
|
local name = GetSpellInfo(sid)
|
|
if type(name) == "string" and name ~= "" then
|
|
return name
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function GetSpellIconPath(spellId)
|
|
local icon = HMGT_SpellData and HMGT_SpellData.GetSpellIcon and HMGT_SpellData.GetSpellIcon(spellId)
|
|
if not icon or icon == "" then
|
|
icon = "Interface\\Icons\\INV_Misc_QuestionMark"
|
|
end
|
|
return icon
|
|
end
|
|
|
|
local function SpellLabel(entry)
|
|
local spellId = tonumber(entry and entry.spellId) or 0
|
|
return tostring(entry and entry.name or GetSpellNameById(spellId) or ("Spell " .. spellId))
|
|
end
|
|
|
|
local function SpellDesc(entry)
|
|
local cooldown = tonumber(HMGT_SpellData and HMGT_SpellData.GetBaseCooldown and HMGT_SpellData.GetBaseCooldown(entry)) or tonumber(entry and entry.cooldown) or 0
|
|
local specs = {}
|
|
if type(entry and entry.specs) == "table" then
|
|
for _, spec in ipairs(entry.specs) do
|
|
specs[#specs + 1] = tostring(spec)
|
|
end
|
|
end
|
|
return table.concat({
|
|
string.format("SpellID: %d", tonumber(entry and entry.spellId) or 0),
|
|
string.format("%s: %s", L["OPT_TRACKER_CATEGORIES"] or "Categories", GetCategoryLabel(entry and entry.category or "utility")),
|
|
string.format("CD: %ss", cooldown),
|
|
#specs > 0 and ("Specs: " .. table.concat(specs, ", ")) or "Specs: All",
|
|
}, " | ")
|
|
end
|
|
|
|
local function GetOrderedValues(preferredOrder, availableMap)
|
|
local ordered = {}
|
|
local seen = {}
|
|
|
|
for _, key in ipairs(preferredOrder or {}) do
|
|
if availableMap[key] then
|
|
ordered[#ordered + 1] = key
|
|
seen[key] = true
|
|
end
|
|
end
|
|
|
|
local extras = {}
|
|
for key in pairs(availableMap or {}) do
|
|
if not seen[key] then
|
|
extras[#extras + 1] = key
|
|
end
|
|
end
|
|
table.sort(extras)
|
|
for _, key in ipairs(extras) do
|
|
ordered[#ordered + 1] = key
|
|
end
|
|
|
|
return ordered
|
|
end
|
|
|
|
local function GetSpellFilterState(filterKey)
|
|
HMGT._genericTrackerSpellFilters = HMGT._genericTrackerSpellFilters or {}
|
|
local key = tostring(filterKey or "default")
|
|
HMGT._genericTrackerSpellFilters[key] = HMGT._genericTrackerSpellFilters[key] or {
|
|
search = "",
|
|
enabledOnly = false,
|
|
}
|
|
return HMGT._genericTrackerSpellFilters[key]
|
|
end
|
|
|
|
local function BuildSpellBrowserArgs(config)
|
|
config = type(config) == "table" and config or {}
|
|
|
|
local filterKey = tostring(config.filterKey or "default")
|
|
local emptyText = tostring(config.emptyText or (L["OPT_TRACKERS_EMPTY"] or "No tracked spells available."))
|
|
local spellDescription = config.spellDescription or SpellDesc
|
|
local applyChanges = config.applyChanges or function()
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
local pool = {}
|
|
|
|
if type(config.poolProvider) == "function" then
|
|
pool = config.poolProvider() or {}
|
|
elseif type(config.pool) == "table" then
|
|
pool = config.pool
|
|
end
|
|
|
|
if type(config.isSpellEnabled) ~= "function" or type(config.setSpellEnabled) ~= "function" then
|
|
return {
|
|
missing = {
|
|
type = "description",
|
|
order = 1,
|
|
width = "full",
|
|
name = emptyText,
|
|
},
|
|
}
|
|
end
|
|
|
|
local browserClassSpells = {}
|
|
local entryBySpellId = {}
|
|
|
|
for _, entry in ipairs(pool) do
|
|
for _, classToken in ipairs(entry.classes or {}) do
|
|
browserClassSpells[classToken] = browserClassSpells[classToken] or {}
|
|
local category = tostring(entry.category or "utility")
|
|
browserClassSpells[classToken][category] = browserClassSpells[classToken][category] or {}
|
|
|
|
local duplicate = false
|
|
for _, existing in ipairs(browserClassSpells[classToken][category]) do
|
|
if existing.spellId == entry.spellId then
|
|
duplicate = true
|
|
break
|
|
end
|
|
end
|
|
if not duplicate then
|
|
browserClassSpells[classToken][category][#browserClassSpells[classToken][category] + 1] = entry
|
|
end
|
|
end
|
|
local spellId = tonumber(entry and entry.spellId)
|
|
if spellId and spellId > 0 then
|
|
entryBySpellId[spellId] = entry
|
|
end
|
|
end
|
|
|
|
local classOrder = GetOrderedValues(HMGT_SpellData and HMGT_SpellData.ClassOrder or {}, browserClassSpells)
|
|
if #classOrder == 0 then
|
|
return {
|
|
missing = {
|
|
type = "description",
|
|
order = 1,
|
|
width = "full",
|
|
name = emptyText,
|
|
},
|
|
}
|
|
end
|
|
|
|
local function IsEntryVisible(entry, classToken, category)
|
|
local spellId = tonumber(entry and entry.spellId)
|
|
if not spellId or spellId <= 0 then
|
|
return false
|
|
end
|
|
|
|
local filterState = GetSpellFilterState(filterKey)
|
|
if filterState.enabledOnly and not config.isSpellEnabled(spellId, entry) then
|
|
return false
|
|
end
|
|
|
|
local search = NormalizeSearchText(filterState.search)
|
|
if search == "" then
|
|
return true
|
|
end
|
|
|
|
local haystack = table.concat({
|
|
tostring(entry.name or GetSpellNameById(spellId) or ""),
|
|
tostring(spellId),
|
|
tostring(LocalizedClassName(classToken)),
|
|
tostring(GetCategoryLabel(category)),
|
|
}, " "):lower()
|
|
|
|
return haystack:find(search, 1, true) ~= nil
|
|
end
|
|
|
|
local function CollectVisibleSpellIds(classToken, category)
|
|
local ids = {}
|
|
local categories = {}
|
|
|
|
if category then
|
|
categories[1] = category
|
|
else
|
|
categories = GetOrderedValues(HMGT_SpellData and HMGT_SpellData.CategoryOrder or {}, browserClassSpells[classToken] or {})
|
|
end
|
|
|
|
for _, currentCategory in ipairs(categories) do
|
|
for _, entry in ipairs((browserClassSpells[classToken] and browserClassSpells[classToken][currentCategory]) or {}) do
|
|
if IsEntryVisible(entry, classToken, currentCategory) then
|
|
ids[#ids + 1] = tonumber(entry.spellId)
|
|
end
|
|
end
|
|
end
|
|
|
|
return ids
|
|
end
|
|
|
|
local function CountVisible(classToken, category)
|
|
local total = 0
|
|
local enabled = 0
|
|
|
|
for _, spellId in ipairs(CollectVisibleSpellIds(classToken, category)) do
|
|
total = total + 1
|
|
if config.isSpellEnabled(spellId, entryBySpellId[spellId]) then
|
|
enabled = enabled + 1
|
|
end
|
|
end
|
|
return total, enabled
|
|
end
|
|
|
|
local function CountAllVisible()
|
|
local total = 0
|
|
local enabled = 0
|
|
for _, classToken in ipairs(classOrder) do
|
|
local classTotal, classEnabled = CountVisible(classToken)
|
|
total = total + classTotal
|
|
enabled = enabled + classEnabled
|
|
end
|
|
return total, enabled
|
|
end
|
|
|
|
local function SetSpellIdsEnabled(spellIds, value)
|
|
for _, spellId in ipairs(spellIds) do
|
|
config.setSpellEnabled(spellId, value, entryBySpellId[spellId])
|
|
end
|
|
applyChanges()
|
|
end
|
|
|
|
local browserArgs = {
|
|
header = {
|
|
type = "header",
|
|
order = 1,
|
|
name = L["OPT_SPELL_BROWSER"] or "Spell Browser",
|
|
},
|
|
info = {
|
|
type = "description",
|
|
order = 2,
|
|
width = "full",
|
|
name = function()
|
|
local total, enabled = CountAllVisible()
|
|
if type(config.infoText) == "function" then
|
|
return config.infoText(total, enabled)
|
|
end
|
|
return string.format(
|
|
"%s\n\n|cffffd100%s|r: %d\n|cffffd100%s|r: %d",
|
|
L["OPT_SPELL_BROWSER_DESC"] or "Filter tracked spells by name or Spell ID and apply quick actions to the visible results.",
|
|
L["OPT_SPELLS_VISIBLE"] or "Visible spells",
|
|
total,
|
|
L["OPT_SPELLS_ENABLED_COUNT"] or "Enabled",
|
|
enabled
|
|
)
|
|
end,
|
|
},
|
|
search = {
|
|
type = "input",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_FILTER_SEARCH"] or "Search",
|
|
desc = L["OPT_FILTER_SEARCH_DESC"] or "Search by spell name or Spell ID",
|
|
get = function()
|
|
return GetSpellFilterState(filterKey).search or ""
|
|
end,
|
|
set = function(_, val)
|
|
GetSpellFilterState(filterKey).search = val or ""
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
enabledOnly = {
|
|
type = "toggle",
|
|
order = 4,
|
|
width = "full",
|
|
name = L["OPT_FILTER_ENABLED_ONLY"] or "Show enabled spells only",
|
|
get = function()
|
|
return GetSpellFilterState(filterKey).enabledOnly == true
|
|
end,
|
|
set = function(_, val)
|
|
GetSpellFilterState(filterKey).enabledOnly = val and true or false
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
selectVisible = {
|
|
type = "execute",
|
|
order = 5,
|
|
width = "full",
|
|
name = L["OPT_SELECT_VISIBLE"] or "Select visible",
|
|
func = function()
|
|
local spellIds = {}
|
|
for _, classToken in ipairs(classOrder) do
|
|
for _, spellId in ipairs(CollectVisibleSpellIds(classToken)) do
|
|
spellIds[#spellIds + 1] = spellId
|
|
end
|
|
end
|
|
SetSpellIdsEnabled(spellIds, true)
|
|
end,
|
|
},
|
|
deselectVisible = {
|
|
type = "execute",
|
|
order = 6,
|
|
width = "full",
|
|
name = L["OPT_DESELECT_VISIBLE"] or "Deselect visible",
|
|
func = function()
|
|
local spellIds = {}
|
|
for _, classToken in ipairs(classOrder) do
|
|
for _, spellId in ipairs(CollectVisibleSpellIds(classToken)) do
|
|
spellIds[#spellIds + 1] = spellId
|
|
end
|
|
end
|
|
SetSpellIdsEnabled(spellIds, false)
|
|
end,
|
|
},
|
|
resetFilters = {
|
|
type = "execute",
|
|
order = 7,
|
|
width = "full",
|
|
name = L["OPT_FILTER_RESET"] or "Reset filters",
|
|
func = function()
|
|
local filterState = GetSpellFilterState(filterKey)
|
|
filterState.search = ""
|
|
filterState.enabledOnly = false
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
}
|
|
|
|
local function BuildClassArgs(classToken)
|
|
local categories = browserClassSpells[classToken] or {}
|
|
local categoryOrder = GetOrderedValues(HMGT_SpellData and HMGT_SpellData.CategoryOrder or {}, categories)
|
|
local classArgs = {
|
|
browserHeader = {
|
|
type = "header",
|
|
order = 1,
|
|
name = L["OPT_SPELL_BROWSER"] or "Spell Browser",
|
|
},
|
|
search = {
|
|
type = "input",
|
|
order = 2,
|
|
width = "full",
|
|
name = L["OPT_FILTER_SEARCH"] or "Search",
|
|
desc = L["OPT_FILTER_SEARCH_DESC"] or "Search by spell name or Spell ID",
|
|
get = function()
|
|
return GetSpellFilterState(filterKey).search or ""
|
|
end,
|
|
set = function(_, val)
|
|
GetSpellFilterState(filterKey).search = val or ""
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
enabledOnly = {
|
|
type = "toggle",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_FILTER_ENABLED_ONLY"] or "Show enabled spells only",
|
|
get = function()
|
|
return GetSpellFilterState(filterKey).enabledOnly == true
|
|
end,
|
|
set = function(_, val)
|
|
GetSpellFilterState(filterKey).enabledOnly = val and true or false
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
resetFilters = {
|
|
type = "execute",
|
|
order = 4,
|
|
width = "full",
|
|
name = L["OPT_FILTER_RESET"] or "Reset filters",
|
|
func = function()
|
|
local filterState = GetSpellFilterState(filterKey)
|
|
filterState.search = ""
|
|
filterState.enabledOnly = false
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
selectionHeader = {
|
|
type = "header",
|
|
order = 5,
|
|
name = L["OPT_SELECTION"] or "Selection",
|
|
},
|
|
summary = {
|
|
type = "description",
|
|
order = 6,
|
|
width = "full",
|
|
name = function()
|
|
local total, enabled = CountVisible(classToken)
|
|
return string.format(
|
|
"|cffffd100%s|r: %d |cffffd100%s|r: %d",
|
|
L["OPT_SPELLS_VISIBLE"] or "Visible spells",
|
|
total,
|
|
L["OPT_SPELLS_ENABLED_COUNT"] or "Enabled",
|
|
enabled
|
|
)
|
|
end,
|
|
},
|
|
selectVisible = {
|
|
type = "execute",
|
|
order = 7,
|
|
width = "full",
|
|
name = L["OPT_SELECT_VISIBLE"] or "Select visible",
|
|
func = function()
|
|
SetSpellIdsEnabled(CollectVisibleSpellIds(classToken), true)
|
|
end,
|
|
},
|
|
deselectVisible = {
|
|
type = "execute",
|
|
order = 8,
|
|
width = "full",
|
|
name = L["OPT_DESELECT_VISIBLE"] or "Deselect visible",
|
|
func = function()
|
|
SetSpellIdsEnabled(CollectVisibleSpellIds(classToken), false)
|
|
end,
|
|
},
|
|
}
|
|
local categoryOrderIndex = 10
|
|
for _, category in ipairs(categoryOrder) do
|
|
if categories[category] then
|
|
local categoryArgs = {
|
|
summary = {
|
|
type = "description",
|
|
order = 1,
|
|
width = "full",
|
|
name = function()
|
|
local total, enabled = CountVisible(classToken, category)
|
|
return string.format(
|
|
"|cffffd100%s|r: %d |cffffd100%s|r: %d",
|
|
L["OPT_SPELLS_VISIBLE"] or "Visible spells",
|
|
total,
|
|
L["OPT_SPELLS_ENABLED_COUNT"] or "Enabled",
|
|
enabled
|
|
)
|
|
end,
|
|
},
|
|
}
|
|
|
|
local spellOrder = 2
|
|
for _, entry in ipairs(categories[category]) do
|
|
local spellId = tonumber(entry.spellId)
|
|
local spellIcon = GetSpellIconPath(spellId)
|
|
categoryArgs["spell_" .. tostring(spellId)] = {
|
|
type = "toggle",
|
|
order = spellOrder,
|
|
name = SpellLabel(entry),
|
|
image = spellIcon,
|
|
imageCoords = { 0.07, 0.93, 0.07, 0.93 },
|
|
desc = spellDescription(entry),
|
|
hidden = function()
|
|
return not IsEntryVisible(entry, classToken, category)
|
|
end,
|
|
get = function()
|
|
return config.isSpellEnabled(spellId, entry)
|
|
end,
|
|
set = function(_, val)
|
|
config.setSpellEnabled(spellId, val, entry)
|
|
applyChanges()
|
|
end,
|
|
}
|
|
spellOrder = spellOrder + 1
|
|
end
|
|
|
|
classArgs["cat_" .. category] = {
|
|
type = "group",
|
|
order = categoryOrderIndex,
|
|
inline = true,
|
|
name = " ",
|
|
hidden = function()
|
|
local total = CountVisible(classToken, category)
|
|
return total == 0
|
|
end,
|
|
args = {
|
|
header = {
|
|
type = "header",
|
|
order = 1,
|
|
name = GetCategoryLabel(category),
|
|
},
|
|
},
|
|
}
|
|
for key, value in pairs(categoryArgs) do
|
|
classArgs["cat_" .. category].args[key] = value
|
|
end
|
|
categoryOrderIndex = categoryOrderIndex + 1
|
|
end
|
|
end
|
|
|
|
return classArgs
|
|
end
|
|
|
|
for index, classToken in ipairs(classOrder) do
|
|
browserArgs["class_" .. classToken] = {
|
|
type = "group",
|
|
order = 10 + index,
|
|
hidden = function()
|
|
return CountVisible(classToken) == 0
|
|
end,
|
|
name = function()
|
|
local total, enabled = CountVisible(classToken)
|
|
return string.format("%s (%d/%d)", LocalizedClassName(classToken), enabled, total)
|
|
end,
|
|
args = BuildClassArgs(classToken),
|
|
}
|
|
end
|
|
|
|
return browserArgs
|
|
end
|
|
|
|
local function GetAllTrackedSpellPool()
|
|
local categoryMap = {}
|
|
for _, tracker in ipairs(GetSortedTrackers()) do
|
|
for _, category in ipairs(tracker.categories or {}) do
|
|
categoryMap[category] = true
|
|
end
|
|
end
|
|
|
|
local orderedCategories = GetOrderedValues(HMGT_SpellData and HMGT_SpellData.CategoryOrder or {}, categoryMap)
|
|
if HMGT_SpellData and type(HMGT_SpellData.GetSpellPoolForCategories) == "function" then
|
|
return HMGT_SpellData.GetSpellPoolForCategories(orderedCategories)
|
|
end
|
|
return {}
|
|
end
|
|
|
|
local function EntryMatchesTracker(entry, tracker)
|
|
if not entry or not tracker then
|
|
return false
|
|
end
|
|
if HMGT_SpellData and type(HMGT_SpellData.EntryMatchesCategories) == "function" then
|
|
return HMGT_SpellData.EntryMatchesCategories(entry, tracker.categories)
|
|
end
|
|
|
|
local trackerCategories = {}
|
|
for _, category in ipairs(tracker.categories or {}) do
|
|
trackerCategories[tostring(category)] = true
|
|
end
|
|
|
|
if trackerCategories[tostring(entry.category or "utility")] then
|
|
return true
|
|
end
|
|
|
|
for _, tag in ipairs(entry.trackerTags or {}) do
|
|
if trackerCategories[tostring(tag)] then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function GetApplicableTrackersForSpell(entry)
|
|
local trackers = {}
|
|
for _, tracker in ipairs(GetSortedTrackers()) do
|
|
if EntryMatchesTracker(entry, tracker) then
|
|
trackers[#trackers + 1] = tracker
|
|
end
|
|
end
|
|
return trackers
|
|
end
|
|
|
|
local function GetApplicableTrackerLabels(entry)
|
|
local labels = {}
|
|
for _, tracker in ipairs(GetApplicableTrackersForSpell(entry)) do
|
|
labels[#labels + 1] = GetTrackerLabel(tracker)
|
|
end
|
|
return labels
|
|
end
|
|
|
|
local function IsGlobalSpellEnabled(spellId, entry)
|
|
local trackers = GetApplicableTrackersForSpell(entry)
|
|
if #trackers == 0 then
|
|
return false
|
|
end
|
|
for _, tracker in ipairs(trackers) do
|
|
if tracker.enabledSpells[spellId] == false then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function SetGlobalSpellEnabled(spellId, value, entry)
|
|
for _, tracker in ipairs(GetApplicableTrackersForSpell(entry)) do
|
|
tracker.enabledSpells[spellId] = value
|
|
end
|
|
end
|
|
|
|
local function BuildGlobalSpellDescription(entry)
|
|
local base = SpellDesc(entry)
|
|
local labels = GetApplicableTrackerLabels(entry)
|
|
if #labels == 0 then
|
|
return base
|
|
end
|
|
return string.format("%s | %s: %s", base, L["OPT_TRACKERS"] or "Tracker Bars", table.concat(labels, ", "))
|
|
end
|
|
|
|
local function BuildGlobalSpellBrowserArgs()
|
|
return BuildSpellBrowserArgs({
|
|
filterKey = "global-tracked-spells",
|
|
emptyText = L["OPT_TRACKED_SPELLS_EMPTY"] or "No spells are currently tracked by your tracker bars.",
|
|
poolProvider = GetAllTrackedSpellPool,
|
|
isSpellEnabled = IsGlobalSpellEnabled,
|
|
setSpellEnabled = SetGlobalSpellEnabled,
|
|
spellDescription = BuildGlobalSpellDescription,
|
|
infoText = function(total, enabled)
|
|
return string.format(
|
|
"%s\n\n%s\n\n|cffffd100%s|r: %d\n|cffffd100%s|r: %d",
|
|
L["OPT_SPELL_BROWSER_DESC"] or "Filter tracked spells by name or Spell ID and apply quick actions to the visible results.",
|
|
L["OPT_TRACKED_SPELLS_DESC"] or "Changes here apply to all tracker bars that use the spell's categories.",
|
|
L["OPT_SPELLS_VISIBLE"] or "Visible spells",
|
|
total,
|
|
L["OPT_SPELLS_ENABLED_COUNT"] or "Enabled",
|
|
enabled
|
|
)
|
|
end,
|
|
applyChanges = function()
|
|
TriggerTrackerUpdate(false)
|
|
end,
|
|
})
|
|
end
|
|
|
|
local function BuildTrackerOverviewArgs()
|
|
return {
|
|
description = {
|
|
type = "description",
|
|
order = 1,
|
|
width = "full",
|
|
name = function()
|
|
local trackers = GetSortedTrackers()
|
|
local names = {}
|
|
for _, tracker in ipairs(trackers) do
|
|
names[#names + 1] = GetTrackerLabel(tracker)
|
|
end
|
|
|
|
local body = L["OPT_TRACKERS_DESC"] or "Create tracker bars and bind them to one or more spell categories."
|
|
if #names == 0 then
|
|
return string.format("%s\n\n%s", body, L["OPT_TRACKERS_EMPTY"] or "No tracker bars configured yet.")
|
|
end
|
|
return string.format("%s\n\n%s (%d): %s", body, L["OPT_TRACKERS"] or "Tracker Bars", #trackers, table.concat(names, ", "))
|
|
end,
|
|
},
|
|
addTracker = {
|
|
type = "execute",
|
|
order = 2,
|
|
width = "full",
|
|
name = L["OPT_ADD_TRACKER"] or "Add tracker",
|
|
func = function()
|
|
local nextId = HMGT:GetNextTrackerId()
|
|
local tracker = HMGT:CreateTrackerConfig(nextId, {
|
|
name = string.format("%s %d", L["OPT_TRACKER"] or "Tracker", nextId),
|
|
})
|
|
HMGT.db.profile.trackers = HMGT.db.profile.trackers or {}
|
|
HMGT.db.profile.trackers[#HMGT.db.profile.trackers + 1] = tracker
|
|
TriggerTrackerUpdate(true)
|
|
end,
|
|
},
|
|
}
|
|
end
|
|
|
|
local function BuildTrackerGroup(trackerId, order)
|
|
local function s()
|
|
return GetTrackerSettings(trackerId)
|
|
end
|
|
|
|
local function SetCategoryEnabled(category, enabled)
|
|
local tracker = s()
|
|
if not tracker then
|
|
return
|
|
end
|
|
|
|
local selected = {}
|
|
for _, existing in ipairs(tracker.categories or {}) do
|
|
selected[existing] = true
|
|
end
|
|
|
|
if enabled then
|
|
selected[category] = true
|
|
else
|
|
local count = 0
|
|
for _ in pairs(selected) do
|
|
count = count + 1
|
|
end
|
|
if count <= 1 then
|
|
return
|
|
end
|
|
selected[category] = nil
|
|
end
|
|
|
|
local ordered = {}
|
|
local seen = {}
|
|
for _, key in ipairs(HMGT_SpellData and HMGT_SpellData.CategoryOrder or {}) do
|
|
if selected[key] then
|
|
ordered[#ordered + 1] = key
|
|
seen[key] = true
|
|
end
|
|
end
|
|
local extras = {}
|
|
for key in pairs(selected) do
|
|
if not seen[key] then
|
|
extras[#extras + 1] = key
|
|
end
|
|
end
|
|
table.sort(extras)
|
|
for _, key in ipairs(extras) do
|
|
ordered[#ordered + 1] = key
|
|
end
|
|
|
|
tracker.categories = ordered
|
|
TriggerTrackerUpdate(true)
|
|
end
|
|
|
|
local function RemoveTracker()
|
|
local profileTrackers = HMGT.db.profile.trackers or {}
|
|
local removedAnchorKey = HMGT:GetTrackerAnchorKey(trackerId)
|
|
|
|
for index = #profileTrackers, 1, -1 do
|
|
if tonumber(profileTrackers[index].id) == tonumber(trackerId) then
|
|
table.remove(profileTrackers, index)
|
|
break
|
|
end
|
|
end
|
|
|
|
for _, tracker in ipairs(profileTrackers) do
|
|
if tracker.anchorTo == removedAnchorKey then
|
|
tracker.anchorTo = "UIParent"
|
|
tracker.anchorCustom = ""
|
|
end
|
|
end
|
|
|
|
HMGT:RefreshFrameAnchors(true)
|
|
TriggerTrackerUpdate(true)
|
|
end
|
|
|
|
local function GetRemoveTrackerConfirmationText()
|
|
local tracker = s()
|
|
local label = tracker and GetTrackerLabel(tracker) or (L["OPT_TRACKER"] or "Tracker")
|
|
return string.format(
|
|
L["OPT_REMOVE_TRACKER_CONFIRM"] or 'Really remove tracker "%s"?',
|
|
tostring(label)
|
|
)
|
|
end
|
|
|
|
return {
|
|
type = "group",
|
|
order = order,
|
|
childGroups = "tab",
|
|
name = function()
|
|
local tracker = s()
|
|
return tracker and GetTrackerLabel(tracker) or (L["OPT_TRACKER"] or "Tracker")
|
|
end,
|
|
args = {
|
|
header = {
|
|
type = "header",
|
|
order = 1,
|
|
name = function()
|
|
local tracker = s()
|
|
return tracker and GetTrackerLabel(tracker) or (L["OPT_TRACKER"] or "Tracker")
|
|
end,
|
|
},
|
|
summaryGroup = {
|
|
type = "group",
|
|
order = 2,
|
|
inline = true,
|
|
name = " ",
|
|
args = {
|
|
summary = {
|
|
type = "description",
|
|
order = 1,
|
|
width = "full",
|
|
name = function()
|
|
local tracker = s()
|
|
return tracker and GetTrackerSummaryText(tracker) or (L["OPT_TRACKERS_EMPTY"] or "No tracker selected.")
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
removeTracker = {
|
|
type = "execute",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_REMOVE_TRACKER"] or "Remove tracker",
|
|
confirm = GetRemoveTrackerConfirmationText,
|
|
func = RemoveTracker,
|
|
},
|
|
mode = {
|
|
type = "group",
|
|
order = 10,
|
|
name = L["OPT_UI_GROUP_MODE"] or "Mode",
|
|
args = {
|
|
name = {
|
|
type = "input",
|
|
order = 1,
|
|
width = "full",
|
|
name = L["OPT_TRACKER_NAME"] or "Tracker name",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.name or ""
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
local trimmed = tostring(val or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|
if trimmed == "" then
|
|
trimmed = string.format("%s %d", L["OPT_TRACKER"] or "Tracker", tonumber(tracker.id) or 0)
|
|
end
|
|
tracker.name = trimmed
|
|
NotifyOptionsChanged()
|
|
end
|
|
end,
|
|
},
|
|
trackerType = {
|
|
type = "select",
|
|
order = 2,
|
|
width = "full",
|
|
name = L["OPT_TRACKER_TYPE"] or "Tracker type",
|
|
desc = L["OPT_TRACKER_TYPE_DESC"] or "Choose whether this tracker uses one shared frame or separate frames per group member.",
|
|
values = TRACKER_TYPE_VALUES,
|
|
get = function()
|
|
local tracker = s()
|
|
return (tracker and tracker.trackerType) or "normal"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.trackerType = (val == "group") and "group" or "normal"
|
|
tracker.perGroupMember = tracker.trackerType == "group"
|
|
if tracker.trackerType ~= "group" then
|
|
tracker.attachToPartyFrame = false
|
|
end
|
|
NotifyOptionsChanged()
|
|
RefreshAnchors(true)
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showBar = {
|
|
type = "select",
|
|
order = 2.5,
|
|
width = "full",
|
|
name = L["OPT_DISPLAY_MODE"] or "Display mode",
|
|
desc = L["OPT_DISPLAY_MODE_DESC"] or "Show as progress bars or icons",
|
|
values = {
|
|
bar = L["OPT_DISPLAY_BAR"] or "Progress bars",
|
|
icon = L["OPT_DISPLAY_ICON"] or "Icons",
|
|
},
|
|
get = function()
|
|
local tracker = s()
|
|
return (tracker and tracker.showBar) and "bar" or "icon"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showBar = (val == "bar")
|
|
if tracker.showBar and (tracker.growDirection == "LEFT" or tracker.growDirection == "RIGHT") then
|
|
tracker.growDirection = "DOWN"
|
|
end
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
enabled = {
|
|
type = "toggle",
|
|
order = 3,
|
|
width = "half",
|
|
name = L["OPT_ENABLED"] or "Enabled",
|
|
desc = L["OPT_ENABLED_DESC"] or "Enable or disable this tracker",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.enabled ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.enabled = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
includeSelfFrame = {
|
|
type = "toggle",
|
|
order = 4,
|
|
width = "full",
|
|
name = L["OPT_INCLUDE_SELF_FRAME"] or "Create a frame for your own player too",
|
|
desc = L["OPT_INCLUDE_SELF_FRAME_DESC"] or "Also provision a per-member tracker frame for your own player.",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker
|
|
or not IsGroupTracker(tracker)
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.includeSelfFrame == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.includeSelfFrame = val and true or false
|
|
NotifyOptionsChanged()
|
|
RefreshAnchors(true)
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
categories = {
|
|
type = "multiselect",
|
|
order = 5,
|
|
width = "full",
|
|
name = L["OPT_TRACKER_CATEGORIES"] or "Categories",
|
|
desc = L["OPT_TRACKER_CATEGORIES_DESC"] or "Select which spell categories this tracker should display.",
|
|
values = function()
|
|
return GetTrackerCategoryValues()
|
|
end,
|
|
get = function(_, key)
|
|
local tracker = s()
|
|
if not tracker then
|
|
return false
|
|
end
|
|
for _, category in ipairs(tracker.categories or {}) do
|
|
if category == key then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end,
|
|
set = function(_, key, val)
|
|
SetCategoryEnabled(key, val)
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
visibility = {
|
|
type = "group",
|
|
order = 20,
|
|
name = L["OPT_UI_GROUP_VISIBILITY"] or "Visibility",
|
|
args = {
|
|
showInSolo = {
|
|
type = "toggle",
|
|
order = 1,
|
|
name = L["OPT_SHOW_SOLO"] or "Show when solo",
|
|
desc = L["OPT_SHOW_SOLO_DESC"] or "Show this tracker when not in a group",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showInSolo ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showInSolo = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showInGroup = {
|
|
type = "toggle",
|
|
order = 2,
|
|
name = L["OPT_SHOW_GROUP"] or "Show in group",
|
|
desc = L["OPT_SHOW_GROUP_DESC"] or "Show this tracker in a party",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showInGroup ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showInGroup = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showInRaid = {
|
|
type = "toggle",
|
|
order = 3,
|
|
name = L["OPT_SHOW_RAID"] or "Show in raid",
|
|
desc = L["OPT_SHOW_RAID_DESC"] or "Show this tracker in a raid group",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showInRaid ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showInRaid = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showOnlyReady = {
|
|
type = "toggle",
|
|
order = 4,
|
|
width = "full",
|
|
name = L["OPT_SHOW_ONLY_READY"] or "Show only ready cooldowns",
|
|
desc = L["OPT_SHOW_ONLY_READY_DESC"] or "Only show entries that are currently ready",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showOnlyReady == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showOnlyReady = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
readySoonSec = {
|
|
type = "range",
|
|
order = 5,
|
|
min = 0,
|
|
max = 300,
|
|
step = 1,
|
|
width = "full",
|
|
name = L["OPT_READY_SOON_SEC"] or "Ready soon threshold (sec)",
|
|
desc = L["OPT_READY_SOON_SEC_DESC"] or "Show only cooldowns that are ready or below this remaining time (0 = disabled)",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.readySoonSec or 0
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.readySoonSec = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
roleFilter = {
|
|
type = "select",
|
|
order = 6,
|
|
name = L["OPT_ROLE_FILTER"] or "Role filter",
|
|
values = ROLE_FILTER_VALUES,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.roleFilter or "ALL"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.roleFilter = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
rangeCheck = {
|
|
type = "toggle",
|
|
order = 7,
|
|
name = L["OPT_RANGE_CHECK"] or "Range check",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.rangeCheck == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.rangeCheck = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
hideOutOfRange = {
|
|
type = "toggle",
|
|
order = 8,
|
|
name = L["OPT_HIDE_OOR"] or "Hide out of range",
|
|
disabled = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.rangeCheck ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.hideOutOfRange == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.hideOutOfRange = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
outOfRangeAlpha = {
|
|
type = "range",
|
|
order = 9,
|
|
min = 0.1,
|
|
max = 1,
|
|
step = 0.05,
|
|
name = L["OPT_OOR_ALPHA"] or "Out of range alpha",
|
|
disabled = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.rangeCheck ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.outOfRangeAlpha or 0.4
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.outOfRangeAlpha = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
placement = {
|
|
type = "group",
|
|
order = 30,
|
|
name = L["OPT_UI_GROUP_PLACEMENT"] or "Placement",
|
|
args = {
|
|
locked = {
|
|
type = "toggle",
|
|
order = 1,
|
|
name = L["OPT_LOCKED"] or "Lock frame",
|
|
desc = L["OPT_LOCKED_DESC"] or "Prevent the frame from being moved",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.locked == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.locked = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
growDirection = {
|
|
type = "select",
|
|
order = 2,
|
|
name = L["OPT_GROW_DIR"] or "Grow direction",
|
|
values = function()
|
|
local tracker = s()
|
|
if tracker and tracker.showBar then
|
|
return {
|
|
DOWN = L["OPT_GROW_DOWN"] or "Downward",
|
|
UP = L["OPT_GROW_UP"] or "Upward",
|
|
}
|
|
end
|
|
return {
|
|
DOWN = L["OPT_GROW_DOWN"] or "Downward",
|
|
UP = L["OPT_GROW_UP"] or "Upward",
|
|
LEFT = L["OPT_GROW_LEFT"] or "Leftward",
|
|
RIGHT = L["OPT_GROW_RIGHT"] or "Rightward",
|
|
}
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
if not tracker then
|
|
return "DOWN"
|
|
end
|
|
local dir = tracker.growDirection or "DOWN"
|
|
if tracker.showBar and (dir == "LEFT" or dir == "RIGHT") then
|
|
return "DOWN"
|
|
end
|
|
return dir
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.growDirection = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
attachToPartyFrame = {
|
|
type = "toggle",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_ATTACH_PARTY_FRAME"] or "Attach to Party Frame",
|
|
desc = L["OPT_ATTACH_PARTY_FRAME_DESC"] or "Anchor each group cooldown frame to its corresponding party unit frame",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or not IsGroupTracker(tracker)
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.attachToPartyFrame == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.attachToPartyFrame = val and true or false
|
|
NotifyOptionsChanged()
|
|
RefreshAnchors(true)
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
partyAttachSide = {
|
|
type = "select",
|
|
order = 4,
|
|
name = L["OPT_ATTACH_PARTY_SIDE"] or "Attach side",
|
|
values = {
|
|
LEFT = L["OPT_ATTACH_LEFT"] or "Left",
|
|
RIGHT = L["OPT_ATTACH_RIGHT"] or "Right",
|
|
},
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or not IsGroupTracker(tracker) or tracker.attachToPartyFrame ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.partyAttachSide or "RIGHT"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.partyAttachSide = val
|
|
RefreshAnchors(true)
|
|
end
|
|
end,
|
|
},
|
|
partyAttachOffsetX = {
|
|
type = "range",
|
|
order = 5,
|
|
min = -200,
|
|
max = 200,
|
|
step = 1,
|
|
name = function()
|
|
local tracker = s()
|
|
return string.format("%s: %s", L["OPT_ATTACH_PARTY_OFFSET_X"] or "Attach X offset", tostring(tracker and tracker.partyAttachOffsetX or 8))
|
|
end,
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or not IsGroupTracker(tracker) or tracker.attachToPartyFrame ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.partyAttachOffsetX or 8
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.partyAttachOffsetX = val
|
|
RefreshAnchors(true)
|
|
end
|
|
end,
|
|
},
|
|
partyAttachOffsetY = {
|
|
type = "range",
|
|
order = 6,
|
|
min = -200,
|
|
max = 200,
|
|
step = 1,
|
|
name = function()
|
|
local tracker = s()
|
|
return string.format("%s: %s", L["OPT_ATTACH_PARTY_OFFSET_Y"] or "Attach Y offset", tostring(tracker and tracker.partyAttachOffsetY or 0))
|
|
end,
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or not IsGroupTracker(tracker) or tracker.attachToPartyFrame ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.partyAttachOffsetY or 0
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.partyAttachOffsetY = val
|
|
RefreshAnchors(true)
|
|
end
|
|
end,
|
|
},
|
|
anchorTo = {
|
|
type = "select",
|
|
order = 7,
|
|
name = L["OPT_ANCHOR_TO"] or "Anchor to",
|
|
desc = L["OPT_ANCHOR_TO_DESC"] or "Attach this frame to another frame or to the screen",
|
|
hidden = function()
|
|
return IsPartyAttachMode(s())
|
|
end,
|
|
values = function()
|
|
local tracker = s()
|
|
return tracker and HMGT:GetAnchorTargetOptions(tracker.id, tracker.anchorTo) or {}
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
if not tracker then
|
|
return "UIParent"
|
|
end
|
|
local current = tracker.anchorTo or "UIParent"
|
|
local values = HMGT:GetAnchorTargetOptions(tracker.id, current)
|
|
if values[current] then
|
|
return current
|
|
end
|
|
return "CUSTOM"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
local selfAnchor = HMGT:GetTrackerAnchorKey(tracker.id)
|
|
if val == selfAnchor then
|
|
val = "UIParent"
|
|
end
|
|
if val ~= "CUSTOM" then
|
|
tracker.anchorCustom = tracker.anchorCustom or ""
|
|
end
|
|
tracker.anchorTo = val
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
anchorCustom = {
|
|
type = "input",
|
|
order = 8,
|
|
width = "full",
|
|
name = L["OPT_ANCHOR_CUSTOM_NAME"] or "Custom frame",
|
|
desc = L["OPT_ANCHOR_CUSTOM_NAME_DESC"] or "Global frame name, e.g. ElvUF_Player",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or IsPartyAttachMode(tracker) or (tracker.anchorTo or "UIParent") ~= "CUSTOM"
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.anchorCustom or ""
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.anchorCustom = tostring(val or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
anchorPoint = {
|
|
type = "select",
|
|
order = 9,
|
|
name = L["OPT_ANCHOR_POINT"] or "Anchor point",
|
|
desc = L["OPT_ANCHOR_POINT_DESC"] or "Point on this frame to use for anchoring",
|
|
values = ANCHOR_POINT_VALUES,
|
|
hidden = function()
|
|
return IsPartyAttachMode(s())
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.anchorPoint or "TOPLEFT"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.anchorPoint = val
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
anchorRelativePoint = {
|
|
type = "select",
|
|
order = 10,
|
|
name = L["OPT_ANCHOR_REL_POINT"] or "Relative point",
|
|
desc = L["OPT_ANCHOR_REL_POINT_DESC"] or "Point on the target frame to anchor to",
|
|
values = ANCHOR_POINT_VALUES,
|
|
hidden = function()
|
|
return IsPartyAttachMode(s())
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.anchorRelPoint or "TOPLEFT"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.anchorRelPoint = val
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
anchorX = {
|
|
type = "range",
|
|
order = 11,
|
|
min = -2000,
|
|
max = 2000,
|
|
step = 1,
|
|
name = L["OPT_ANCHOR_X"] or "X offset",
|
|
hidden = function()
|
|
return IsPartyAttachMode(s())
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
if not tracker then
|
|
return 0
|
|
end
|
|
if tracker.anchorX ~= nil then
|
|
return tracker.anchorX
|
|
end
|
|
return tracker.posX or 0
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.anchorX = val
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
anchorY = {
|
|
type = "range",
|
|
order = 12,
|
|
min = -2000,
|
|
max = 2000,
|
|
step = 1,
|
|
name = L["OPT_ANCHOR_Y"] or "Y offset",
|
|
hidden = function()
|
|
return IsPartyAttachMode(s())
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
if not tracker then
|
|
return 0
|
|
end
|
|
if tracker.anchorY ~= nil then
|
|
return tracker.anchorY
|
|
end
|
|
return tracker.posY or 0
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.anchorY = val
|
|
RefreshAnchors(false)
|
|
end
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
layout = {
|
|
type = "group",
|
|
order = 40,
|
|
name = L["OPT_UI_GROUP_LAYOUT"] or "Layout",
|
|
args = {
|
|
width = {
|
|
type = "range",
|
|
order = 1,
|
|
min = 100,
|
|
max = 600,
|
|
step = 1,
|
|
name = L["OPT_WIDTH"] or "Width (bars)",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.width or 250
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.width = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
barHeight = {
|
|
type = "range",
|
|
order = 2,
|
|
min = 10,
|
|
max = 60,
|
|
step = 1,
|
|
name = L["OPT_BAR_HEIGHT"] or "Bar height",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.barHeight or 20
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.barHeight = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
barSpacing = {
|
|
type = "range",
|
|
order = 3,
|
|
min = 0,
|
|
max = 20,
|
|
step = 1,
|
|
name = L["OPT_BAR_SPACING"] or "Bar spacing",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar ~= true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.barSpacing or 2
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.barSpacing = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
barTexture = {
|
|
type = "select",
|
|
order = 4,
|
|
name = L["OPT_BAR_TEXTURE"] or "Texture",
|
|
desc = L["OPT_BAR_TEXTURE_DESC"] or "Texture of the progress bar",
|
|
dialogControl = "LSM30_Statusbar",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar ~= true
|
|
end,
|
|
values = AceGUIWidgetLSMlists and AceGUIWidgetLSMlists.statusbar or (LSM and LSM:HashTable("statusbar")) or {},
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.barTexture or "Blizzard"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.barTexture = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
iconSize = {
|
|
type = "range",
|
|
order = 5,
|
|
min = 12,
|
|
max = 100,
|
|
step = 1,
|
|
name = L["OPT_ICON_SIZE"] or "Icon size",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.iconSize or 32
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.iconSize = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
iconSpacing = {
|
|
type = "range",
|
|
order = 6,
|
|
min = 0,
|
|
max = 20,
|
|
step = 1,
|
|
name = L["OPT_ICON_SPACING"] or "Icon spacing",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.iconSpacing or 2
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.iconSpacing = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
iconCols = {
|
|
type = "range",
|
|
order = 7,
|
|
min = 1,
|
|
max = 20,
|
|
step = 1,
|
|
name = L["OPT_ICON_COLS"] or "Icons per row",
|
|
desc = L["OPT_ICON_COLS_DESC"] or "Number of icons per row (DOWN/UP) or per column (LEFT/RIGHT)",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.iconCols or 6
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.iconCols = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
iconOverlay = {
|
|
type = "select",
|
|
order = 8,
|
|
name = L["OPT_ICON_OVERLAY"] or "Cooldown display",
|
|
desc = L["OPT_ICON_OVERLAY_DESC"] or "How to show remaining cooldown on icons",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
values = {
|
|
sweep = L["OPT_ICON_OVERLAY_SWEEP"] or "Cooldown sweep",
|
|
timer = L["OPT_ICON_OVERLAY_TIMER"] or "Text timer (MM:SS)",
|
|
},
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.iconOverlay or "sweep"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.iconOverlay = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
textAnchor = {
|
|
type = "select",
|
|
order = 9,
|
|
name = L["OPT_TEXT_ANCHOR"] or "Text position",
|
|
desc = L["OPT_TEXT_ANCHOR_DESC"] or "Where to show name and timer relative to the icon",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
values = {
|
|
onIcon = L["OPT_ANCHOR_ON_ICON"] or "On icon (overlay)",
|
|
above = L["OPT_ANCHOR_ABOVE"] or "Above icon",
|
|
below = L["OPT_ANCHOR_BELOW"] or "Below icon",
|
|
left = L["OPT_ANCHOR_LEFT"] or "Left of icon",
|
|
right = L["OPT_ANCHOR_RIGHT"] or "Right of icon",
|
|
},
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.textAnchor or "below"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.textAnchor = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showReadyText = {
|
|
type = "toggle",
|
|
order = 10,
|
|
name = L["OPT_SHOW_READY_TEXT"] or "Show ready text",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showReadyText ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showReadyText = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showChargesOnIcon = {
|
|
type = "toggle",
|
|
order = 11,
|
|
name = L["OPT_SHOW_CHARGES_ON_ICON"] or "Show charges on icon",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showChargesOnIcon == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showChargesOnIcon = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
showRemainingOnIcon = {
|
|
type = "toggle",
|
|
order = 12,
|
|
name = L["OPT_SHOW_REMAINING_ON_ICON"] or "Show remaining time on icon",
|
|
hidden = function()
|
|
local tracker = s()
|
|
return not tracker or tracker.showBar == true or (tracker.iconOverlay or "sweep") == "sweep"
|
|
end,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showRemainingOnIcon == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showRemainingOnIcon = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
appearance = {
|
|
type = "group",
|
|
order = 50,
|
|
name = L["OPT_UI_GROUP_APPEARANCE"] or "Appearance",
|
|
args = {
|
|
showPlayerName = {
|
|
type = "toggle",
|
|
order = 1,
|
|
name = L["OPT_SHOW_NAME"] or "Show player names",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.showPlayerName ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.showPlayerName = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
colorByClass = {
|
|
type = "toggle",
|
|
order = 2,
|
|
name = L["OPT_CLASS_COLOR"] or "Use class colours",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.colorByClass ~= false
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.colorByClass = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
font = {
|
|
type = "select",
|
|
order = 3,
|
|
name = L["OPT_FONT"] or "Typeface",
|
|
dialogControl = "LSM30_Font",
|
|
values = AceGUIWidgetLSMlists and AceGUIWidgetLSMlists.font or (LSM and LSM:HashTable("font")) or {},
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.font or "Friz Quadrata TT"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.font = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
fontSize = {
|
|
type = "range",
|
|
order = 4,
|
|
min = 6,
|
|
max = 24,
|
|
step = 1,
|
|
name = L["OPT_FONT_SIZE"] or "Font size",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.fontSize or 12
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.fontSize = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
fontOutline = {
|
|
type = "select",
|
|
order = 5,
|
|
name = L["OPT_FONT_OUTLINE"] or "Font outline",
|
|
values = FONT_OUTLINE_VALUES,
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.fontOutline or "OUTLINE"
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.fontOutline = val
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
borderEnabled = {
|
|
type = "toggle",
|
|
order = 6,
|
|
name = L["OPT_BORDER_ENABLED"] or "Show border",
|
|
desc = L["OPT_BORDER_ENABLED_DESC"] or "Show a 1px border around progress bars and icons",
|
|
get = function()
|
|
local tracker = s()
|
|
return tracker and tracker.borderEnabled == true
|
|
end,
|
|
set = function(_, val)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.borderEnabled = val and true or false
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
borderColor = {
|
|
type = "color",
|
|
order = 7,
|
|
hasAlpha = true,
|
|
name = L["OPT_BORDER_COLOR"] or "Border color",
|
|
desc = L["OPT_BORDER_COLOR_DESC"] or "Color of the 1px border",
|
|
get = function()
|
|
local tracker = s()
|
|
local color = tracker and tracker.borderColor or {}
|
|
return color.r or color[1] or 1, color.g or color[2] or 1, color.b or color[3] or 1, color.a or color[4] or 1
|
|
end,
|
|
set = function(_, r, g, b, a)
|
|
local tracker = s()
|
|
if tracker then
|
|
tracker.borderColor = { r = r, g = g, b = b, a = a }
|
|
TriggerTrackerUpdate(false)
|
|
end
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
end
|
|
|
|
RefreshTrackerOptionArgs = function()
|
|
if not trackerOptionsGroup then
|
|
return
|
|
end
|
|
|
|
trackerOptionsGroup.args = BuildTrackerOverviewArgs()
|
|
|
|
local trackers = GetSortedTrackers()
|
|
for index, tracker in ipairs(trackers) do
|
|
local trackerId = tonumber(tracker.id)
|
|
if trackerId then
|
|
trackerOptionsGroup.args["tracker_" .. trackerId] = BuildTrackerGroup(trackerId, 10 + index)
|
|
end
|
|
end
|
|
end
|
|
|
|
RefreshTrackedSpellsOptionArgs = function()
|
|
if not trackedSpellsOptionsGroup then
|
|
return
|
|
end
|
|
trackedSpellsOptionsGroup.args = BuildGlobalSpellBrowserArgs()
|
|
end
|
|
|
|
trackerOptionsGroup = {
|
|
type = "group",
|
|
name = L["OPT_TRACKERS"] or "Tracker Bars",
|
|
order = 10,
|
|
childGroups = "tree",
|
|
args = {},
|
|
}
|
|
|
|
trackedSpellsOptionsGroup = {
|
|
type = "group",
|
|
name = L["OPT_SECTION_SPELLS"] or "Tracked Spells",
|
|
order = 20,
|
|
childGroups = "tree",
|
|
args = {},
|
|
}
|
|
|
|
RefreshTrackerOptionArgs()
|
|
RefreshTrackedSpellsOptionArgs()
|
|
|
|
HMGT_Config:RegisterOptionsProvider("tracker.trackers", function()
|
|
if RefreshTrackerOptionArgs then
|
|
RefreshTrackerOptionArgs()
|
|
end
|
|
return {
|
|
path = "tracker.trackers",
|
|
order = 10,
|
|
group = trackerOptionsGroup,
|
|
}
|
|
end)
|
|
|
|
HMGT_Config:RegisterOptionsProvider("tracker.spells", function()
|
|
if RefreshTrackedSpellsOptionArgs then
|
|
RefreshTrackedSpellsOptionArgs()
|
|
end
|
|
return {
|
|
path = "tracker.spells",
|
|
order = 20,
|
|
group = trackedSpellsOptionsGroup,
|
|
}
|
|
end)
|
|
|
|
HMGT_Config:RegisterOptionsProvider("tracker", function()
|
|
if RefreshTrackerOptionArgs then
|
|
RefreshTrackerOptionArgs()
|
|
end
|
|
if RefreshTrackedSpellsOptionArgs then
|
|
RefreshTrackedSpellsOptionArgs()
|
|
end
|
|
|
|
local group = {
|
|
type = "group",
|
|
name = L["OPT_MODULE_TRACKER"] or "Tracker",
|
|
order = 10,
|
|
childGroups = "tree",
|
|
args = {
|
|
actionsHeader = {
|
|
type = "header",
|
|
name = L["OPT_TRACKER_ACTIONS"] or "Tracker actions",
|
|
order = 1,
|
|
},
|
|
lockAll = {
|
|
type = "execute",
|
|
order = 1.1,
|
|
width = "full",
|
|
name = L["OPT_LOCK_ALL"],
|
|
func = function()
|
|
if HMGT_Config and HMGT_Config.SetAllTrackerFramesLocked then
|
|
HMGT_Config.SetAllTrackerFramesLocked(true)
|
|
end
|
|
end,
|
|
},
|
|
unlockAll = {
|
|
type = "execute",
|
|
order = 1.2,
|
|
width = "full",
|
|
name = L["OPT_UNLOCK_ALL"],
|
|
func = function()
|
|
if HMGT_Config and HMGT_Config.SetAllTrackerFramesLocked then
|
|
HMGT_Config.SetAllTrackerFramesLocked(false)
|
|
end
|
|
end,
|
|
},
|
|
demoMode = {
|
|
type = "execute",
|
|
order = 1.3,
|
|
width = "full",
|
|
name = L["OPT_DEMO_MODE"],
|
|
desc = L["OPT_DEMO_MODE_DESC"],
|
|
func = function()
|
|
HMGT:DemoMode()
|
|
end,
|
|
},
|
|
testMode = {
|
|
type = "execute",
|
|
order = 1.4,
|
|
width = "full",
|
|
name = L["OPT_TEST_MODE"],
|
|
desc = L["OPT_TEST_MODE_DESC"],
|
|
func = function()
|
|
HMGT:TestMode()
|
|
end,
|
|
},
|
|
trackerBars = CopyGroup(trackerOptionsGroup, {
|
|
order = 10,
|
|
name = trackerOptionsGroup.name or (L["OPT_TRACKERS"] or "Tracker Bars"),
|
|
}),
|
|
trackedSpells = CopyGroup(trackedSpellsOptionsGroup, {
|
|
order = 20,
|
|
name = trackedSpellsOptionsGroup.name or (L["OPT_SECTION_SPELLS"] or "Tracked Spells"),
|
|
}),
|
|
},
|
|
}
|
|
|
|
return {
|
|
path = "tracker",
|
|
order = 10,
|
|
group = group,
|
|
}
|
|
end)
|