mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-30 15:40:51 +00:00
"Settings" in the Combat Log tab's menu opens Blizzard's Combat Log page, rebuilt in Lua with pfUI widgets: the filter list with copy, add and delete, and the Message Sources, Message Types, Colors, Formatting and Settings tabs. Combat Log Defaults restores the default filters. Closing the window refills the log only when the active filter changed. The log now records while ChatFrame2 is hidden, so switching tabs no longer loses history. The default filters are 4.3.4's: Self, Everything, What happened to me? and Kills. Classic Era's My actions left out auras.
1006 lines
39 KiB
Lua
1006 lines
39 KiB
Lua
-- Combat Log settings: the Combat Log page of Classic Era's ChatConfigFrame
|
|
-- (Blizzard_ChatFrame/Classic/ChatConfigFrame), built with pfUI's widgets.
|
|
-- The combatlog module opens it from the Combat Log tab's menu and hands it
|
|
-- the filter state as `log`.
|
|
setfenv(1, pfUI:GetEnvironment())
|
|
|
|
pfUI.combatlog = {}
|
|
|
|
-- ChatConfigFrame's eventList states for the subtypes of an unchecked group
|
|
local GRAY_CHECKED = 1
|
|
local UNCHECKED_ENABLED = 2
|
|
local UNCHECKED_DISABLED = 3
|
|
|
|
local SCHOOL_MASK_FIRE = 4
|
|
local SCHOOL_MASK_FROST = 16
|
|
|
|
-- ChatConfigFrame's cap on saved filters
|
|
local MAX_COMBATLOG_FILTERS = 20
|
|
local FILTER_ROWS = 4
|
|
local FILTER_ROW_HEIGHT = 16
|
|
|
|
local function Resolve(value)
|
|
if type(value) == "function" then return value() end
|
|
return value
|
|
end
|
|
|
|
local function SetCheck(check, checked)
|
|
check:SetChecked(checked and 1 or nil)
|
|
end
|
|
|
|
local function SetCheckEnabled(check, enabled)
|
|
if enabled then
|
|
check:Enable()
|
|
check.text:SetTextColor(1, 1, 1)
|
|
else
|
|
check:Disable()
|
|
check.text:SetTextColor(.5, .5, .5)
|
|
end
|
|
end
|
|
|
|
-- ChatConfigCheckButtonTemplate and ChatConfigSmallCheckButtonTemplate
|
|
local function CreateCheck(parent, text, tooltip, small)
|
|
local check = CreateFrame("CheckButton", nil, parent, "UICheckButtonTemplate")
|
|
SkinCheckbox(check, small and 12 or 14)
|
|
check.text = check:CreateFontString(nil, "OVERLAY", small and "GameFontHighlightSmall" or "GameFontHighlight")
|
|
check.text:SetPoint("LEFT", check, "RIGHT", 2, 0)
|
|
check.text:SetText(text)
|
|
check:SetHitRectInsets(0, small and -70 or -145, 0, 0)
|
|
check.tooltip = tooltip
|
|
check:SetScript("OnClick", function(self)
|
|
local checked = self:GetChecked()
|
|
if self.func then self.func(self, checked) end
|
|
PlaySound(checked and SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON or SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF)
|
|
end)
|
|
check:SetScript("OnEnter", function(self)
|
|
if self.tooltip then
|
|
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
|
GameTooltip:SetText(self.tooltip, 1, 1, 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end
|
|
end)
|
|
check:SetScript("OnLeave", function()
|
|
GameTooltip:Hide()
|
|
end)
|
|
return check
|
|
end
|
|
|
|
-- ChatConfigBoxWithHeaderTemplate
|
|
local function CreateBox(parent, title)
|
|
local box = CreateFrame("Frame", nil, parent)
|
|
CreateBackdrop(box, nil, nil, .75)
|
|
if title then
|
|
box.title = box:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
box.title:SetPoint("BOTTOMLEFT", box, "TOPLEFT", 0, 4)
|
|
box.title:SetText(title)
|
|
end
|
|
return box
|
|
end
|
|
|
|
local function CreateSwatch(parent)
|
|
local swatch = CreateFrame("Button", nil, parent)
|
|
swatch:SetSize(24, 12)
|
|
CreateBackdrop(swatch)
|
|
swatch.prev = swatch.backdrop:CreateTexture(nil, "OVERLAY")
|
|
swatch.prev:SetAllPoints(swatch)
|
|
if swatch.backdrop_shadow then swatch.backdrop_shadow:Hide() end
|
|
return swatch
|
|
end
|
|
|
|
local function CreateButton(parent, text, width)
|
|
local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
|
|
SkinButton(button)
|
|
button:SetSize(width, 22)
|
|
button:SetText(text)
|
|
return button
|
|
end
|
|
|
|
function pfUI.combatlog.CreateConfig(log)
|
|
local selected -- CHATCONFIG_SELECTED_FILTER
|
|
local selectedIndex -- ChatConfigCombatSettingsFilters.selectedFilter
|
|
local changed -- the log's active filter was edited; it reapplies on close
|
|
local Update -- refreshes every page from the selected filter
|
|
|
|
-- the log reapplies its filter on close only after an edit to that filter,
|
|
-- so closing the window doesn't clear what the log holds
|
|
local function Edited()
|
|
local filters = log.GetFilters()
|
|
if selected == filters.filters[filters.currentFilter] then changed = true end
|
|
Update()
|
|
end
|
|
|
|
--
|
|
-- The filter model (ChatConfigFrame's helpers). A filter's first part holds
|
|
-- the event list and the source flags. Its second part holds the dest flags,
|
|
-- unless it names units by GUID; a one-part filter keeps both in its first.
|
|
--
|
|
local function UsesGUID(direction)
|
|
local flags = selected.filters[1][direction == "SOURCE" and "sourceFlags" or "destFlags"]
|
|
for k in pairs(flags or {}) do
|
|
if type(k) == "string" then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function DestFilter()
|
|
if UsesGUID("SOURCE") or UsesGUID("DEST") then return selected.filters[1] end
|
|
return selected.filters[2] or selected.filters[1]
|
|
end
|
|
|
|
-- no flag table means every unit; unchecking one starts from all of them
|
|
local function AllFlags()
|
|
return {
|
|
[COMBATLOG_FILTER_MINE] = true, [COMBATLOG_FILTER_MY_PET] = true,
|
|
[COMBATLOG_FILTER_FRIENDLY_UNITS] = true, [COMBATLOG_FILTER_HOSTILE_PLAYERS] = true,
|
|
[COMBATLOG_FILTER_HOSTILE_UNITS] = true, [COMBATLOG_FILTER_NEUTRAL_UNITS] = true,
|
|
[COMBATLOG_FILTER_UNKNOWN_UNITS] = true,
|
|
}
|
|
end
|
|
|
|
local function IsMessageDoneBy(flag)
|
|
local flags = selected.filters[1].sourceFlags
|
|
return not flags or flags[flag]
|
|
end
|
|
|
|
local function IsMessageDoneTo(flag)
|
|
local flags = DestFilter().destFlags
|
|
return not flags or flags[flag]
|
|
end
|
|
|
|
local function ToggleMessageSource(checked, flag)
|
|
local filter = selected.filters[1]
|
|
filter.sourceFlags = filter.sourceFlags or AllFlags()
|
|
filter.sourceFlags[flag] = checked and true or false
|
|
end
|
|
|
|
local function ToggleMessageDest(checked, flag)
|
|
local filter = DestFilter()
|
|
filter.destFlags = filter.destFlags or AllFlags()
|
|
filter.destFlags[flag] = checked and true or false
|
|
end
|
|
|
|
local function GetMessageTypeState(messageType)
|
|
if type(messageType) == "table" then messageType = messageType[1] end
|
|
return selected.filters[1].eventList[messageType]
|
|
end
|
|
|
|
-- only the first type counts; a subtype's types go on and off together
|
|
local function HasMessageType(messageType)
|
|
local state = GetMessageTypeState(messageType)
|
|
return state and state ~= UNCHECKED_ENABLED and state ~= UNCHECKED_DISABLED
|
|
end
|
|
|
|
local function ToggleMessageType(checked, ...)
|
|
local eventList = selected.filters[1].eventList
|
|
for _, messageType in pairs({ ... }) do
|
|
eventList[messageType] = checked and true or false
|
|
end
|
|
end
|
|
|
|
-- A group shows checked unless its first subtype with a state is parked.
|
|
local function HasMessageTypeGroup(group)
|
|
for _, sub in ipairs(group.subTypes) do
|
|
local state = GetMessageTypeState(sub.type)
|
|
if state == GRAY_CHECKED or state == UNCHECKED_DISABLED then
|
|
return false
|
|
elseif state then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Unchecking a group parks its subtypes' states, so checking it again
|
|
-- restores the ones that were on.
|
|
local function ToggleMessageTypeGroup(checked, group)
|
|
local eventList = selected.filters[1].eventList
|
|
for _, sub in ipairs(group.subTypes) do
|
|
local state = GetMessageTypeState(sub.type)
|
|
local on = state == true or state == GRAY_CHECKED
|
|
local value
|
|
if checked then
|
|
value = on and true or UNCHECKED_ENABLED
|
|
else
|
|
value = on and GRAY_CHECKED or UNCHECKED_DISABLED
|
|
end
|
|
local types = type(sub.type) == "table" and sub.type or { sub.type }
|
|
for _, messageType in pairs(types) do
|
|
eventList[messageType] = value
|
|
end
|
|
end
|
|
end
|
|
|
|
--
|
|
-- The checkbox tables (COMBAT_CONFIG_MESSAGESOURCES_*, _MESSAGETYPES_*).
|
|
-- Enchants and pet loyalty are left out: ClassicAPI never logs them.
|
|
--
|
|
local function Source(text, flag, tooltip)
|
|
return {
|
|
text = text,
|
|
checked = function() return IsMessageDoneBy(flag) end,
|
|
hidden = function() return UsesGUID("SOURCE") end,
|
|
func = function(self, checked) ToggleMessageSource(checked, flag) end,
|
|
tooltip = tooltip,
|
|
}
|
|
end
|
|
|
|
local function Dest(text, flag, tooltip)
|
|
return {
|
|
text = text,
|
|
checked = function() return IsMessageDoneTo(flag) end,
|
|
hidden = function() return UsesGUID("DEST") end,
|
|
func = function(self, checked) ToggleMessageDest(checked, flag) end,
|
|
tooltip = tooltip,
|
|
}
|
|
end
|
|
|
|
local MESSAGESOURCES_BY = {
|
|
{
|
|
text = function() return UsesGUID("SOURCE") and COMBATLOG_FILTER_STRING_CUSTOM_UNIT or COMBATLOG_FILTER_STRING_ME end,
|
|
checked = function() return UsesGUID("SOURCE") or IsMessageDoneBy(COMBATLOG_FILTER_MINE) end,
|
|
disabled = function() return UsesGUID("SOURCE") end,
|
|
func = function(self, checked) ToggleMessageSource(checked, COMBATLOG_FILTER_MINE) end,
|
|
tooltip = FILTER_BY_ME_COMBATLOG_TOOLTIP,
|
|
},
|
|
Source(COMBATLOG_FILTER_STRING_MY_PET, COMBATLOG_FILTER_MY_PET, FILTER_BY_PET_COMBATLOG_TOOLTIP),
|
|
Source(COMBATLOG_FILTER_STRING_FRIENDLY_UNITS, COMBATLOG_FILTER_FRIENDLY_UNITS, FILTER_BY_FRIENDS_COMBATLOG_TOOLTIP),
|
|
Source(COMBATLOG_FILTER_STRING_HOSTILE_PLAYERS, COMBATLOG_FILTER_HOSTILE_PLAYERS, FILTER_BY_HOSTILE_PLAYERS_COMBATLOG_TOOLTIP),
|
|
Source(COMBATLOG_FILTER_STRING_HOSTILE_UNITS, COMBATLOG_FILTER_HOSTILE_UNITS, FILTER_BY_ENEMIES_COMBATLOG_TOOLTIP),
|
|
Source(COMBATLOG_FILTER_STRING_NEUTRAL_UNITS, COMBATLOG_FILTER_NEUTRAL_UNITS, FILTER_BY_NEUTRAL_COMBATLOG_TOOLTIP),
|
|
Source(COMBATLOG_FILTER_STRING_UNKNOWN_UNITS, COMBATLOG_FILTER_UNKNOWN_UNITS, FILTER_BY_UNKNOWN_COMBATLOG_TOOLTIP),
|
|
}
|
|
|
|
local MESSAGESOURCES_TO = {
|
|
{
|
|
text = function() return UsesGUID("DEST") and COMBATLOG_FILTER_STRING_CUSTOM_UNIT or COMBATLOG_FILTER_STRING_ME end,
|
|
checked = function() return UsesGUID("DEST") or IsMessageDoneTo(COMBATLOG_FILTER_MINE) end,
|
|
disabled = function() return UsesGUID("DEST") end,
|
|
func = function(self, checked) ToggleMessageDest(checked, COMBATLOG_FILTER_MINE) end,
|
|
tooltip = FILTER_TO_ME_COMBATLOG_TOOLTIP,
|
|
},
|
|
Dest(COMBATLOG_FILTER_STRING_MY_PET, COMBATLOG_FILTER_MY_PET, FILTER_TO_PET_COMBATLOG_TOOLTIP),
|
|
Dest(COMBATLOG_FILTER_STRING_FRIENDLY_UNITS, COMBATLOG_FILTER_FRIENDLY_UNITS, FILTER_TO_FRIENDS_COMBATLOG_TOOLTIP),
|
|
Dest(COMBATLOG_FILTER_STRING_HOSTILE_PLAYERS, COMBATLOG_FILTER_HOSTILE_PLAYERS, FILTER_TO_HOSTILE_PLAYERS_COMBATLOG_TOOLTIP),
|
|
Dest(COMBATLOG_FILTER_STRING_HOSTILE_UNITS, COMBATLOG_FILTER_HOSTILE_UNITS, FILTER_TO_HOSTILE_COMBATLOG_TOOLTIP),
|
|
Dest(COMBATLOG_FILTER_STRING_NEUTRAL_UNITS, COMBATLOG_FILTER_NEUTRAL_UNITS, FILTER_TO_NEUTRAL_COMBATLOG_TOOLTIP),
|
|
Dest(COMBATLOG_FILTER_STRING_UNKNOWN_UNITS, COMBATLOG_FILTER_UNKNOWN_UNITS, FILTER_TO_UNKNOWN_COMBATLOG_TOOLTIP),
|
|
}
|
|
|
|
-- a subtype that turns its event types on and off together
|
|
local function Type(text, tooltip, ...)
|
|
local types = { ... }
|
|
return {
|
|
text = text,
|
|
type = types,
|
|
checked = function() return HasMessageType(types) end,
|
|
func = function(self, checked) ToggleMessageType(checked, unpack(types)) end,
|
|
tooltip = tooltip,
|
|
}
|
|
end
|
|
|
|
local AURA_TYPES = { "SPELL_AURA_APPLIED", "SPELL_AURA_APPLIED_DOSE", "SPELL_AURA_REMOVED", "SPELL_AURA_REMOVED_DOSE", "SPELL_AURA_REFRESH" }
|
|
|
|
-- buffs and debuffs share the aura events; those stop only when both are off
|
|
local function Aura(text, tooltip, setting, other)
|
|
return {
|
|
text = text,
|
|
type = AURA_TYPES,
|
|
checked = function() return not selected.settings[setting] end,
|
|
func = function(self, checked)
|
|
selected.settings[setting] = not checked
|
|
if checked or selected.settings[other] then
|
|
ToggleMessageType(checked, unpack(AURA_TYPES))
|
|
end
|
|
end,
|
|
tooltip = tooltip,
|
|
}
|
|
end
|
|
|
|
local MESSAGETYPES_LEFT = {
|
|
{
|
|
text = MELEE, tooltip = MELEE_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Type(DAMAGE, SWING_DAMAGE_COMBATLOG_TOOLTIP, "SWING_DAMAGE"),
|
|
Type(MISSES, SWING_MISSED_COMBATLOG_TOOLTIP, "SWING_MISSED"),
|
|
},
|
|
},
|
|
{
|
|
text = RANGED, tooltip = RANGED_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Type(DAMAGE, RANGE_DAMAGE_COMBATLOG_TOOLTIP, "RANGE_DAMAGE"),
|
|
Type(MISSES, RANGE_MISSED_COMBATLOG_TOOLTIP, "RANGE_MISSED"),
|
|
},
|
|
},
|
|
{
|
|
text = AURAS, tooltip = AURAS_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Aura(BENEFICIAL, BENEFICIAL_AURA_COMBATLOG_TOOLTIP, "hideBuffs", "hideDebuffs"),
|
|
Aura(HOSTILE, HARMFUL_AURA_COMBATLOG_TOOLTIP, "hideDebuffs", "hideBuffs"),
|
|
Type(DISPELS, DISPEL_AURA_COMBATLOG_TOOLTIP, "SPELL_DISPEL", "SPELL_DISPEL_FAILED", "SPELL_STOLEN"),
|
|
},
|
|
},
|
|
{
|
|
text = PERIODIC, tooltip = SPELL_PERIODIC_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Type(DAMAGE, SPELL_PERIODIC_DAMAGE_COMBATLOG_TOOLTIP, "SPELL_PERIODIC_DAMAGE"),
|
|
Type(MISSES, SPELL_PERIODIC_MISSED_COMBATLOG_TOOLTIP, "SPELL_PERIODIC_MISSED"),
|
|
Type(HEALS, SPELL_PERIODIC_HEAL_COMBATLOG_TOOLTIP, "SPELL_PERIODIC_HEAL"),
|
|
Type(OTHER, SPELL_PERIODIC_OTHER_COMBATLOG_TOOLTIP, "SPELL_PERIODIC_DRAIN", "SPELL_PERIODIC_LEECH"),
|
|
},
|
|
},
|
|
}
|
|
|
|
local MESSAGETYPES_RIGHT = {
|
|
{
|
|
text = SPELLS, tooltip = SPELLS_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Type(DAMAGE, SPELL_DAMAGE_COMBATLOG_TOOLTIP, "SPELL_DAMAGE"),
|
|
Type(MISSES, SPELL_MISSED_COMBATLOG_TOOLTIP, "SPELL_MISSED"),
|
|
Type(HEALS, SPELL_HEAL_COMBATLOG_TOOLTIP, "SPELL_HEAL"),
|
|
Type(POWER_GAINS, POWER_GAINS_COMBATLOG_TOOLTIP, "SPELL_ENERGIZE", "SPELL_PERIODIC_ENERGIZE"),
|
|
Type(DRAINS, SPELL_DRAIN_COMBATLOG_TOOLTIP, "SPELL_DRAIN", "SPELL_LEECH"),
|
|
Type(INTERRUPTS, SPELL_INTERRUPT_COMBATLOG_TOOLTIP, "SPELL_INTERRUPT"),
|
|
Type(SPECIAL, SPELL_INSTAKILL_COMBATLOG_TOOLTIP, "SPELL_INSTAKILL", "SPELL_DURABILITY_DAMAGE", "SPELL_DURABILITY_DAMAGE_ALL"),
|
|
Type(EXTRA_ATTACKS, SPELL_EXTRA_ATTACKS_COMBATLOG_TOOLTIP, "SPELL_EXTRA_ATTACKS"),
|
|
Type(SUMMONS, SPELL_SUMMON_COMBATLOG_TOOLTIP, "SPELL_SUMMON"),
|
|
Type(RESURRECT, SPELL_RESURRECT_COMBATLOG_TOOLTIP, "SPELL_RESURRECT"),
|
|
},
|
|
},
|
|
{
|
|
text = SPELL_CASTING, tooltip = SPELL_CASTING_COMBATLOG_TOOLTIP,
|
|
subTypes = {
|
|
Type(START, SPELL_CAST_START_COMBATLOG_TOOLTIP, "SPELL_CAST_START"),
|
|
Type(SUCCESS, SPELL_CAST_SUCCESS_COMBATLOG_TOOLTIP, "SPELL_CAST_SUCCESS"),
|
|
Type(FAILURES, SPELL_CAST_FAILED_COMBATLOG_TOOLTIP, "SPELL_CAST_FAILED"),
|
|
},
|
|
},
|
|
}
|
|
|
|
local MESSAGETYPES_MISC = {
|
|
Type(DAMAGE_SHIELD, DAMAGE_SHIELD_COMBATLOG_TOOLTIP, "DAMAGE_SHIELD", "DAMAGE_SHIELD_MISSED"),
|
|
Type(ENVIRONMENTAL_DAMAGE, ENVIRONMENTAL_DAMAGE_COMBATLOG_TOOLTIP, "ENVIRONMENTAL_DAMAGE"),
|
|
Type(KILLS, KILLS_COMBATLOG_TOOLTIP, "PARTY_KILL"),
|
|
Type(DEATHS, DEATHS_COMBATLOG_TOOLTIP, "UNIT_DIED", "UNIT_DESTROYED", "UNIT_DISSIPATES"),
|
|
}
|
|
|
|
local UNIT_COLORS = {
|
|
{ text = COMBATLOG_FILTER_STRING_ME, flag = COMBATLOG_FILTER_MINE },
|
|
{ text = COMBATLOG_FILTER_STRING_MY_PET, flag = COMBATLOG_FILTER_MY_PET },
|
|
{ text = COMBATLOG_FILTER_STRING_FRIENDLY_UNITS, flag = COMBATLOG_FILTER_FRIENDLY_UNITS },
|
|
{ text = COMBATLOG_FILTER_STRING_HOSTILE_UNITS, flag = COMBATLOG_FILTER_HOSTILE_UNITS },
|
|
{ text = COMBATLOG_FILTER_STRING_HOSTILE_PLAYERS, flag = COMBATLOG_FILTER_HOSTILE_PLAYERS },
|
|
{ text = COMBATLOG_FILTER_STRING_NEUTRAL_UNITS, flag = COMBATLOG_FILTER_NEUTRAL_UNITS },
|
|
{ text = COMBATLOG_FILTER_STRING_UNKNOWN_UNITS, flag = COMBATLOG_FILTER_UNKNOWN_UNITS },
|
|
}
|
|
|
|
--
|
|
-- Checkbox builders (ChatConfig_CreateCheckboxes, _CreateTieredCheckboxes)
|
|
--
|
|
local function CreateCheckboxList(parent, title, entries)
|
|
local box = CreateBox(parent, title)
|
|
box:SetWidth(200)
|
|
box.entries = entries
|
|
box.checks = {}
|
|
for i, entry in ipairs(entries) do
|
|
local check = CreateCheck(box, nil, entry.tooltip)
|
|
local func = entry.func
|
|
check.func = function(self, checked) func(self, checked) Edited() end
|
|
box.checks[i] = check
|
|
end
|
|
return box
|
|
end
|
|
|
|
-- hidden entries close up, and the box fits the rest
|
|
local function UpdateCheckboxList(box)
|
|
local shown = 0
|
|
for i, entry in ipairs(box.entries) do
|
|
local check = box.checks[i]
|
|
if Resolve(entry.hidden) then
|
|
check:Hide()
|
|
else
|
|
check:ClearAllPoints()
|
|
check:SetPoint("TOPLEFT", box, "TOPLEFT", 8, -6 - shown * 22)
|
|
check.text:SetText(Resolve(entry.text))
|
|
SetCheck(check, Resolve(entry.checked))
|
|
SetCheckEnabled(check, not Resolve(entry.disabled))
|
|
check:Show()
|
|
shown = shown + 1
|
|
end
|
|
end
|
|
box:SetHeight(shown * 22 + 8)
|
|
end
|
|
|
|
-- a checkbox per group with its subtypes in two columns under it; an entry
|
|
-- without subtypes is a plain checkbox
|
|
local function CreateTieredList(parent, entries, small)
|
|
local list = CreateFrame("Frame", nil, parent)
|
|
list:SetWidth(220)
|
|
list.entries = entries
|
|
list.checks = {}
|
|
local y = 0
|
|
for i, entry in ipairs(entries) do
|
|
local check = CreateCheck(list, entry.text, entry.tooltip, small)
|
|
check:SetPoint("TOPLEFT", list, "TOPLEFT", 0, -y)
|
|
y = y + 22
|
|
check.subs = {}
|
|
if entry.subTypes then
|
|
check.func = function(self, checked) ToggleMessageTypeGroup(checked, entry) Edited() end
|
|
for k, sub in ipairs(entry.subTypes) do
|
|
local subcheck = CreateCheck(list, sub.text, sub.tooltip, true)
|
|
subcheck:SetPoint("TOPLEFT", check, "BOTTOMLEFT", 15 + (k - 1) % 2 * 95, -2 - ceil(k / 2 - 1) * 20)
|
|
local func = sub.func
|
|
subcheck.func = function(self, checked) func(self, checked) Edited() end
|
|
check.subs[k] = subcheck
|
|
end
|
|
y = y + ceil(#entry.subTypes / 2) * 20 + 8
|
|
else
|
|
local func = entry.func
|
|
check.func = function(self, checked) func(self, checked) Edited() end
|
|
end
|
|
list.checks[i] = check
|
|
end
|
|
list:SetHeight(y)
|
|
return list
|
|
end
|
|
|
|
-- subtypes take clicks only under a checked group
|
|
local function UpdateTieredList(list)
|
|
for i, entry in ipairs(list.entries) do
|
|
local check = list.checks[i]
|
|
if entry.subTypes then
|
|
local groupChecked = HasMessageTypeGroup(entry)
|
|
SetCheck(check, groupChecked)
|
|
for k, sub in ipairs(entry.subTypes) do
|
|
SetCheck(check.subs[k], Resolve(sub.checked))
|
|
SetCheckEnabled(check.subs[k], groupChecked)
|
|
end
|
|
else
|
|
SetCheck(check, Resolve(entry.checked))
|
|
end
|
|
end
|
|
end
|
|
|
|
local function PickColor(color)
|
|
local r, g, b = color.r, color.g, color.b
|
|
-- SetColorRGB runs the installed func; drop the last picker user's first
|
|
ColorPickerFrame.func = nil
|
|
ColorPickerFrame.cancelFunc = nil
|
|
ColorPickerFrame.hasOpacity = nil
|
|
ColorPickerFrame.opacityFunc = nil
|
|
ColorPickerFrame:SetColorRGB(r, g, b)
|
|
ColorPickerFrame.func = function()
|
|
color.r, color.g, color.b = ColorPickerFrame:GetColorRGB()
|
|
Edited()
|
|
end
|
|
ColorPickerFrame.cancelFunc = function()
|
|
color.r, color.g, color.b = r, g, b
|
|
Edited()
|
|
end
|
|
ColorPickerFrame:SetFrameStrata("DIALOG")
|
|
ShowUIPanel(ColorPickerFrame)
|
|
end
|
|
|
|
-- CombatConfig_Colorize_Update's example lines: you hit a target, it hits you
|
|
local function UpdateExamples(page)
|
|
local player, guid = UnitName("player"), UnitGUID("player")
|
|
local text, r, g, b = log.FormatEvent(selected, 0, "SPELL_DAMAGE", false,
|
|
guid, player, 0x511, 0, "0xF13000012B000820", EXAMPLE_TARGET_MONSTER, 0x10a28, 0,
|
|
116, EXAMPLE_SPELL_FROSTBOLT, SCHOOL_MASK_FROST, 27, 0, SCHOOL_MASK_FROST, nil, nil, nil, 1)
|
|
page.example1:SetText(text)
|
|
page.example1:SetTextColor(r, g, b)
|
|
|
|
text, r, g, b = log.FormatEvent(selected, 0, "SPELL_DAMAGE", false,
|
|
"0xF13000024D002914", EXAMPLE_TARGET_MONSTER, 0x10a48, 0, guid, player, 0x511, 0,
|
|
20793, EXAMPLE_SPELL_FIREBALL, SCHOOL_MASK_FIRE, 68, 0, SCHOOL_MASK_FIRE)
|
|
page.example2:SetText(text)
|
|
page.example2:SetTextColor(r, g, b)
|
|
end
|
|
|
|
local function CreateExamples(page)
|
|
page.example1 = page:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
page.example1:SetPoint("TOPLEFT", page, "TOPLEFT", 25, -27)
|
|
page.example1:SetWidth(540)
|
|
page.example1:SetJustifyH("LEFT")
|
|
page.example2 = page:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
page.example2:SetPoint("TOPLEFT", page.example1, "BOTTOMLEFT", 0, 0)
|
|
page.example2:SetWidth(540)
|
|
page.example2:SetJustifyH("LEFT")
|
|
local title = page:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
title:SetPoint("BOTTOMLEFT", page.example1, "TOPLEFT", 0, 3)
|
|
title:SetText(EXAMPLE_TEXT)
|
|
end
|
|
|
|
-- a checkbox bound to one of the selected filter's settings
|
|
local function SettingCheck(parent, text, tooltip, setting, small)
|
|
local check = CreateCheck(parent, text, tooltip, small)
|
|
check.setting = setting
|
|
check.func = function(self, checked)
|
|
selected.settings[setting] = checked and true or false
|
|
Edited()
|
|
end
|
|
return check
|
|
end
|
|
|
|
--
|
|
-- The window (ChatConfigFrame with only its Combat Log category)
|
|
--
|
|
local frame = CreateFrame("Frame", "pfCombatLogConfig", UIParent)
|
|
frame:SetSize(620, 600)
|
|
frame:SetPoint("CENTER", 0, 0)
|
|
frame:SetFrameStrata("HIGH")
|
|
frame:SetMovable(true)
|
|
frame:EnableMouse(true)
|
|
frame:SetClampedToScreen(true)
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:SetScript("OnDragStart", function() this:StartMoving() end)
|
|
frame:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
|
|
CreateBackdrop(frame, nil, nil, .9)
|
|
CreateBackdropShadow(frame)
|
|
tinsert(UISpecialFrames, "pfCombatLogConfig")
|
|
frame:Hide()
|
|
|
|
frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
frame.title:SetPoint("TOP", frame, "TOP", 0, -10)
|
|
frame.title:SetText(COMBAT_LOG)
|
|
|
|
local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
|
closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -4, -4)
|
|
SkinCloseButton(closeButton, frame.backdrop or frame, -6, -6)
|
|
|
|
--
|
|
-- The saved filters: a list to pick one from, and buttons to reorder,
|
|
-- copy, add and delete them
|
|
--
|
|
local filterList = CreateFrame("Frame", nil, frame, "pfUIScrollBoxListTemplate")
|
|
filterList:SetPoint("TOPLEFT", frame, "TOPLEFT", 12, -32)
|
|
filterList:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, -32)
|
|
-- the template keeps 5px around the rows, which sit 2px apart
|
|
filterList:SetHeight(FILTER_ROWS * (FILTER_ROW_HEIGHT + 2) - 2 + 10)
|
|
CreateBackdrop(filterList, nil, nil, .75)
|
|
|
|
local SelectFilter
|
|
|
|
local function InitFilterRow(row, entry)
|
|
if not row.text then
|
|
row.highlight = row:CreateTexture(nil, "BACKGROUND")
|
|
row.highlight:SetAllPoints(row)
|
|
row.highlight:SetTexture(.3, .3, .3, .4)
|
|
row.hover = row:CreateTexture(nil, "BACKGROUND")
|
|
row.hover:SetAllPoints(row)
|
|
row.hover:SetTexture(1, 1, 1, .1)
|
|
row.hover:Hide()
|
|
row.text = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
row.text:SetPoint("LEFT", row, "LEFT", 4, 0)
|
|
row:SetScript("OnClick", function() SelectFilter(row.index) end)
|
|
row:SetScript("OnEnter", function() row.hover:Show() end)
|
|
row:SetScript("OnLeave", function() row.hover:Hide() end)
|
|
end
|
|
row.index = entry.index
|
|
row.text:SetText(entry.name)
|
|
row.highlight:SetShown(entry.index == selectedIndex)
|
|
end
|
|
|
|
local filterView = CreateScrollBoxListLinearView(0, 0, 0, 2, 2)
|
|
filterView:SetElementExtent(FILTER_ROW_HEIGHT)
|
|
filterView:SetElementInitializer("Button", InitFilterRow)
|
|
ScrollUtil.InitScrollBoxListWithScrollBar(filterList.ScrollBox, filterList.ScrollBar, filterView)
|
|
|
|
-- ChatConfig_MoveFilterUp / _MoveFilterDown; the active filter keeps its
|
|
-- place in the log
|
|
local function MoveFilter(offset)
|
|
local filters = log.GetFilters()
|
|
local to = selectedIndex + offset
|
|
if to < 1 or to > #filters.filters then return end
|
|
filters.filters[selectedIndex], filters.filters[to] = filters.filters[to], filters.filters[selectedIndex]
|
|
if filters.currentFilter == selectedIndex then
|
|
filters.currentFilter = to
|
|
elseif filters.currentFilter == to then
|
|
filters.currentFilter = selectedIndex
|
|
end
|
|
log.UpdateQuickButtons()
|
|
SelectFilter(to)
|
|
end
|
|
|
|
local function CreateMoveButton(dir, tooltip, offset)
|
|
local button = CreateFrame("Button", nil, frame)
|
|
SkinArrowButton(button, dir, 16)
|
|
button:SetScript("OnClick", function()
|
|
MoveFilter(offset)
|
|
PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
|
|
end)
|
|
button:SetScript("OnEnter", function()
|
|
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
|
GameTooltip:SetText(tooltip, 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end)
|
|
button:SetScript("OnLeave", function() GameTooltip:Hide() end)
|
|
return button
|
|
end
|
|
|
|
local moveUp = CreateMoveButton("up", MOVE_FILTER_UP, -1)
|
|
moveUp:SetPoint("TOPLEFT", filterList, "BOTTOMLEFT", 4, -8)
|
|
local moveDown = CreateMoveButton("down", MOVE_FILTER_DOWN, 1)
|
|
moveDown:SetPoint("LEFT", moveUp, "RIGHT", 8, 0)
|
|
|
|
-- CombatConfig_DeleteCurrentCombatFilter; the log switches to the first
|
|
-- filter only when the one it shows is deleted
|
|
local function DeleteFilter()
|
|
local filters = log.GetFilters()
|
|
if #filters.filters <= 1 then return end
|
|
tremove(filters.filters, selectedIndex)
|
|
if selectedIndex == filters.currentFilter then
|
|
log.SelectFilter(1)
|
|
changed = nil
|
|
else
|
|
if selectedIndex < filters.currentFilter then
|
|
filters.currentFilter = filters.currentFilter - 1
|
|
end
|
|
log.UpdateQuickButtons()
|
|
end
|
|
SelectFilter(1)
|
|
end
|
|
|
|
local deleteButton = CreateButton(frame, DELETE, 70)
|
|
deleteButton:SetPoint("TOPRIGHT", filterList, "BOTTOMRIGHT", 0, -6)
|
|
deleteButton:SetScript("OnClick", function()
|
|
CreateQuestionDialog(CONFIRM_COMBAT_FILTER_DELETE, DeleteFilter)
|
|
end)
|
|
|
|
local addButton = CreateButton(frame, ADD_FILTER, 90)
|
|
addButton:SetPoint("RIGHT", deleteButton, "LEFT", -6, 0)
|
|
addButton:SetScript("OnClick", function()
|
|
log.NewFilter(nil, SelectFilter)
|
|
end)
|
|
|
|
local copyButton = CreateButton(frame, COPY_FILTER, 90)
|
|
copyButton:SetPoint("RIGHT", addButton, "LEFT", -6, 0)
|
|
copyButton:SetScript("OnClick", function()
|
|
log.NewFilter(selected, SelectFilter)
|
|
end)
|
|
|
|
--
|
|
-- The selected filter's settings, one tab at a time
|
|
--
|
|
local content = CreateFrame("Frame", nil, frame)
|
|
content:SetPoint("TOPLEFT", frame, "TOPLEFT", 12, -172)
|
|
content:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -12, 42)
|
|
CreateBackdrop(content, nil, nil, .75)
|
|
|
|
local tabs = {}
|
|
local function SelectTab(id)
|
|
for i, tab in ipairs(tabs) do
|
|
tab.page:SetShown(i == id)
|
|
if i == id then tab:LockHighlight() else tab:UnlockHighlight() end
|
|
end
|
|
end
|
|
|
|
local function CreateTab(text)
|
|
local tab = CreateButton(frame, text, 10)
|
|
tab:SetHeight(20)
|
|
tab:SetWidth(tab:GetTextWidth() + 24)
|
|
local id = #tabs + 1
|
|
if id == 1 then
|
|
tab:SetPoint("BOTTOMLEFT", content, "TOPLEFT", 0, 6)
|
|
else
|
|
tab:SetPoint("LEFT", tabs[id - 1], "RIGHT", 4, 0)
|
|
end
|
|
tab:SetScript("OnClick", function()
|
|
PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON)
|
|
SelectTab(id)
|
|
end)
|
|
tab.page = CreateFrame("Frame", nil, content)
|
|
tab.page:SetAllPoints(content)
|
|
tabs[id] = tab
|
|
return tab.page
|
|
end
|
|
|
|
-- Message Sources
|
|
local page = CreateTab(MESSAGE_SOURCES)
|
|
local doneBy = CreateCheckboxList(page, DONE_BY, MESSAGESOURCES_BY)
|
|
doneBy:SetPoint("TOPLEFT", page, "TOPLEFT", 13, -25)
|
|
local doneTo = CreateCheckboxList(page, DONE_TO, MESSAGESOURCES_TO)
|
|
doneTo:SetPoint("TOPLEFT", doneBy, "TOPRIGHT", 50, 0)
|
|
|
|
-- Message Types
|
|
page = CreateTab(MESSAGE_TYPES)
|
|
local typesLeft = CreateTieredList(page, MESSAGETYPES_LEFT)
|
|
typesLeft:SetPoint("TOPLEFT", page, "TOPLEFT", 13, -10)
|
|
local typesRight = CreateTieredList(page, MESSAGETYPES_RIGHT)
|
|
typesRight:SetPoint("TOPLEFT", typesLeft, "TOPRIGHT", 60, 0)
|
|
local typesMisc = CreateTieredList(page, MESSAGETYPES_MISC, true)
|
|
typesMisc:SetPoint("TOPLEFT", typesRight, "BOTTOMLEFT", 0, -22)
|
|
local miscTitle = page:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
miscTitle:SetPoint("BOTTOMLEFT", typesMisc, "TOPLEFT", 0, 4)
|
|
miscTitle:SetText(MISCELLANEOUS)
|
|
|
|
-- Colors
|
|
local colors = CreateTab(COLORS)
|
|
CreateExamples(colors)
|
|
|
|
local unitColors = CreateBox(colors, UNIT_COLORS)
|
|
unitColors:SetPoint("TOPLEFT", colors, "TOPLEFT", 13, -100)
|
|
unitColors:SetSize(200, #UNIT_COLORS * 22 + 8)
|
|
unitColors.swatches = {}
|
|
for i, entry in ipairs(UNIT_COLORS) do
|
|
local label = unitColors:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
label:SetPoint("TOPLEFT", unitColors, "TOPLEFT", 8, -10 - (i - 1) * 22)
|
|
label:SetText(entry.text)
|
|
local swatch = CreateSwatch(unitColors)
|
|
swatch:SetPoint("RIGHT", unitColors, "TOPRIGHT", -8, -15 - (i - 1) * 22)
|
|
swatch.flag = entry.flag
|
|
swatch:SetScript("OnClick", function() PickColor(selected.colors.unitColoring[this.flag]) end)
|
|
unitColors.swatches[i] = swatch
|
|
end
|
|
|
|
local highlighting = CreateBox(colors, HIGHLIGHTING)
|
|
highlighting:SetPoint("TOPLEFT", unitColors, "BOTTOMLEFT", 0, -25)
|
|
highlighting:SetSize(200, 50)
|
|
local highlightChecks = {
|
|
SettingCheck(highlighting, COMBATLOG_HIGHLIGHT_KILL, HIGHLIGHT_KILL_COMBATLOG_TOOLTIP, "lineHighlighting", true),
|
|
SettingCheck(highlighting, COMBATLOG_HIGHLIGHT_ABILITY, HIGHLIGHT_ABILITY_COMBATLOG_TOOLTIP, "abilityHighlighting", true),
|
|
SettingCheck(highlighting, COMBATLOG_HIGHLIGHT_DAMAGE, HIGHLIGHT_DAMAGE_COMBATLOG_TOOLTIP, "amountHighlighting", true),
|
|
SettingCheck(highlighting, COMBATLOG_HIGHLIGHT_SCHOOL, HIGHLIGHT_SCHOOL_COMBATLOG_TOOLTIP, "schoolNameHighlighting", true),
|
|
}
|
|
for i, check in ipairs(highlightChecks) do
|
|
check:SetPoint("TOPLEFT", highlighting, "TOPLEFT", 8 + (i - 1) % 2 * 95, -6 - ceil(i / 2 - 1) * 20)
|
|
end
|
|
|
|
local colorize = CreateBox(colors, COLORIZE)
|
|
colorize:SetPoint("TOPLEFT", unitColors, "TOPRIGHT", 50, 0)
|
|
colorize:SetSize(240, 192)
|
|
|
|
local unitNames = CreateCheck(colorize, UNIT_NAMES, UNIT_NAMES_COMBATLOG_TOOLTIP)
|
|
unitNames:SetPoint("TOPLEFT", colorize, "TOPLEFT", 8, -6)
|
|
unitNames.func = function(self, checked)
|
|
local on = checked and true or false
|
|
selected.settings.unitColoring, selected.settings.sourceColoring, selected.settings.destColoring = on, on, on
|
|
Edited()
|
|
end
|
|
|
|
local spellNames = SettingCheck(colorize, SPELL_NAMES, SPELL_NAMES_COMBATLOG_TOOLTIP, "abilityColoring")
|
|
spellNames:SetPoint("TOPLEFT", unitNames, "BOTTOMLEFT", 0, -8)
|
|
local spellSchool = SettingCheck(colorize, COLOR_BY_SCHOOL, SPELL_COLOR_BY_SCHOOL_COMBATLOG_TOOLTIP, "abilitySchoolColoring", true)
|
|
spellSchool:SetPoint("TOPLEFT", spellNames, "BOTTOMLEFT", 15, -2)
|
|
local spellSwatch = CreateSwatch(colorize)
|
|
spellSwatch:SetPoint("RIGHT", colorize, "RIGHT", -8, 0)
|
|
spellSwatch:SetPoint("TOP", spellNames, "TOP", 0, -4)
|
|
spellSwatch:SetScript("OnClick", function() PickColor(selected.colors.defaults.spell) end)
|
|
|
|
local damageNumber = SettingCheck(colorize, DAMAGE_NUMBER, SPELL_DAMAGE_NUMBER_COMBATLOG_TOOLTIP, "amountColoring")
|
|
damageNumber:SetPoint("TOPLEFT", spellSchool, "BOTTOMLEFT", -15, -8)
|
|
local damageSchool = SettingCheck(colorize, COLOR_BY_SCHOOL, SPELL_COLOR_BY_SCHOOL_COMBATLOG_TOOLTIP, "amountSchoolColoring", true)
|
|
damageSchool:SetPoint("TOPLEFT", damageNumber, "BOTTOMLEFT", 15, -2)
|
|
local damageSwatch = CreateSwatch(colorize)
|
|
damageSwatch:SetPoint("RIGHT", colorize, "RIGHT", -8, 0)
|
|
damageSwatch:SetPoint("TOP", damageNumber, "TOP", 0, -4)
|
|
damageSwatch:SetScript("OnClick", function() PickColor(selected.colors.defaults.damage) end)
|
|
|
|
local schoolNames = SettingCheck(colorize, DAMAGE_SCHOOL_TEXT, SPELL_DAMAGE_SCHOOL_COMBATLOG_TOOLTIP, "schoolNameColoring")
|
|
schoolNames:SetPoint("TOPLEFT", damageSchool, "BOTTOMLEFT", -15, -8)
|
|
|
|
local entireLine = SettingCheck(colorize, ENTIRE_LINE, ENTIRE_LINE_COMBATLOG_TOOLTIP, "lineColoring")
|
|
entireLine:SetPoint("TOPLEFT", schoolNames, "BOTTOMLEFT", 0, -8)
|
|
|
|
-- the two line color priorities, as radio buttons
|
|
local function PriorityCheck(text, tooltip, priority)
|
|
local check = CreateCheck(colorize, text, tooltip, true)
|
|
check.func = function()
|
|
selected.settings.lineColorPriority = priority
|
|
Edited()
|
|
end
|
|
return check
|
|
end
|
|
local bySource = PriorityCheck(BY_SOURCE, BY_SOURCE_COMBATLOG_TOOLTIP, 1)
|
|
bySource:SetPoint("TOPLEFT", entireLine, "BOTTOMLEFT", 15, -2)
|
|
local byTarget = PriorityCheck(BY_TARGET, BY_TARGET_COMBATLOG_TOOLTIP, 2)
|
|
byTarget:SetPoint("LEFT", bySource, "RIGHT", 80, 0)
|
|
|
|
-- Formatting
|
|
local formatting = CreateTab(FORMATTING)
|
|
CreateExamples(formatting)
|
|
|
|
local timestamp = SettingCheck(formatting, SHOW_TIMESTAMP, TIMESTAMP_COMBATLOG_TOOLTIP, "timestamp")
|
|
timestamp:SetPoint("TOPLEFT", formatting, "TOPLEFT", 25, -100)
|
|
local braces = SettingCheck(formatting, SHOW_BRACES, SHOW_BRACES_COMBATLOG_TOOLTIP, "braces")
|
|
braces:SetPoint("TOPLEFT", timestamp, "BOTTOMLEFT", 0, -15)
|
|
|
|
local unitBraces = CreateCheck(formatting, UNIT_NAMES, UNIT_NAMES_SHOW_BRACES_COMBATLOG_TOOLTIP, true)
|
|
unitBraces:SetPoint("TOPLEFT", braces, "BOTTOMLEFT", 15, -2)
|
|
unitBraces.func = function(self, checked)
|
|
local on = checked and true or false
|
|
selected.settings.unitBraces, selected.settings.sourceBraces, selected.settings.destBraces = on, on, on
|
|
Edited()
|
|
end
|
|
local spellBraces = SettingCheck(formatting, SPELL_NAMES, SPELL_NAMES_SHOW_BRACES_COMBATLOG_TOOLTIP, "spellBraces", true)
|
|
spellBraces:SetPoint("TOPLEFT", unitBraces, "BOTTOMLEFT", 0, -2)
|
|
local itemBraces = SettingCheck(formatting, ITEM_NAMES, ITEM_NAMES_SHOW_BRACES_COMBATLOG_TOOLTIP, "itemBraces", true)
|
|
itemBraces:SetPoint("TOPLEFT", spellBraces, "BOTTOMLEFT", 0, -2)
|
|
|
|
local fullText = SettingCheck(formatting, USE_FULL_TEXT_MODE, FULL_TEXT_COMBATLOG_TOOLTIP, "fullText")
|
|
fullText:SetPoint("TOPLEFT", itemBraces, "BOTTOMLEFT", -15, -13)
|
|
|
|
-- Settings: the filter's name and its quick button
|
|
local settings = CreateTab(SETTINGS)
|
|
|
|
local SetFilterName
|
|
local nameBox = CreateTextBox(nil, settings)
|
|
nameBox:SetSize(150, 20)
|
|
nameBox:SetMaxLetters(32)
|
|
nameBox:SetPoint("TOPLEFT", settings, "TOPLEFT", 37, -36)
|
|
nameBox:SetScript("OnEnterPressed", function()
|
|
SetFilterName(this:GetText())
|
|
this:ClearFocus()
|
|
end)
|
|
local nameLabel = settings:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
nameLabel:SetPoint("BOTTOMLEFT", nameBox, "TOPLEFT", 0, 4)
|
|
nameLabel:SetText(FILTER_NAME)
|
|
|
|
local saveButton = CreateButton(settings, SAVE, 78)
|
|
saveButton:SetPoint("LEFT", nameBox, "RIGHT", 8, 0)
|
|
saveButton:SetScript("OnClick", function()
|
|
SetFilterName(nameBox:GetText())
|
|
nameBox:ClearFocus()
|
|
end)
|
|
|
|
-- CombatConfig_SetFilterName
|
|
function SetFilterName(name)
|
|
if name == "" then
|
|
name = format(DEFAULT_COMBATLOG_FILTER_NAME, #log.GetFilters().filters)
|
|
end
|
|
selected.name = name
|
|
log.UpdateQuickButtons()
|
|
Update()
|
|
end
|
|
|
|
local quickButton = CreateCheck(settings, SHOW_QUICK_BUTTON, QUICK_BUTTON_COMBATLOG_TOOLTIP)
|
|
quickButton:SetPoint("TOPLEFT", nameBox, "BOTTOMLEFT", -6, -19)
|
|
quickButton.func = function(self, checked)
|
|
selected.hasQuickButton = checked and true or false
|
|
log.UpdateQuickButtons()
|
|
Update()
|
|
end
|
|
|
|
local quickDisplay = {}
|
|
for i, entry in ipairs({ { SOLO, "solo" }, { PARTY, "party" }, { RAID, "raid" } }) do
|
|
local key = entry[2]
|
|
local check = CreateCheck(settings, entry[1], nil, true)
|
|
check:SetPoint("TOPLEFT", quickButton, "BOTTOMLEFT", 20 + (i - 1) * 95, -2)
|
|
check.func = function(self, checked)
|
|
selected.quickButtonDisplay[key] = checked and true or false
|
|
log.UpdateQuickButtons()
|
|
end
|
|
check.key = key
|
|
quickDisplay[i] = check
|
|
end
|
|
|
|
--
|
|
-- Refresh (ChatConfig_UpdateCombatSettings)
|
|
--
|
|
local function UpdateColors()
|
|
for _, swatch in ipairs(unitColors.swatches) do
|
|
local color = selected.colors.unitColoring[swatch.flag]
|
|
swatch.prev:SetTexture(color.r, color.g, color.b)
|
|
end
|
|
for _, check in ipairs(highlightChecks) do
|
|
SetCheck(check, selected.settings[check.setting])
|
|
end
|
|
|
|
local s = selected.settings
|
|
SetCheck(unitNames, s.unitColoring)
|
|
SetCheck(spellNames, s.abilityColoring)
|
|
SetCheck(spellSchool, s.abilityColoring and s.abilitySchoolColoring)
|
|
SetCheckEnabled(spellSchool, s.abilityColoring)
|
|
spellSwatch.prev:SetTexture(selected.colors.defaults.spell.r, selected.colors.defaults.spell.g, selected.colors.defaults.spell.b)
|
|
SetCheck(damageNumber, s.amountColoring)
|
|
SetCheck(damageSchool, s.amountSchoolColoring)
|
|
SetCheckEnabled(damageSchool, s.amountColoring)
|
|
damageSwatch.prev:SetTexture(selected.colors.defaults.damage.r, selected.colors.defaults.damage.g, selected.colors.defaults.damage.b)
|
|
SetCheck(schoolNames, s.schoolNameColoring)
|
|
SetCheck(entireLine, s.lineColoring)
|
|
SetCheck(bySource, s.lineColorPriority == 1)
|
|
SetCheck(byTarget, s.lineColorPriority ~= 1)
|
|
SetCheckEnabled(bySource, s.lineColoring)
|
|
SetCheckEnabled(byTarget, s.lineColoring)
|
|
|
|
UpdateExamples(colors)
|
|
end
|
|
|
|
local function UpdateFormatting()
|
|
local s = selected.settings
|
|
SetCheck(timestamp, s.timestamp)
|
|
SetCheck(braces, s.braces)
|
|
SetCheck(unitBraces, s.unitBraces)
|
|
SetCheck(spellBraces, s.spellBraces)
|
|
SetCheck(itemBraces, s.itemBraces)
|
|
SetCheckEnabled(unitBraces, s.braces)
|
|
SetCheckEnabled(spellBraces, s.braces)
|
|
SetCheckEnabled(itemBraces, s.braces)
|
|
SetCheck(fullText, s.fullText)
|
|
|
|
UpdateExamples(formatting)
|
|
end
|
|
|
|
local function UpdateSettings()
|
|
nameBox:SetText(selected.name or "")
|
|
SetCheck(quickButton, selected.hasQuickButton)
|
|
for _, check in ipairs(quickDisplay) do
|
|
SetCheck(check, selected.quickButtonDisplay[check.key])
|
|
SetCheckEnabled(check, selected.hasQuickButton)
|
|
end
|
|
end
|
|
|
|
function Update()
|
|
local filters = log.GetFilters().filters
|
|
|
|
local entries = {}
|
|
for i, filter in ipairs(filters) do
|
|
entries[i] = { index = i, name = filter.name }
|
|
end
|
|
filterList.ScrollBox:SetDataProvider(CreateDataProvider(entries), ScrollBoxConstants.RetainScrollPosition)
|
|
|
|
-- the last filter can't be deleted
|
|
if #filters > 1 then deleteButton:Enable() else deleteButton:Disable() end
|
|
if #filters < MAX_COMBATLOG_FILTERS then
|
|
addButton:Enable()
|
|
copyButton:Enable()
|
|
else
|
|
addButton:Disable()
|
|
copyButton:Disable()
|
|
end
|
|
if selectedIndex > 1 then moveUp:Enable() else moveUp:Disable() end
|
|
if selectedIndex < #filters then moveDown:Enable() else moveDown:Disable() end
|
|
|
|
UpdateCheckboxList(doneBy)
|
|
UpdateCheckboxList(doneTo)
|
|
UpdateTieredList(typesLeft)
|
|
UpdateTieredList(typesRight)
|
|
UpdateTieredList(typesMisc)
|
|
UpdateColors()
|
|
UpdateFormatting()
|
|
UpdateSettings()
|
|
end
|
|
|
|
-- ChatConfigFilter_OnClick
|
|
function SelectFilter(index)
|
|
selectedIndex = index
|
|
selected = log.GetFilters().filters[index]
|
|
Update()
|
|
end
|
|
|
|
--
|
|
-- Defaults and Okay
|
|
--
|
|
local defaultsButton = CreateButton(frame, COMBATLOG_DEFAULTS, 170)
|
|
defaultsButton:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 12, 12)
|
|
defaultsButton:SetScript("OnClick", function()
|
|
CreateQuestionDialog(CONFIRM_COMBAT_FILTER_DEFAULTS, function()
|
|
log.Reset()
|
|
changed = nil
|
|
SelectFilter(1)
|
|
end)
|
|
end)
|
|
|
|
local okayButton = CreateButton(frame, OKAY, 78)
|
|
okayButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -12, 12)
|
|
okayButton:SetScript("OnClick", function()
|
|
PlaySound(SOUNDKIT.GS_TITLE_OPTION_OK)
|
|
frame:Hide()
|
|
end)
|
|
|
|
-- opens on the filter the log shows
|
|
frame:SetScript("OnShow", function()
|
|
changed = nil
|
|
SelectFilter(log.GetFilters().currentFilter)
|
|
end)
|
|
|
|
frame:SetScript("OnHide", function()
|
|
if changed then
|
|
changed = nil
|
|
log.SelectFilter(log.GetFilters().currentFilter)
|
|
end
|
|
end)
|
|
|
|
SelectTab(1)
|
|
return frame
|
|
end
|