chore: move addon into Chatter/ + add standard .gitignore
Matches the Exiles fork-layout convention (each addon in its own folder).
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
local mod = Chatter:NewModule("All Edge resizing","AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["All Edge resizing"]
|
||||
|
||||
function mod:Info()
|
||||
return L["Allows you to use the edge for resizing, instead of just the lower right corner."]
|
||||
end
|
||||
|
||||
local anchorPoints = { "TopLeft", "TopRight", "BottomLeft", "BottomRight", "Top", "Right", "Left", "Bottom" }
|
||||
|
||||
function mod:OnInitialize()
|
||||
|
||||
end
|
||||
|
||||
local function ChatFrame_StartResizing(self)
|
||||
local chatFrame = self:GetParent()
|
||||
if chatFrame.isLocked then return end
|
||||
if chatFrame.isDocked and chatFrame ~= DEFAULT_CHAT_FRAME then return end
|
||||
chatFrame.resizing = 1
|
||||
chatFrame:StartSizing(self.anchorPoint)
|
||||
end
|
||||
|
||||
local function ChatFrame_StopResizing(self)
|
||||
local chatFrame = self:GetParent()
|
||||
chatFrame:StopMovingOrSizing()
|
||||
if chatFrame == DEFAULT_CHAT_FRAME then
|
||||
FCF_DockUpdate()
|
||||
end
|
||||
chatFrame.resizing = nil
|
||||
FCF_SavePositionAndDimensions(chatFrame);
|
||||
end
|
||||
|
||||
function mod:SetChatWindowLocked(index, locked, ...)
|
||||
local f = _G["ChatFrame" .. index]
|
||||
for _, v in ipairs(anchorPoints) do
|
||||
local k = "resize" .. v
|
||||
if f[k] then
|
||||
f[k]:EnableMouse(not locked)
|
||||
end
|
||||
end
|
||||
return self.hooks.SetChatWindowLocked(index, locked, ...)
|
||||
end
|
||||
|
||||
function mod:MakeResizers(frame)
|
||||
local f = frame
|
||||
if not f.resizeTopLeft then
|
||||
f.background = _G[("ChatFrame%dBackground"):format(frame:GetID())]
|
||||
for _, v in ipairs(anchorPoints) do
|
||||
local k = "resize" .. v
|
||||
f[k] = CreateFrame("Button", "ChatFrame" .. frame:GetID() .. "Resize" .. v, f)
|
||||
f[k].anchorPoint = v:upper()
|
||||
f[k]:SetWidth(16)
|
||||
f[k]:SetHeight(16)
|
||||
f[k]:SetScript("OnMouseDown", ChatFrame_StartResizing)
|
||||
f[k]:SetScript("OnMouseUp", ChatFrame_StopResizing)
|
||||
LowerFrameLevel(f[k])
|
||||
end
|
||||
f.resizeTopLeft:SetPoint("TOPLEFT", f.background, -2, 2)
|
||||
f.resizeTopRight:SetPoint("TOPRIGHT", f.background, 2, 2)
|
||||
f.resizeBottomLeft:SetPoint("BOTTOMLEFT", f.background, -2, -3)
|
||||
f.resizeBottomRight:SetPoint("BOTTOMRIGHT", f.background, 2, -3)
|
||||
f.resizeTop:SetPoint("LEFT", f.resizeTopLeft, "RIGHT", 0, 0)
|
||||
f.resizeTop:SetPoint("RIGHT", f.resizeTopRight, "LEFT", 0, 0)
|
||||
f.resizeRight:SetPoint("TOP", f.resizeTopRight, "BOTTOM", 0, 0)
|
||||
f.resizeRight:SetPoint("BOTTOM", f.resizeBottomRight, "TOP", 0, 0)
|
||||
f.resizeBottom:SetPoint("LEFT", f.resizeBottomLeft, "RIGHT", 0, 0)
|
||||
f.resizeBottom:SetPoint("RIGHT", f.resizeBottomRight, "LEFT", 0, 0)
|
||||
f.resizeLeft:SetPoint("TOP", f.resizeTopLeft, "BOTTOM", 0, 0)
|
||||
f.resizeLeft:SetPoint("BOTTOM", f.resizeBottomLeft, "TOP", 0, 0)
|
||||
else
|
||||
f.resizeTopLeft:Show()
|
||||
f.resizeTopRight:Show()
|
||||
f.resizeBottomLeft:Show()
|
||||
f.resizeBottomRight:Show()
|
||||
f.resizeTop:Show()
|
||||
f.resizeTop:Show()
|
||||
f.resizeRight:Show()
|
||||
f.resizeRight:Show()
|
||||
f.resizeBottom:Show()
|
||||
f.resizeBottom:Show()
|
||||
f.resizeLeft:Show()
|
||||
f.resizeLeft:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:HideResizers(f)
|
||||
f.resizeTopLeft:Hide()
|
||||
f.resizeTopRight:Hide()
|
||||
f.resizeBottomLeft:Hide()
|
||||
f.resizeBottomRight:Hide()
|
||||
f.resizeTop:Hide()
|
||||
f.resizeTop:Hide()
|
||||
f.resizeRight:Hide()
|
||||
f.resizeRight:Hide()
|
||||
f.resizeBottom:Hide()
|
||||
f.resizeBottom:Hide()
|
||||
f.resizeLeft:Hide()
|
||||
f.resizeLeft:Hide()
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G[("ChatFrame%d"):format(i)]
|
||||
self:MakeResizers(f)
|
||||
local b = _G[("ChatFrame%dResizeButton"):format(i)]
|
||||
b:SetScript("OnShow", b.Hide)
|
||||
b:Hide()
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local f = _G[name]
|
||||
self:MakeResizers(f)
|
||||
local b = _G[("ChatFrame%dResizeButton"):format(f:GetID())]
|
||||
b:SetScript("OnShow", b.Hide)
|
||||
b:Hide()
|
||||
end
|
||||
self:RawHook("SetChatWindowLocked",true)
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame"..i]
|
||||
self:HideResizers(f)
|
||||
local b = _G[("ChatFrame%dResizeButton"):format(f:GetID())]
|
||||
b:SetScript("OnShow", b.Show)
|
||||
b:Show()
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local f = _G[name]
|
||||
self:HideResizers(f)
|
||||
local b = _G[("ChatFrame%dResizeButton"):format(f:GetID())]
|
||||
b:SetScript("OnShow", b.Show)
|
||||
b:Show()
|
||||
end
|
||||
self:UnhookAll()
|
||||
end
|
||||
@@ -0,0 +1,352 @@
|
||||
local mod = Chatter:NewModule("Alt Linking", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Alt Linking"]
|
||||
|
||||
local NAMES
|
||||
local GUILDNOTES
|
||||
local pairs = _G.pairs
|
||||
local select = _G.select
|
||||
local setmetatable = _G.setmetatable
|
||||
local tinsert = _G.tinsert
|
||||
local tremove = _G.tremove
|
||||
local type = _G.type
|
||||
local unpack = _G.unpack
|
||||
local strlower= _G.string.lower
|
||||
local gmatch = _G.string.gmatch
|
||||
|
||||
local leftBracket, rightBracket
|
||||
|
||||
local defaults = {
|
||||
realm = {},
|
||||
profile = {
|
||||
guildNotes=true,
|
||||
altNotesFallback=true,
|
||||
colorMode = "COLOR_MOD",
|
||||
color = {0.6, 0.6, 0.6},
|
||||
leftBracket = "[",
|
||||
rightBracket = "]",
|
||||
}
|
||||
}
|
||||
local colorModes = {
|
||||
COLOR_MOD = L["Use PlayerNames coloring"],
|
||||
CUSTOM = L["Use custom color"],
|
||||
CHANNEL = L["Use channel color"]
|
||||
}
|
||||
|
||||
local customColorNames = setmetatable({}, {
|
||||
__index = function(t, v)
|
||||
local r, g, b = unpack(mod.db.profile.color)
|
||||
t[v] = ("|cff%02x%02x%02x%s|r"):format(r * 255, g * 255, b * 255, v)
|
||||
return t[v]
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local options
|
||||
function mod:GetOptions()
|
||||
options = options or {
|
||||
guildNotes = {
|
||||
order=100,
|
||||
type = "toggle",
|
||||
name = L["Use guildnotes"],
|
||||
desc = L["Look in guildnotes for character names, unless a note is set manually"],
|
||||
get = function()
|
||||
return mod.db.profile.guildNotes
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.guildNotes = v
|
||||
mod:EnableGuildNotes(v)
|
||||
end,
|
||||
},
|
||||
altNotesFallback = {
|
||||
order=101,
|
||||
type = "toggle",
|
||||
name = L["Alt note fallback"],
|
||||
desc = L["If no name can be found for an 'alt' rank character, use entire note"],
|
||||
disabled = function()
|
||||
return not mod.db.profile.guildNotes
|
||||
end,
|
||||
get = function()
|
||||
return mod.db.profile.altNotesFallback
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.altNotesFallback = v
|
||||
mod:ScanGuildNotes()
|
||||
end,
|
||||
},
|
||||
colorMode = {
|
||||
order=110,
|
||||
type = "select",
|
||||
name = L["Name color"],
|
||||
desc = L["Set the coloring mode for alt names"],
|
||||
values = colorModes,
|
||||
get = function()
|
||||
return mod.db.profile.colorMode
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.colorMode = v
|
||||
end
|
||||
},
|
||||
color = {
|
||||
order=111,
|
||||
type = "color",
|
||||
name = L["Custom color"],
|
||||
desc = L["Select the custom color to use for alt names"],
|
||||
get = function()
|
||||
return unpack(mod.db.profile.color)
|
||||
end,
|
||||
set = function(info, r, g, b)
|
||||
mod.db.profile.color[1] = r
|
||||
mod.db.profile.color[2] = g
|
||||
mod.db.profile.color[3] = b
|
||||
for k, v in pairs(customColorNames) do
|
||||
customColorNames[k] = nil
|
||||
end
|
||||
end,
|
||||
disabled = function() return mod.db.profile.colorMode ~= "CUSTOM" end
|
||||
},
|
||||
leftbracket = {
|
||||
type = "input",
|
||||
name = L["Left Bracket"],
|
||||
desc = L["Character to use for the left bracket"],
|
||||
get = function() return mod.db.profile.leftBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.leftBracket = v
|
||||
leftBracket = v
|
||||
end
|
||||
},
|
||||
rightbracket = {
|
||||
type = "input",
|
||||
name = L["Right Bracket"],
|
||||
desc = L["Character to use for the right bracket"],
|
||||
get = function() return mod.db.profile.rightBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.rightBracket = v
|
||||
rightBracket = v
|
||||
end
|
||||
},
|
||||
}
|
||||
return options
|
||||
end
|
||||
|
||||
|
||||
|
||||
local accept = function(self, char)
|
||||
local editBox = _G[this:GetParent():GetName().."EditBox"]
|
||||
local main = editBox:GetText()
|
||||
mod:AddAlt(char, main)
|
||||
this:GetParent():Hide()
|
||||
end
|
||||
|
||||
StaticPopupDialogs['MENUITEM_SET_MAIN'] = {
|
||||
text = L["Who is %s's main?"],
|
||||
button1 = TEXT(ACCEPT),
|
||||
button2 = TEXT(CANCEL),
|
||||
hasEditBox = 1,
|
||||
maxLetters = 128,
|
||||
exclusive = 0,
|
||||
OnShow = function()
|
||||
_G[this:GetName().."EditBox"]:SetFocus()
|
||||
end,
|
||||
OnHide = function()
|
||||
if ( _G[this:GetName().."EditBox"]:IsShown() ) then
|
||||
_G[this:GetName().."EditBox"]:SetFocus();
|
||||
end
|
||||
_G[this:GetName().."EditBox"]:SetText("");
|
||||
end,
|
||||
OnAccept = accept,
|
||||
EditBoxOnEnterPressed = accept,
|
||||
EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
|
||||
timeout = 0,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1
|
||||
}
|
||||
|
||||
UnitPopupButtons["SET_MAIN"] = {
|
||||
text = L["Set Main"],
|
||||
dist = 0,
|
||||
func = mod.GetMainName
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("AltLinks", defaults)
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
NAMES = self.db.realm
|
||||
UnitPopupButtons["SET_MAIN"].func = self.GetMainName
|
||||
tinsert(UnitPopupMenus["SELF"], #UnitPopupMenus["SELF"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["PLAYER"], #UnitPopupMenus["PLAYER"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["FRIEND"], #UnitPopupMenus["FRIEND"] - 1, "SET_MAIN")
|
||||
tinsert(UnitPopupMenus["PARTY"], #UnitPopupMenus["PARTY"] - 1, "SET_MAIN")
|
||||
self:SecureHook("UnitPopup_ShowMenu")
|
||||
|
||||
leftBracket, rightBracket = self.db.profile.leftBracket, self.db.profile.rightBracket
|
||||
|
||||
mod:EnableGuildNotes(mod.db.profile.guildNotes)
|
||||
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
self.colorMod = Chatter:GetModule("Player Class Colors")
|
||||
end
|
||||
|
||||
local types = {"SELF", "PLAYER", "FRIEND", "PARTY"}
|
||||
function mod:OnDisable()
|
||||
for j = 1, #types do
|
||||
local t = types[j]
|
||||
for i = 1, #UnitPopupMenus[t] do
|
||||
if UnitPopupMenus[t][i] == "SET_MAIN" then
|
||||
tremove(UnitPopupMenus[t], i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
mod:EnableGuildNotes(false)
|
||||
end
|
||||
|
||||
|
||||
function mod.GetMainName()
|
||||
local alt = UIDROPDOWNMENU_INIT_MENU.name
|
||||
local popup = StaticPopup_Show("MENUITEM_SET_MAIN", alt)
|
||||
if popup then
|
||||
popup.data = alt
|
||||
local editbox = getglobal(popup:GetName().."EditBox")
|
||||
editbox:SetText(NAMES[alt] or GUILDNOTES[alt] or "")
|
||||
editbox:HighlightText()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:UnitPopup_ShowMenu(dropdownMenu, which, unit, name, userData, ...)
|
||||
for i=1, UIDROPDOWNMENU_MAXBUTTONS do
|
||||
local button = _G["DropDownList"..UIDROPDOWNMENU_MENU_LEVEL.."Button"..i];
|
||||
if button.value == "SET_MAIN" then
|
||||
button.func = UnitPopupButtons["SET_MAIN"].func
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:AddAlt(alt, main)
|
||||
if #main == 0 then
|
||||
if GUILDNOTES[alt] then
|
||||
-- let the user store an empty note, meaning "dont show me this main"
|
||||
else
|
||||
main = nil
|
||||
end
|
||||
end
|
||||
NAMES[alt] = main
|
||||
end
|
||||
|
||||
local function pName(msg, name)
|
||||
if name and #name > 0 then
|
||||
local alt = NAMES[name] or GUILDNOTES[name]
|
||||
if alt and alt ~= "" then -- empty notes can be stored to override guildnote data
|
||||
local mode = mod.db.profile.colorMode
|
||||
if mode == "CUSTOM" then
|
||||
alt = customColorNames[alt]
|
||||
elseif mode == "COLOR_MOD" and mod.colorMod and mod.colorMod:IsEnabled() then
|
||||
alt = mod.colorMod:ColorName(alt)
|
||||
end
|
||||
return ("%s%s%s%s"):format( msg, leftBracket, alt, rightBracket )
|
||||
end
|
||||
end
|
||||
return msg
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if text and type(text) == "string" then
|
||||
--text = text:gsub("(|Hplayer:([^:]+)[:%d+]*|h.-|h)", pName)
|
||||
text = text:gsub("(|Hplayer:([^:]+).-|h.-|h)", pName)
|
||||
end
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Enables you to right-click a person's name in chat and set a note on them to be displayed in chat, such as their main character's name. Can also scan guild notes for character names to display, if no note has been manually set."]
|
||||
end
|
||||
|
||||
function mod:EnableGuildNotes(enable)
|
||||
GUILDNOTES={}
|
||||
if enable then
|
||||
mod:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||
if IsInGuild() then
|
||||
GuildRoster()
|
||||
end
|
||||
mod:ScanGuildNotes() -- Unfortunately we can't count on GuildRoster() triggering the event if someone else triggered it recently. So we try once at first straight off the bat.
|
||||
else
|
||||
mod:UnregisterEvent("GUILD_ROSTER_UPDATE")
|
||||
end
|
||||
end
|
||||
|
||||
local doscan=true -- always the first time we start up
|
||||
function mod:GUILD_ROSTER_UPDATE(event,arg1)
|
||||
-- arg1 gets set for SOME changes to the guild, but notably not for player notes.. doh (unless you're the one editing them yourself)
|
||||
-- we force a scan when the guild frame is actually visible (i.e. when we know the player is actually interested in seeing changes)
|
||||
-- i'd like to be able to not have the guildframe check there, but there's plenty of stupid-ass addons that spam GuildRoster() every 10/15/20 seconds, so ... no.
|
||||
if arg1 or GuildFrame:IsVisible() or doscan then
|
||||
doscan=false
|
||||
mod:ScanGuildNotes()
|
||||
end
|
||||
|
||||
if arg1 then
|
||||
-- but it appears that when arg1 is set, the player note change isn't available yet; that happens on the next arg1=nil update (about 0.1s later), so catch that one too. ghod this is messy.
|
||||
doscan=true
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ScanGuildNotes()
|
||||
if not IsInGuild() then
|
||||
return
|
||||
end
|
||||
--DBG print("Scanning guildnotes!")
|
||||
--DBG local n,nFallback=0,0
|
||||
local names = {} -- ["playername"]="Playername" (note lowercase = uppercase) (yes, this works for 'foreign' letters too in WoW, even though it does not in standard Lua)
|
||||
GUILDNOTES = {} -- Yes, we do want to zap it, otherwise we end up storing notes for people being promoted/demoted through alt ranks and stuff
|
||||
|
||||
-- #1: find all names
|
||||
for i=1,GetNumGuildMembers(true) do
|
||||
local name = GetGuildRosterInfo(i)
|
||||
names[strlower(name or "?")] = name
|
||||
end
|
||||
|
||||
-- #2: scan all words in all guild notes, see if a name is mentioned
|
||||
for i=1,GetNumGuildMembers(true) do
|
||||
local name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i);
|
||||
local success
|
||||
for word in gmatch(strlower(note or ""), "[%a\128-\255]+") do
|
||||
if names[word] then
|
||||
GUILDNOTES[name] = names[word]
|
||||
success = true
|
||||
--DBG n=n+1
|
||||
break
|
||||
end
|
||||
end
|
||||
if not success and mod.db.profile.altNotesFallback and note and note~="" then
|
||||
-- #3: no joy? then if this is an 'alt' rank, use the entire note
|
||||
rank=strlower(rank or "")
|
||||
if strfind(rank, "alt") or
|
||||
strfind(rank, L["alt2"]) or
|
||||
strfind(rank, L["alt3"]) then
|
||||
GUILDNOTES[name] = note
|
||||
--DBG print("Fallback: ",note)
|
||||
--DBG nFallback=nFallback+1
|
||||
end
|
||||
end
|
||||
end
|
||||
--DBG print("Mapped",n,"names and",nFallback,"fallbacks!")
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
local mod = Chatter:NewModule("Chat Autolog")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Chat Autolog"]
|
||||
|
||||
function mod:OnEnable()
|
||||
self.isLogging = LoggingChat()
|
||||
LoggingChat(true)
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
LoggingChat(self.isLogging)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Automatically turns on chat logging."]
|
||||
end
|
||||
@@ -0,0 +1,84 @@
|
||||
local mod = Chatter:NewModule("Automatic Whisper Windows", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Automatic Whisper Windows"]
|
||||
|
||||
function mod:OnEnable()
|
||||
self:RegisterEvent("CHAT_MSG_WHISPER","ProcessWhisper")
|
||||
self:RegisterEvent("CHAT_MSG_WHISPER_INFORM","ProcessWhisper")
|
||||
self:RegisterEvent("CHAT_MSG_BN_WHISPER_INFORM", "ProcessWhisper")
|
||||
self:RegisterEvent("CHAT_MSG_BN_WHISPER","ProcessWhisper")
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
self:UnregisterEvent("CHAT_MSG_WHISPER")
|
||||
self:UnregisterEvent("CHAT_MSG_WHISPER_INFORM")
|
||||
self:UnregisterEvent("CHAT_MSG_BNWHISPER")
|
||||
self:UnregisterEvent("CHAT_MSG_BNWHISPER_INFORM")
|
||||
end
|
||||
|
||||
function mod:AlwaysDecorate(frame)
|
||||
if not self:IsEnabled() then
|
||||
local t = frame.chatType
|
||||
local a = frame.chatTarget
|
||||
local accessID = ChatHistory_GetAccessID(t, a)
|
||||
local chatFrame = nil
|
||||
for i= 1,NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame"..i]
|
||||
local i = cf:GetNumMessages(accessID)
|
||||
if i > 0 then
|
||||
chatFrame = cf
|
||||
end
|
||||
end
|
||||
if chatFrame then
|
||||
Chatter.loading = true
|
||||
for i = 1, chatFrame:GetNumMessages(accessID) do
|
||||
local text, accessID, lineID, extraData = chatFrame:GetMessageInfo(i, accessID);
|
||||
local cType, cTarget = ChatHistory_GetChatType(extraData);
|
||||
local info = ChatTypeInfo[cType];
|
||||
frame:AddMessage(text, info.r, info.g, info.b, lineID, false, accessID, extraData);
|
||||
end
|
||||
Chatter.loading = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mod:ProcessWhisper(event,message,sender,language,channelString,target,flags,arg7,arg8,...)
|
||||
-- Do we have a temp window already for this target
|
||||
local type = "WHISPER"
|
||||
if event == "CHAT_MSG_BN_WHISPER" or event == "CHAT_MSG_BN_WHISPER_INFORM" then
|
||||
type = "BN_WHISPER"
|
||||
end
|
||||
if FCFManager_GetNumDedicatedFrames(type, sender) == 0 then
|
||||
local chatFrame = nil
|
||||
local foundSrc = false
|
||||
local accessID = ChatHistory_GetAccessID(type, sender)
|
||||
for i= 1,NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame"..i]
|
||||
if not foundSrc then
|
||||
for i = 1, cf:GetNumMessages(accessID) do
|
||||
chatFrame = cf
|
||||
foundSrc = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not chatFrame then
|
||||
return true
|
||||
end
|
||||
Chatter.loading = true
|
||||
local t = FCF_OpenTemporaryWindow(type, sender, chatFrame, true)
|
||||
-- lets hand copy the shit over
|
||||
for i = 1, chatFrame:GetNumMessages(accessID) do
|
||||
local text, accessID, lineID, extraData = chatFrame:GetMessageInfo(i, accessID);
|
||||
local cType, cTarget = ChatHistory_GetChatType(extraData);
|
||||
local info = ChatTypeInfo[cType];
|
||||
t:AddMessage(text, info.r, info.g, info.b, lineID, false, accessID, extraData);
|
||||
end
|
||||
Chatter.loading = false
|
||||
-- was a fix for an issue in the editbox, no longer needed
|
||||
--for i=1,NUM_CHAT_WINDOWS do
|
||||
-- local cf = _G["ChatFrame"..i.."EditBox"]
|
||||
-- cf:Show()
|
||||
--end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,131 @@
|
||||
-- Strip icons like |TInterface\\FriendsFrame\\UI-Toast-ToastIcons.tga:16:16:0:0:128:64:2:29:34:61
|
||||
local mod = Chatter:NewModule("BNet", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["RealID Polish"]
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
toastx = 0,
|
||||
toasty = 0,
|
||||
showToast = false
|
||||
}
|
||||
}
|
||||
|
||||
local options
|
||||
function mod:GetOptions()
|
||||
options = options or {
|
||||
showToastIcons = {
|
||||
order=100,
|
||||
type = "toggle",
|
||||
name = L["Show Toast Icons"],
|
||||
desc = L["Show toast icons in the chat frames"],
|
||||
get = function()
|
||||
return mod.db.profile.showToast
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.showToast = v
|
||||
end,
|
||||
},
|
||||
toastWindowXoffset = {
|
||||
order=101,
|
||||
type = "range",
|
||||
min = -4000,
|
||||
max = 4000,
|
||||
name = L["Toast X offset"],
|
||||
desc = L["Move the Toast X offset to ChatFrame1"],
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function()
|
||||
return mod.db.profile.toastx
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.toastx = v
|
||||
mod:UpdateToastOffsets()
|
||||
end,
|
||||
},
|
||||
toastWindowYoffset = {
|
||||
order=102,
|
||||
type = "range",
|
||||
min = -4000,
|
||||
max = 4000,
|
||||
name = L["Toast Y offset"],
|
||||
desc = L["Move the Toast Y offset, relative to ChatFrame1"],
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function()
|
||||
return mod.db.profile.toasty
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.toasty = v
|
||||
mod:UpdateToastOffsets()
|
||||
end,
|
||||
},
|
||||
testToast = {
|
||||
order=103,
|
||||
name = L["Test"],
|
||||
type = "execute",
|
||||
func = function() BNToastFrame_AddToast(BN_TOAST_TYPE_NEW_INVITE) end,
|
||||
}
|
||||
}
|
||||
return options
|
||||
end
|
||||
|
||||
|
||||
function mod:UpdateToastOffsets()
|
||||
if self:IsEnabled() then
|
||||
local cf = DEFAULT_CHAT_FRAME
|
||||
local bside = cf.buttonSide
|
||||
local cfTop = cf.buttonFrame:GetTop() or 0
|
||||
local bnH = BNToastFrame:GetHeight() or 0
|
||||
local offscreen = cfTop + bnH + BN_TOAST_TOP_OFFSET + BN_TOAST_TOP_BUFFER > GetScreenHeight();
|
||||
BN_TOAST_LEFT_OFFSET = 1 + self.db.profile.toastx
|
||||
if bside == "right" then
|
||||
BN_TOAST_RIGHT_OFFSET = -1 + self.db.profile.toastx
|
||||
end
|
||||
BN_TOAST_TOP_OFFSET = 40 + self.db.profile.toasty
|
||||
if offscreen then
|
||||
BN_TOAST_BOTTOM_OFFSET = -12 + self.db.profile.toasty
|
||||
end
|
||||
BNToastFrame_UpdateAnchor(true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("RealIdPolish", defaults)
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
self:UnhookAll()
|
||||
BN_TOAST_TOP_OFFSET = 40
|
||||
BN_TOAST_BOTTOM_OFFSET = -12
|
||||
BN_TOAST_RIGHT_OFFSET = -1
|
||||
BN_TOAST_LEFT_OFFSET = 1
|
||||
BN_TOAST_TOP_BUFFER = 20
|
||||
BN_TOAST_MAX_LINE_WIDTH = 196
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
self:Hook("BNToastFrame_Close",true)
|
||||
self:UpdateToastOffsets()
|
||||
end
|
||||
|
||||
function mod:BNToastFrame_Close()
|
||||
self:UpdateToastOffsets()
|
||||
end
|
||||
|
||||
function mod:ParseLinks(text)
|
||||
if not text then return nil end
|
||||
if mod.db.profile.showToast then return text end
|
||||
text = gsub(text, "(|TInterface(.*)ToastIcons.tga([:%d]*)|t)", "")
|
||||
return text
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
return self.hooks[frame].AddMessage(frame, mod:ParseLinks(text), ...)
|
||||
end
|
||||
@@ -0,0 +1,234 @@
|
||||
local mod = Chatter:NewModule("Disable Buttons", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
|
||||
mod.modName = L["Disable Buttons"]
|
||||
|
||||
local fmt = _G.string.format
|
||||
local function hide(self)
|
||||
if not self.override then
|
||||
self:Hide()
|
||||
end
|
||||
self.override = nil
|
||||
end
|
||||
|
||||
local options = {
|
||||
bottomButton = {
|
||||
type = "toggle",
|
||||
name = L["Show bottom when scrolled"],
|
||||
desc = L["Show bottom button when scrolled up"],
|
||||
width = "double",
|
||||
get = function()
|
||||
return mod.db.profile.scrollReminder
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.scrollReminder = v
|
||||
if v then
|
||||
mod:EnableBottomButton()
|
||||
else
|
||||
mod:DisableBottomButton()
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local bottomButtons = {}
|
||||
|
||||
local defaults = { profile = {} }
|
||||
local clickFunc = function(self) self:GetParent():ScrollToBottom() end
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Buttons", defaults)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
local button = CreateFrame("Button", nil, f)
|
||||
button:SetNormalTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Up]])
|
||||
button:SetPushedTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Down]])
|
||||
button:SetDisabledTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Disabled]])
|
||||
button:SetHighlightTexture([[Interface\Buttons\UI-Common-MouseHilight]])
|
||||
button:SetWidth(20)
|
||||
button:SetHeight(20)
|
||||
button:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0)
|
||||
button:SetScript("OnClick", clickFunc)
|
||||
button:Hide()
|
||||
f.downButton = button
|
||||
end
|
||||
self:SecureHook("FCF_RestorePositionAndDimensions")
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
local button = CreateFrame("Button", nil, frame)
|
||||
button:SetNormalTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Up]])
|
||||
button:SetPushedTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Down]])
|
||||
button:SetDisabledTexture([[Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Disabled]])
|
||||
button:SetHighlightTexture([[Interface\Buttons\UI-Common-MouseHilight]])
|
||||
button:SetWidth(20)
|
||||
button:SetHeight(20)
|
||||
button:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, 0)
|
||||
button:SetScript("OnClick", clickFunc)
|
||||
button:Hide()
|
||||
frame.downButton = button
|
||||
-- Adjust the menu buttons
|
||||
self:ApplyFrameChanges(frame)
|
||||
if(self.db.profile.scrollReminder) then self:ApplyBottomButton(frame) end
|
||||
end
|
||||
|
||||
function mod:FCF_RestorePositionAndDimensions(chatFrame)
|
||||
if Chatter.db.profile.modules[mod:GetName()] then
|
||||
chatFrame:SetClampRectInsets(0, 0, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Fix the jump in
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
f:SetClampRectInsets(0, 0, 0, 0)
|
||||
end
|
||||
|
||||
function mod:ApplyFrameChanges(f)
|
||||
f:SetClampRectInsets(0, 0, 0, 0)
|
||||
local ff = _G[f:GetName() .. "ButtonFrame"]
|
||||
ff:Hide()
|
||||
ff:SetScript("OnShow", hide)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
ChatFrameMenuButton:Hide()
|
||||
ChatFrameMenuButton:SetScript("OnShow", hide)
|
||||
FriendsMicroButton:Hide()
|
||||
FriendsMicroButton:SetScript("OnShow", hide)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
self:ApplyFrameChanges(f)
|
||||
end
|
||||
if(self.db.profile.scrollReminder) then self:EnableBottomButton() end
|
||||
for index,frame in ipairs(self.TempChatFrames) do
|
||||
local f = _G[frame]
|
||||
self:ApplyFrameChanges(f)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:UnDecorate(frame)
|
||||
frame:SetClampRectInsets(-35, 35, 26, -50)
|
||||
-- Reset the postion so if the buttons were offscreen frame goes to where it should be
|
||||
if frame:IsMovable() then
|
||||
FCF_RestorePositionAndDimensions(frame)
|
||||
end
|
||||
local ff = _G[frame:GetName() .. "ButtonFrame"]
|
||||
ff:Show()
|
||||
ff:SetScript("OnShow", nil)
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
ChatFrameMenuButton:Show()
|
||||
ChatFrameMenuButton:SetScript("OnShow", nil)
|
||||
FriendsMicroButton:Show()
|
||||
FriendsMicroButton:SetScript("OnShow", nil)
|
||||
self:DisableBottomButton()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
self:UnDecorate(f)
|
||||
end
|
||||
for index,frame in ipairs(self.TempChatFrames) do
|
||||
local f = _G[frame]
|
||||
self:UnDecorate(f)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Hides the buttons attached to the chat frame"]
|
||||
end
|
||||
|
||||
function mod:ApplyBottomButton(frame)
|
||||
if self:IsHooked(frame,"ScrollUp") then
|
||||
return nil
|
||||
end
|
||||
self:Hook(frame, "ScrollUp", true)
|
||||
self:Hook(frame, "ScrollToTop", "ScrollUp", true)
|
||||
self:Hook(frame, "PageUp", "ScrollUp", true)
|
||||
self:Hook(frame, "ScrollDown", true)
|
||||
self:Hook(frame, "ScrollToBottom", "ScrollDownForce", true)
|
||||
self:Hook(frame, "PageDown", "ScrollDown", true)
|
||||
if frame:GetCurrentScroll() ~= 0 then
|
||||
frame.downButton:Show()
|
||||
end
|
||||
if frame ~= COMBATLOG then
|
||||
self:Hook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:EnableBottomButton()
|
||||
if self.buttonsEnabled then return end
|
||||
self.buttonsEnabled = true
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
if f then
|
||||
self:ApplyBottomButton(f)
|
||||
end
|
||||
end
|
||||
for index,frame in ipairs(self.TempChatFrames) do
|
||||
local f = _G[frame]
|
||||
if f then
|
||||
self:ApplyBottomButton(f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:UnApplyBottomButton(f)
|
||||
self:Unhook(f, "ScrollUp")
|
||||
self:Unhook(f, "ScrollToTop")
|
||||
self:Unhook(f, "PageUp")
|
||||
self:Unhook(f, "ScrollDown")
|
||||
self:Unhook(f, "ScrollToBottom")
|
||||
self:Unhook(f, "PageDown")
|
||||
if f ~= COMBATLOG then
|
||||
self:Unhook(f, "AddMessage")
|
||||
end
|
||||
f.downButton:Hide()
|
||||
end
|
||||
|
||||
function mod:DisableBottomButton()
|
||||
if not self.buttonsEnabled then return end
|
||||
self.buttonsEnabled = false
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i]
|
||||
if f then
|
||||
self:UnApplyBottomButton(f)
|
||||
end
|
||||
end
|
||||
for index,frame in ipairs(self.TempChatFrames) do
|
||||
local f = _G[frame]
|
||||
if f then
|
||||
self:UnApplyBottomButton(f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ScrollUp(frame)
|
||||
frame.downButton:Show()
|
||||
frame.downButton:UnlockHighlight()
|
||||
end
|
||||
|
||||
function mod:ScrollDown(frame)
|
||||
if frame:GetCurrentScroll() == 0 then
|
||||
frame.downButton:Hide()
|
||||
frame.downButton:UnlockHighlight()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ScrollDownForce(frame)
|
||||
frame.downButton:Hide()
|
||||
frame.downButton:UnlockHighlight()
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if frame:GetCurrentScroll() > 0 then
|
||||
frame.downButton:Show()
|
||||
frame.downButton:LockHighlight()
|
||||
else
|
||||
frame.downButton:Hide()
|
||||
frame.downButton:UnlockHighlight()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,114 @@
|
||||
local mod = Chatter:NewModule("Channel Colors", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Channel Colors"]
|
||||
local GetChannelList = _G.GetChannelList
|
||||
local GetChannelName = _G.GetChannelName
|
||||
local GetMessageTypeColor = _G.GetMessageTypeColor
|
||||
local select = _G.select
|
||||
local tonumber = _G.tonumber
|
||||
local type = _G.type
|
||||
|
||||
function mod:Info()
|
||||
return L["Keeps your channel colors by name rather than by number."]
|
||||
end
|
||||
|
||||
local defaults = {
|
||||
profile = { colors = {} }
|
||||
}
|
||||
|
||||
local options = {
|
||||
splitter = {
|
||||
type = "header",
|
||||
name = L["Other Channels"],
|
||||
order = 49
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("ChannelColors", defaults)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
self:RegisterEvent("UPDATE_CHAT_COLOR")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
||||
self:AddChannels(GetChannelList())
|
||||
self:AddChannels(
|
||||
"SAY", L["Say"],
|
||||
"YELL", L["Yell"],
|
||||
"GUILD", L["Guild"],
|
||||
"OFFICER", L["Officer"],
|
||||
"PARTY", L["Party"],
|
||||
"PARTY_LEADER", PARTY_LEADER,
|
||||
"RAID", L["Raid"],
|
||||
"RAID_LEADER", L["Raid Leader"],
|
||||
"RAID_WARNING", L["Raid Warning"],
|
||||
"BATTLEGROUND", L["Battleground"],
|
||||
"BATTLEGROUND_LEADER", L["Battleground Leader"],
|
||||
"WHISPER", L["Whisper"],
|
||||
"BN_WHISPER", L["RealID Whisper"],
|
||||
"BN_CONVERSATION", L["RealID Conversation"]
|
||||
)
|
||||
end
|
||||
|
||||
function mod:AddChannels(...)
|
||||
for i = 1, select("#", ...), 2 do
|
||||
local id, name = select(i, ...)
|
||||
self.db.profile.colors[name] = self.db.profile.colors[name] or {}
|
||||
if not self.db.profile.colors[name].r then
|
||||
local r, g, b = GetMessageTypeColor(type(id) == "number" and ("CHANNEL" .. id) or id)
|
||||
self.db.profile.colors[name].r = r
|
||||
self.db.profile.colors[name].g = g
|
||||
self.db.profile.colors[name].b = b
|
||||
end
|
||||
if not options[name:gsub(" ", "_")] then
|
||||
options[name:gsub(" ", "_")] = {
|
||||
type = "color",
|
||||
name = name,
|
||||
desc = L["Select a color for this channel"],
|
||||
order = type(id) == "number" and (50 + id) or 48,
|
||||
get = function()
|
||||
local c = self.db.profile.colors[name]
|
||||
if c then
|
||||
return c.r, c.g, c.b
|
||||
else
|
||||
return GetMessageTypeColor(type(id) == "number" and ("CHANNEL" .. id) or id)
|
||||
end
|
||||
end,
|
||||
set = function(info, r, g, b)
|
||||
self.db.profile.colors[name] = self.db.profile.colors[name] or {}
|
||||
self.db.profile.colors[name].r = r
|
||||
self.db.profile.colors[name].g = g
|
||||
self.db.profile.colors[name].b = b
|
||||
ChangeChatColor(type(id) == "number" and ("CHANNEL" .. id) or id, r, g, b);
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:CHAT_MSG_CHANNEL_NOTICE(evt, notice, _, _, fullname, _, _, channelType, channelNumber, channelName)
|
||||
if notice == "YOU_JOINED" then
|
||||
self:AddChannels(GetChannelList())
|
||||
channelName = channelName:match("^(%w+)")
|
||||
local c = self.db.profile.colors[channelName]
|
||||
if c then
|
||||
ChangeChatColor("CHANNEL" .. channelNumber, c.r, c.g, c.b);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:UPDATE_CHAT_COLOR(evt, chan, r, g, b)
|
||||
if chan then
|
||||
local num = tonumber(chan:match("(%d+)$"))
|
||||
local channelNum = num and select(2, GetChannelName(num))
|
||||
local name = channelNum and channelNum:match("^(%w+)") or chan
|
||||
self.db.profile.colors[name] = self.db.profile.colors[name] or {}
|
||||
self.db.profile.colors[name].r = r
|
||||
self.db.profile.colors[name].g = g
|
||||
self.db.profile.colors[name].b = b
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,199 @@
|
||||
local mod = Chatter:NewModule("Channel Names", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Channel Names"]
|
||||
|
||||
local gsub = _G.string.gsub
|
||||
local find = _G.string.find
|
||||
local pairs = _G.pairs
|
||||
local loadstring = _G.loadstring
|
||||
local tostring = _G.tostring
|
||||
local GetChannelList = _G.GetChannelList
|
||||
local select = _G.select
|
||||
|
||||
local empty_tag = L["$$EMPTY$$"];
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
channels = {
|
||||
[L["Guild"]] = "[G]",
|
||||
[L["Officer"]] = "[O]",
|
||||
[L["Party"]] = "[P]",
|
||||
[PARTY_LEADER] = "[PL]",
|
||||
[L["Dungeon Guide"]] = "[DG]",
|
||||
[L["Raid"]] = "[R]",
|
||||
[L["Raid Leader"]] = "[RL]",
|
||||
[L["Raid Warning"]] = "[RW]",
|
||||
[L["LookingForGroup"]] = "[LFG]",
|
||||
[L["Battleground"]] = "[BG]",
|
||||
[L["Battleground Leader"]] = "[BL]",
|
||||
-- Not localized here intentionally
|
||||
["Whisper From"] = "[W:From]",
|
||||
["Whisper To"] = "[W:To]",
|
||||
["BN Whisper From"] = "[BN:From]",
|
||||
["BN Whisper To"] = "[BN:To]",
|
||||
["away BN Whisper To"] = "<Away>[BN:To]",
|
||||
["busy BN Whisper To"] = "<Busy>[BN:To]"
|
||||
},
|
||||
addSpace = true
|
||||
}
|
||||
}
|
||||
|
||||
local channels
|
||||
|
||||
local options = {
|
||||
splitter = {
|
||||
type = "header",
|
||||
name = L["Custom Channels"]
|
||||
},
|
||||
addSpace = {
|
||||
type = "toggle",
|
||||
name = L["Add space after channels"],
|
||||
desc = L["Add space after channels"],
|
||||
get = function() return mod.db.profile.addSpace end,
|
||||
set = function(info, v) mod.db.profile.addSpace = v end
|
||||
}
|
||||
}
|
||||
|
||||
local serverChannels = {}
|
||||
local function excludeChannels(...)
|
||||
for i = 1, select("#", ...) do
|
||||
local name = select(i, ...)
|
||||
serverChannels[name] = true
|
||||
end
|
||||
end
|
||||
local functions = {}
|
||||
|
||||
local function addChannel(name)
|
||||
options[name:gsub(" ", "_")] = {
|
||||
type = "input",
|
||||
name = name,
|
||||
desc = L["Replace this channel name with..."],
|
||||
order = name:lower() == name and 101 or 98,
|
||||
get = function()
|
||||
local v = mod.db.profile.channels[name]
|
||||
return v == "" and " " or v
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.channels[name] = #v > 0 and v or nil
|
||||
if v:match("^function%(") then
|
||||
functions[name] = loadstring("return " .. v)()
|
||||
else
|
||||
functions[name] = nil
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("ChannelNames", defaults)
|
||||
self.db.profile.customChannels = nil
|
||||
for k, _ in pairs(self.db.profile.channels) do
|
||||
addChannel(k)
|
||||
end
|
||||
excludeChannels(EnumerateServerChannels())
|
||||
for k, v in pairs(serverChannels) do
|
||||
addChannel(k)
|
||||
end
|
||||
self:AddCustomChannels(GetChannelList())
|
||||
|
||||
for k, v in pairs(self.db.profile.channels) do
|
||||
if v:match("^function%(") then
|
||||
functions[k] = loadstring("return " .. v)()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:AddCustomChannels(...)
|
||||
for i = 1, select("#", ...), 2 do
|
||||
local id, name = select(i, ...)
|
||||
if not serverChannels[name] and not options[name:gsub(" ", "_")] then
|
||||
options[name:gsub(" ", "_")] = {
|
||||
type = "input",
|
||||
name = name,
|
||||
desc = L["Replace this channel name with..."],
|
||||
order = id <= 4 and 98 or 101,
|
||||
get = function()
|
||||
local v = self.db.profile.channels[name:lower()]
|
||||
return v == "" and " " or v
|
||||
end,
|
||||
set = function(info, v)
|
||||
self.db.profile.channels[name:lower()] = #v > 0 and v or nil
|
||||
if v:match("^function%(") then
|
||||
functions[name:lower()] = loadstring("return " .. v)()
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
channels = self.db.profile.channels
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:CHAT_MSG_CHANNEL_NOTICE()
|
||||
self:AddCustomChannels(GetChannelList())
|
||||
end
|
||||
|
||||
local function replaceChannel(origChannel, msg, num, channel)
|
||||
local f = functions[channel] or functions[channel:lower()]
|
||||
local newChannelName = f and f(channel) or channels[channel] or channels[channel:lower()] or msg
|
||||
if newChannelName == empty_tag then return "" end
|
||||
return ("|Hchannel:%s|h%s|h%s"):format(origChannel, newChannelName, mod.db.profile.addSpace and " " or "")
|
||||
end
|
||||
|
||||
local function replaceChannelRW(msg, channel)
|
||||
local f = functions[channel] or functions[channel:lower()]
|
||||
local newChannelName = f and f(channel) or channels[channel] or channels[channel:lower()] or msg
|
||||
return newChannelName .. (mod.db.profile.addSpace and " " or "")
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if not text then
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
-- removed the start of check, since blizz timestamps inject themselves in front of the line
|
||||
if (CHAT_TIMESTAMP_FORMAT) then
|
||||
text = gsub(text, "|Hchannel:(%S-)|h(%[([%d. ]*)([^%]]+)%])|h ", replaceChannel)
|
||||
text = gsub(text, "(%[(" .. L["Raid Warning"] .. ")%]) ", replaceChannelRW)
|
||||
else
|
||||
text = gsub(text, "^|Hchannel:(%S-)|h(%[([%d. ]*)([^%]]+)%])|h ", replaceChannel)
|
||||
text = gsub(text, "^(%[(" .. L["Raid Warning"] .. ")%]) ", replaceChannelRW)
|
||||
end
|
||||
text = gsub(text, L["To (|Hplayer.-|h):"], mod.db.profile.channels["Whisper To"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
text = gsub(text, L["(|Hplayer.-|h) whispers:"], mod.db.profile.channels["Whisper From"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
text = gsub(text, L["To (|HBNplayer.-|h):"], mod.db.profile.channels["BN Whisper To"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
text = gsub(text, L["To <Away>(|HBNplayer.-|h):"], mod.db.profile.channels["away BN Whisper To"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
text = gsub(text, L["To <Busy>(|HBNplayer.-|h):"], mod.db.profile.channels["busy BN Whisper To"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
text = gsub(text, L["(|HBNplayer.-|h) whispers:"], mod.db.profile.channels["BN Whisper From"] .. (mod.db.profile.addSpace and " %1:" or "%1:"))
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Enables you to replace channel names with your own names. You can use '%s' to force an empty string."]:format( empty_tag )
|
||||
end
|
||||
|
||||
mod.funcs = functions
|
||||
@@ -0,0 +1,38 @@
|
||||
local mod = Chatter:NewModule("Disable Fading")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Disable Fading"]
|
||||
mod.toggleLabel = L["Disable Fading"]
|
||||
|
||||
function mod:Decorate(cf)
|
||||
cf:SetFading(nil)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetFading(nil)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetFading(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetFading(true)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetFading(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Makes old text disappear rather than fade out"]
|
||||
end
|
||||
@@ -0,0 +1,182 @@
|
||||
local mod = Chatter:NewModule("Chat Font", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Chat Font"]
|
||||
|
||||
local Media = LibStub("LibSharedMedia-3.0")
|
||||
local pairs = _G.pairs
|
||||
local player_entered_world = false
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
frames = {}
|
||||
}
|
||||
}
|
||||
|
||||
local outlines = {[""] = "None", ["OUTLINE"] = "Outline", ["THICKOUTLINE"] = "Thick Outline"}
|
||||
|
||||
local options = {
|
||||
font = {
|
||||
type = "select",
|
||||
name = L["Font"],
|
||||
desc = L["Font"],
|
||||
dialogControl = 'LSM30_Font',
|
||||
values = Media:HashTable("font"),
|
||||
get = function() return mod.db.profile.font end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.font = v
|
||||
mod:SetFont(nil, v)
|
||||
end
|
||||
},
|
||||
fontsize = {
|
||||
type = "range",
|
||||
name = L["Font size"],
|
||||
desc = L["Font size"],
|
||||
min = 4,
|
||||
max = 30,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.fontsize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.fontsize = v
|
||||
mod:SetFont(nil, nil, v)
|
||||
end
|
||||
},
|
||||
outline = {
|
||||
type = "select",
|
||||
name = L["Font Outline"],
|
||||
desc = L["Font outlining"],
|
||||
values = outlines,
|
||||
get = function() return mod.db.profile.outline or "" end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.outline = v
|
||||
mod:SetFont(nil, nil, nil, v)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
defaults.profile.frames["FRAME_" .. i] = {}
|
||||
end
|
||||
self.db = Chatter.db:RegisterNamespace("ChatFont", defaults)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
local t = {
|
||||
type = "group",
|
||||
name = L["Chat Frame "] .. i,
|
||||
desc = L["Chat Frame "] .. i,
|
||||
args = {
|
||||
fontsize = {
|
||||
type = "range",
|
||||
name = L["Font size"],
|
||||
desc = L["Font size"],
|
||||
min = 4,
|
||||
max = 30,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.frames["FRAME_" .. i].fontsize or mod.db.profile.fontsize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames["FRAME_" .. i].fontsize = v
|
||||
mod:SetFont(cf, nil, v)
|
||||
end
|
||||
},
|
||||
font = {
|
||||
type = "select",
|
||||
name = L["Font"],
|
||||
desc = L["Font"],
|
||||
dialogControl = 'LSM30_Font',
|
||||
values = Media:HashTable("font"),
|
||||
get = function() return mod.db.profile.frames["FRAME_" .. i].font or mod.db.profile.font end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames["FRAME_" .. i].font = v
|
||||
mod:SetFont(cf, v)
|
||||
end
|
||||
},
|
||||
outline = {
|
||||
type = "select",
|
||||
name = L["Font Outline"],
|
||||
desc = L["Font outlining"],
|
||||
values = outlines,
|
||||
get = function() return mod.db.profile.frames["FRAME_" .. i].outline or "" end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames["FRAME_" .. i].outline = v
|
||||
mod:SetFont(cf, nil, nil, v)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
options["frame" .. i] = t
|
||||
end
|
||||
end
|
||||
|
||||
function mod:LibSharedMedia_Registered()
|
||||
self:SetFont()
|
||||
end
|
||||
|
||||
function mod:Popout(frame,src)
|
||||
local fontName, fontHeight, fontFlags = src:GetFont()
|
||||
frame:SetFont(fontName,fontHeight,fontFlags)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
Media.RegisterCallback(mod, "LibSharedMedia_Registered")
|
||||
self:LibSharedMedia_Registered()
|
||||
if not player_entered_world then
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
end
|
||||
end
|
||||
|
||||
function mod:PLAYER_ENTERING_WORLD()
|
||||
self:SetFont()
|
||||
self:UnregisterAllEvents()
|
||||
player_entered_world = true
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
Media.UnregisterCallback(mod, "LibSharedMedia_Registered")
|
||||
self:SetFont(nil, "Arial Narrow", 12, "")
|
||||
end
|
||||
|
||||
function mod:SetFont(cf, font, size, outline)
|
||||
if cf then
|
||||
self:SetFrameFont(cf, font, size, outline)
|
||||
else
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
cf = _G["ChatFrame" .. i]
|
||||
self:SetFrameFont(cf, font, size, outline)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:SetFrameFont(cf, font, size, outline)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:SetFrameFont(cf, font, size, outline)
|
||||
local f = "FRAME_" .. cf:GetName():match("%d+")
|
||||
local prof = self.db.profile.frames[f]
|
||||
local profFont = nil
|
||||
if prof then
|
||||
profFont = prof.font
|
||||
else
|
||||
prof = {}
|
||||
end
|
||||
if profFont == "Default" then
|
||||
profFont = nil
|
||||
end
|
||||
local f, s, m = cf:GetFont()
|
||||
font = Media:Fetch("font", font or profFont or self.db.profile.font or f)
|
||||
size = size or prof.fontsize or self.db.profile.fontsize or s
|
||||
outline = outline or prof.outline or self.db.profile.outline or m
|
||||
cf:SetFont(font, size, outline)
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Enables you to set a custom font and font size for your chat frames"]
|
||||
end
|
||||
@@ -0,0 +1,277 @@
|
||||
local mod = Chatter:NewModule("Borders/Background")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Borders/Background"]
|
||||
|
||||
local Media = LibStub("LibSharedMedia-3.0")
|
||||
local CreateFrame = _G.CreateFrame
|
||||
local pairs = _G.pairs
|
||||
local tinsert = _G.tinsert
|
||||
local type = _G.type
|
||||
|
||||
local options = {
|
||||
}
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
frames = {}
|
||||
}
|
||||
}
|
||||
|
||||
local frame_defaults = {
|
||||
enable = true,
|
||||
combatLogFix = false,
|
||||
background = "Blizzard Tooltip",
|
||||
border = "Blizzard Tooltip",
|
||||
inset = 3,
|
||||
edgeSize = 12,
|
||||
backgroundColor = { r = 0, g = 0, b = 0, a = 1 },
|
||||
borderColor = { r = 1, g = 1, b = 1, a = 1 },
|
||||
}
|
||||
|
||||
local function deepcopy(tbl)
|
||||
local new = {}
|
||||
for key,value in pairs(tbl) do
|
||||
new[key] = type(value) == "table" and deepcopy(value) or value -- if it's a table, run deepCopy on it too, so we get a copy and not the original
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
local frames = {}
|
||||
function mod:OnInitialize()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
defaults.profile.frames["FRAME_" .. i] = deepcopy(frame_defaults)
|
||||
if _G["ChatFrame" .. i] == COMBATLOG then
|
||||
defaults.profile.frames["FRAME_" .. i].enable = false
|
||||
end
|
||||
end
|
||||
defaults.profile.frames.FRAME_2.combatLogFix = true
|
||||
|
||||
self.db = Chatter.db:RegisterNamespace("ChatFrameBorders", defaults)
|
||||
|
||||
Media.RegisterCallback(mod, "LibSharedMedia_Registered")
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
local frame = CreateFrame("Frame", nil, cf, "ChatFrameBorderTemplate")
|
||||
frame:EnableMouse(false)
|
||||
cf:SetFrameStrata("LOW")
|
||||
frame:SetFrameStrata("BACKGROUND")
|
||||
frame:SetFrameLevel(1)
|
||||
frame:Hide()
|
||||
frame.id = "FRAME_" .. i
|
||||
tinsert(frames, frame)
|
||||
local t = {
|
||||
type = "group",
|
||||
name = L["Chat Frame "] .. i,
|
||||
desc = L["Chat Frame "] .. i,
|
||||
args = {
|
||||
enable = {
|
||||
type = "toggle",
|
||||
name = L["Enable"],
|
||||
desc = L["Enable borders on this frame"],
|
||||
order = 1,
|
||||
get = function()
|
||||
return mod.db.profile.frames[frame.id].enable
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].enable = v
|
||||
if v then
|
||||
frame:Show()
|
||||
else
|
||||
frame:Hide()
|
||||
end
|
||||
end
|
||||
},
|
||||
combatLogFix = {
|
||||
type = "toggle",
|
||||
name = L["Combat Log Fix"],
|
||||
desc = L["Resize this border to fit the new combat log"],
|
||||
get = function() return mod.db.profile.frames[frame.id].combatLogFix end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].combatLogFix = v
|
||||
mod:SetAnchors(frame, v)
|
||||
end
|
||||
},
|
||||
background = {
|
||||
type = "select",
|
||||
name = L["Background texture"],
|
||||
desc = L["Background texture"],
|
||||
dialogControl = "LSM30_Background",
|
||||
values = Media:HashTable("background"),
|
||||
get = function() return mod.db.profile.frames[frame.id].background end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].background = v
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
border = {
|
||||
type = "select",
|
||||
name = L["Border texture"],
|
||||
desc = L["Border texture"],
|
||||
dialogControl = "LSM30_Border",
|
||||
values = Media:HashTable("border"),
|
||||
get = function() return mod.db.profile.frames[frame.id].border end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].border = v
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
backgroundColor = {
|
||||
type = "color",
|
||||
name = L["Background color"],
|
||||
desc = L["Background color"],
|
||||
hasAlpha = true,
|
||||
get = function()
|
||||
local c = mod.db.profile.frames[frame.id].backgroundColor
|
||||
return c.r, c.g, c.b, c.a
|
||||
end,
|
||||
set = function(info, r, g, b, a)
|
||||
local c = mod.db.profile.frames[frame.id].backgroundColor
|
||||
c.r, c.g, c.b, c.a = r, g, b, a
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
borderColor = {
|
||||
type = "color",
|
||||
name = L["Border color"],
|
||||
desc = L["Border color"],
|
||||
hasAlpha = true,
|
||||
get = function()
|
||||
local c = mod.db.profile.frames[frame.id].borderColor
|
||||
return c.r, c.g, c.b, c.a
|
||||
end,
|
||||
set = function(info, r, g, b, a)
|
||||
local c = mod.db.profile.frames[frame.id].borderColor
|
||||
c.r, c.g, c.b, c.a = r, g, b, a
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
inset = {
|
||||
type = "range",
|
||||
name = L["Background Inset"],
|
||||
desc = L["Background Inset"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.frames[frame.id].inset end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].inset = v
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
tileSize = {
|
||||
type = "range",
|
||||
name = L["Tile Size"],
|
||||
desc = L["Tile Size"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.frames[frame.id].tileSize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].tileSize = v
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
},
|
||||
edgeSize = {
|
||||
type = "range",
|
||||
name = L["Edge Size"],
|
||||
desc = L["Edge Size"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.frames[frame.id].edgeSize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.frames[frame.id].edgeSize = v
|
||||
mod:SetBackdrop(frame)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
options[frame.id] = t
|
||||
end
|
||||
end
|
||||
|
||||
function mod:LibSharedMedia_Registered()
|
||||
mod:SetBackdrops()
|
||||
end
|
||||
|
||||
function mod:Decorate(cf)
|
||||
local frame = CreateFrame("Frame", nil, cf, "ChatFrameBorderTemplate")
|
||||
frame:EnableMouse(false)
|
||||
cf:SetFrameStrata("LOW")
|
||||
frame:SetFrameStrata("BACKGROUND")
|
||||
frame:SetFrameLevel(1)
|
||||
frame:Hide()
|
||||
frame.id = "FRAME_1"
|
||||
tinsert(frames, frame)
|
||||
self:SetBackdrops()
|
||||
frame:Show()
|
||||
mod:SetAnchors(frame, self.db.profile.frames["FRAME_1"].combatLogFix)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
self:LibSharedMedia_Registered()
|
||||
self:SetBackdrops()
|
||||
for i = 1, #frames do
|
||||
frames[i]:Show()
|
||||
mod:SetAnchors(frames[i], self.db.profile.frames["FRAME_" .. i].combatLogFix)
|
||||
end
|
||||
Media.RegisterCallback(mod, "LibSharedMedia_Registered")
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, #frames do
|
||||
frames[i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:SetBackdrops()
|
||||
for i = 1, #frames do
|
||||
self:SetBackdrop(frames[i])
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
function mod:SetBackdrop(frame)
|
||||
local profile = self.db.profile.frames[frame.id]
|
||||
frame:SetBackdrop({
|
||||
bgFile = Media:Fetch("background", profile.background),
|
||||
edgeFile = Media:Fetch("border", profile.border),
|
||||
tile = true,
|
||||
tileSize = profile.tileSize,
|
||||
edgeSize = profile.edgeSize,
|
||||
insets = {left = profile.inset, right = profile.inset, top = profile.inset, bottom = profile.inset}
|
||||
})
|
||||
local c = profile.backgroundColor
|
||||
frame:SetBackdropColor(c.r, c.g, c.b, c.a)
|
||||
|
||||
local c = profile.borderColor
|
||||
frame:SetBackdropBorderColor(c.r, c.g, c.b, c.a)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:SetAnchors(frame, fix)
|
||||
local p = frame:GetParent()
|
||||
frame:ClearAllPoints()
|
||||
if fix then
|
||||
frame:SetPoint("TOPLEFT", p, "TOPLEFT", -5, 30)
|
||||
frame:SetPoint("TOPRIGHT", p, "TOPRIGHT", 5, 30)
|
||||
frame:SetPoint("BOTTOMLEFT", p, "BOTTOMLEFT", -5, -10)
|
||||
frame:SetPoint("BOTTOMRIGHT", p, "BOTTOMRIGHT", 5, -10)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", p, "TOPLEFT", -5, 5)
|
||||
frame:SetPoint("TOPRIGHT", p, "TOPRIGHT", 5, 5)
|
||||
frame:SetPoint("BOTTOMLEFT", p, "BOTTOMLEFT", -5, -10)
|
||||
frame:SetPoint("BOTTOMRIGHT", p, "BOTTOMRIGHT", 5, -10)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Gives you finer control over the chat frame's background and border colors"]
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
<Ui>
|
||||
<Script file="ChatFrameBorders.lua" />
|
||||
|
||||
<Frame name="ChatFrameBorderTemplate" virtual="true" enableMouse="false">
|
||||
<Backdrop bgFile="Interface\\ChatFrame\\ChatFrameBackground" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||||
<EdgeSize>
|
||||
<AbsValue val="16"/>
|
||||
</EdgeSize>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="5" right="5" top="5" bottom="5"/>
|
||||
</BackgroundInsets>
|
||||
</Backdrop>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="-5" y="7"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="-5" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</Ui>
|
||||
@@ -0,0 +1,65 @@
|
||||
local mod = Chatter:NewModule("ChatLink", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Chat Link"]
|
||||
|
||||
local gsub = _G.string.gsub
|
||||
local find = _G.string.find
|
||||
local GetChannelName = _G.GetChannelName
|
||||
local EnumerateServerChannels = _G.EnumerateServerChannels
|
||||
local select = _G.select
|
||||
|
||||
local serverChannels = {}
|
||||
local function excludeChannels(...)
|
||||
for i = 1, select("#", ...) do
|
||||
local name = select(i, ...)
|
||||
serverChannels[name] = true
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
excludeChannels(EnumerateServerChannels())
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
end
|
||||
|
||||
function mod:ParseLinks(text)
|
||||
if not text then return nil end
|
||||
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:talent:(%x+):([%d-]-:[%d-]-):([^}]-)}", "|c%1|Htalent:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:glyph:(%x+):([%d-]-:[%d-]-):([^}]-)}", "|c%1|Hglyph:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:enchant:(%x+):([%d-]-):([^}]-)}", "|c%1|Henchant:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:spell:(%x+):([%d-]-):([^}]-)}", "|c%1|Hspell:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:quest:(%x+):([%d-]-):([%d-]-):([^}]-)}", "|c%1|Hquest:%2:%3|h[%4]|h|r")
|
||||
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:trade:(%x+):(%-?%d-:%-?%d-:.*:.*):([^}]-)}", "|c%1|Htrade:%2|h[%3]|h|r")
|
||||
-- {CLINK:achievement:ffffff00:780:00000000001ED5C3:1:12:16:8:4294967295:4294967295:4294967295:4294967295:Explore Redridge Mountains}
|
||||
text = gsub(text, "{CLINK:achievement:(%x+):(%-?%d-:%-?%x-:%-?%d-:%-?%d-:%-?%d-:%-?%d-:%-?%d-:%-?%d-:%-?%d-:%-?%d-):([^}]-)}", "|c%1|Hachievement:%2|h[%3]|h|r")
|
||||
return text
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
return self.hooks[frame].AddMessage(frame, mod:ParseLinks(text), ...)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you link items, enchants, spells, talents, achievements and quests in custom channels."]
|
||||
end
|
||||
@@ -0,0 +1,162 @@
|
||||
local mod = Chatter:NewModule("Mousewheel Scroll", "AceHook-3.0","AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Mousewheel Scroll"]
|
||||
|
||||
local IsShiftKeyDown = _G.IsShiftKeyDown
|
||||
local IsControlKeyDown = _G.IsControlKeyDown
|
||||
|
||||
local scrollFunc = function(self, arg1)
|
||||
-- prevent itemtooltips to be kept open when using LinkHover.
|
||||
HideUIPanel(GameTooltip)
|
||||
|
||||
if arg1 > 0 then
|
||||
if IsShiftKeyDown() then
|
||||
self:ScrollToTop()
|
||||
elseif IsControlKeyDown() then
|
||||
self:PageUp()
|
||||
else
|
||||
for i = 1, mod.db.profile.scrollLines do
|
||||
self:ScrollUp()
|
||||
end
|
||||
end
|
||||
elseif arg1 < 0 then
|
||||
if IsShiftKeyDown() then
|
||||
self:ScrollToBottom()
|
||||
elseif IsControlKeyDown() then
|
||||
self:PageDown()
|
||||
else
|
||||
for i = 1, mod.db.profile.scrollLines do
|
||||
self:ScrollDown()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local defaults = { profile = { scrollLines = 1 } }
|
||||
local options = {
|
||||
lines = {
|
||||
type = "range",
|
||||
name = L["Scroll lines"],
|
||||
desc = L["How many lines to scroll per mouse wheel click"],
|
||||
min = 1,
|
||||
max = 20,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.scrollLines end,
|
||||
set = function(info, v) mod.db.profile.scrollLines = v end
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace(self:GetName(), defaults)
|
||||
self:RegisterEvent("CVAR_UPDATE", "ChangedVars")
|
||||
if _G.InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling then
|
||||
self:RawHook("InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling",true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling()
|
||||
-- We want to intercept this and handle it ourselves
|
||||
end
|
||||
|
||||
function mod:ChangedVars(event,cvar,value)
|
||||
if cvar == "CHAT_MOUSE_WHEEL_SCROLL" then
|
||||
if value == "1" then
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G[("%s%d"):format("ChatFrame", i)]
|
||||
cf:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll)
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll)
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
if value == "0" and self:IsEnabled() then
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G[("%s%d"):format("ChatFrame", i)]
|
||||
cf:SetScript("OnMouseWheel", scrollFunc)
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetScript("OnMouseWheel", scrollFunc)
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
if GetCVar("chatMouseScroll") == "1" then
|
||||
return
|
||||
end
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G[("%s%d"):format("ChatFrame", i)]
|
||||
cf:SetScript("OnMouseWheel", scrollFunc)
|
||||
if not cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetScript("OnMouseWheel", scrollFunc)
|
||||
if not cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if GetCVar("chatMouseScroll") == "1" then
|
||||
return
|
||||
end
|
||||
frame:SetScript("OnMouseWheel", scrollFunc)
|
||||
frame:EnableMouseWheel(true)
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G[("%s%d"):format("ChatFrame", i)]
|
||||
if GetCVarBool("chatMouseScroll") then
|
||||
cf:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll)
|
||||
if not cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
else
|
||||
cf:SetScript("OnMouseWheel", nil)
|
||||
if cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if GetCVarBool("chatMouseScroll") then
|
||||
cf:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll)
|
||||
if not cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
else
|
||||
cf:SetScript("OnMouseWheel", nil)
|
||||
if cf:IsMouseWheelEnabled() then
|
||||
cf:EnableMouseWheel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you use the mousewheel to page up and down chat."]
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,304 @@
|
||||
local mod = Chatter:NewModule("ChatTabs", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
local font = GameFontNormalSmall
|
||||
mod.modName = L["Chat Tabs"]
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
height = 29,
|
||||
tabFlash = true
|
||||
}
|
||||
}
|
||||
|
||||
local options = {
|
||||
height = {
|
||||
order = 101,
|
||||
type = "range",
|
||||
name = L["Button Height"],
|
||||
desc = L["Button's height, and text offset from the frame"],
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.height end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.height = v
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local tab = _G["ChatFrame"..i.."Tab"]
|
||||
tab:SetHeight(v)
|
||||
end
|
||||
end,
|
||||
disabled = function() return not mod:IsEnabled() end
|
||||
},
|
||||
hidetabs = {
|
||||
order = 102,
|
||||
type = "toggle",
|
||||
name = L["Hide Tabs"],
|
||||
desc = L["Hides chat frame tabs"],
|
||||
get = function() return mod.db.profile.chattabs end,
|
||||
set = function(info, v) mod.db.profile.chattabs = not mod.db.profile.chattabs; mod:ToggleTabShow() end,
|
||||
disabled = function() return not mod:IsEnabled() end
|
||||
},
|
||||
hideflash = {
|
||||
order = 103,
|
||||
type = "toggle",
|
||||
name = L["Enable Tab Flashing"],
|
||||
desc = L["Enables the Tab to flash when you miss a message"],
|
||||
get = function() return mod.db.profile.tabFlash end,
|
||||
set = function(info, v) mod.db.profile.tabFlash = not mod.db.profile.tabFlash; mod:DecorateTabs() end,
|
||||
disabled = function() return not mod:IsEnabled() end
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace(self:GetName(), defaults)
|
||||
end
|
||||
|
||||
local function SetFontSizes()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local tab = _G["ChatFrame"..i.."Tab"]
|
||||
mod:OnLeave(tab)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local tab = _G[name.."Tab"]
|
||||
mod:OnLeave(tab)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
local name = "ChatFrame"..frame:GetID();
|
||||
local tab = _G[name.."Tab"]
|
||||
tab:SetHeight(mod.db.profile.height)
|
||||
_G[name.."TabLeft"]:Hide()
|
||||
_G[name.."TabMiddle"]:Hide()
|
||||
_G[name.."TabRight"]:Hide()
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
tab.leftHighlightTexture:SetTexture(nil)
|
||||
tab.rightHighlightTexture:SetTexture(nil)
|
||||
tab.middleHighlightTexture:SetTexture([[BUTTONS\CheckButtonGlow]])
|
||||
tab.middleHighlightTexture:SetWidth(76)
|
||||
tab.middleHighlightTexture:SetTexCoord(0, 0, 1, 0.5)
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
tab:EnableMouseWheel(true)
|
||||
self:HookScript(tab, "OnMouseWheel")
|
||||
tab:Show()
|
||||
if (mod.db.profile.chattabs) then
|
||||
mod:HideTab(tab)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:DecorateTabs()
|
||||
CHAT_FRAME_FADE_OUT_TIME = 0.5
|
||||
CHAT_TAB_HIDE_DELAY = 0
|
||||
CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA = 1
|
||||
CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0
|
||||
CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA = 1
|
||||
if self.db.profile.tabFlash then
|
||||
CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA = 1
|
||||
else
|
||||
CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA = 0
|
||||
end
|
||||
CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA = 1
|
||||
CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0
|
||||
end
|
||||
|
||||
function mod:UndecorateTabs()
|
||||
CHAT_FRAME_FADE_OUT_TIME = 2
|
||||
CHAT_TAB_HIDE_DELAY = 1
|
||||
CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA = 1
|
||||
CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0.4
|
||||
CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA = 1
|
||||
CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA = 1
|
||||
CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA = 0.6
|
||||
CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0.2
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
-- self:Hook("FCF_Close", true)
|
||||
self:DecorateTabs()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local chat = _G["ChatFrame"..i]
|
||||
local tab = _G["ChatFrame"..i.."Tab"]
|
||||
tab:SetHeight(mod.db.profile.height)
|
||||
_G["ChatFrame"..i.."TabLeft"]:Hide()
|
||||
_G["ChatFrame"..i.."TabMiddle"]:Hide()
|
||||
_G["ChatFrame"..i.."TabRight"]:Hide()
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
tab.leftHighlightTexture:SetTexture(nil)
|
||||
tab.rightHighlightTexture:SetTexture(nil)
|
||||
tab.middleHighlightTexture:SetTexture([[BUTTONS\CheckButtonGlow]])
|
||||
tab.middleHighlightTexture:SetWidth(76)
|
||||
tab.middleHighlightTexture:SetTexCoord(0, 0, 1, 0.5)
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
--[[ TODO: Grum @ 18/10/2008
|
||||
There seems to be a bug with certain fonts/fontObjects which prevents
|
||||
tab:GetNormalFontObject() to return anything sensible
|
||||
The buttons now have font objects. If you change the size on one it will change on
|
||||
the other tabs as well. However assigning a new font object seems to go wrong with
|
||||
the default ChatFrame$Tab font-object. This will need further investigation
|
||||
|
||||
For now I just disabled all the font-changing mechanics.
|
||||
--]]
|
||||
tab:EnableMouseWheel(true)
|
||||
self:HookScript(tab, "OnMouseWheel")
|
||||
if (mod.db.profile.chattabs) then
|
||||
mod:HideTab(tab)
|
||||
end
|
||||
tab.noMouseAlpha=0
|
||||
tab:SetAlpha(0)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local chat = _G[name]
|
||||
local tab = _G[name.."Tab"]
|
||||
tab:SetHeight(mod.db.profile.height)
|
||||
_G[name.."TabLeft"]:Hide()
|
||||
_G[name.."TabMiddle"]:Hide()
|
||||
_G[name.."TabRight"]:Hide()
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
tab.leftHighlightTexture:SetTexture(nil)
|
||||
tab.rightHighlightTexture:SetTexture(nil)
|
||||
tab.middleHighlightTexture:SetTexture([[BUTTONS\CheckButtonGlow]])
|
||||
tab.middleHighlightTexture:SetWidth(76)
|
||||
tab.middleHighlightTexture:SetTexCoord(0, 0, 1, 0.5)
|
||||
tab.leftSelectedTexture:SetAlpha(0)
|
||||
tab.rightSelectedTexture:SetAlpha(0)
|
||||
tab.middleSelectedTexture:SetAlpha(0)
|
||||
tab:EnableMouseWheel(true)
|
||||
if not self:IsHooked(tab,"OnMouseWheel") then
|
||||
self:HookScript(tab, "OnMouseWheel")
|
||||
end
|
||||
if (mod.db.profile.chattabs) then
|
||||
mod:HideTab(tab)
|
||||
end
|
||||
tab.noMouseAlpha=0
|
||||
tab:SetAlpha(0)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local chat = _G["ChatFrame"..i]
|
||||
local tab = _G["ChatFrame"..i.."Tab"]
|
||||
tab:SetHeight(32)
|
||||
_G["ChatFrame"..i.."TabLeft"]:Show()
|
||||
_G["ChatFrame"..i.."TabMiddle"]:Show()
|
||||
_G["ChatFrame"..i.."TabRight"]:Show()
|
||||
tab:EnableMouseWheel(false)
|
||||
tab:Hide()
|
||||
tab.noMousealpha=0.2
|
||||
tab:SetAlpha(0.2)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local chat = _G[name]
|
||||
local tab = _G[name.."Tab"]
|
||||
tab:SetHeight(32)
|
||||
_G[name.."TabLeft"]:Show()
|
||||
_G[name.."TabMiddle"]:Show()
|
||||
_G[name.."TabRight"]:Show()
|
||||
tab:EnableMouseWheel(false)
|
||||
tab:Hide()
|
||||
tab.noMousealpha=0.2
|
||||
tab:SetAlpha(0.2)
|
||||
end
|
||||
self:UndecorateTabs()
|
||||
end
|
||||
|
||||
function mod:FCF_Close(f)
|
||||
_G[f:GetName() .. "Tab"]:Hide()
|
||||
end
|
||||
|
||||
function mod:OnClick(f, button, ...)
|
||||
if button == "LeftButton" then
|
||||
SetFontSizes(f)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ToggleTabShow()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local tab = _G["ChatFrame"..i.."Tab"]
|
||||
local chat = _G["ChatFrame"..i]
|
||||
if (mod.db.profile.chattabs) then
|
||||
tab:SetScript("OnShow", function(...) tab:Hide() end)
|
||||
else
|
||||
tab:SetScript("OnShow", function(...) tab:Show() end)
|
||||
end
|
||||
tab:Show()
|
||||
tab:Hide()
|
||||
if chat.isDocked or chat:IsVisible() then
|
||||
tab:Show()
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local tab = _G[name.."Tab"]
|
||||
local chat = _G[name]
|
||||
if (mod.db.profile.chattabs) then
|
||||
tab:SetScript("OnShow", function(...) tab:Hide() end)
|
||||
else
|
||||
tab:SetScript("OnShow", function(...) tab:Show() end)
|
||||
end
|
||||
tab:Show()
|
||||
tab:Hide()
|
||||
if chat.isDocked or chat:IsVisible() then
|
||||
tab:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:HideTab(tab)
|
||||
tab:SetScript("OnShow", function(...) tab:Hide() end)
|
||||
tab:Show()
|
||||
if tab:IsVisible() then
|
||||
tab:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnMouseWheel(frame, dir)
|
||||
local chat = _G["ChatFrame" .. frame:GetID()]
|
||||
if not chat.isDocked then return end
|
||||
|
||||
local t
|
||||
for i = 1, #GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES do
|
||||
if GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES[i]:IsVisible() then
|
||||
t = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if t == 1 and dir > 0 then
|
||||
t = #GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES
|
||||
elseif t == #GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES and dir < 0 then
|
||||
t = 1
|
||||
elseif t then
|
||||
t = t + (dir < 0 and 1 or -1)
|
||||
end
|
||||
if t then
|
||||
_G[GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES[t]:GetName() .. "Tab"]:Click()
|
||||
end
|
||||
--SetFontSizes()
|
||||
end
|
||||
|
||||
function mod:OnEnter(frame)
|
||||
local f, s = font:GetFont()
|
||||
frame:SetFont(f, s + 2)
|
||||
end
|
||||
|
||||
function mod:OnLeave(frame)
|
||||
local f, s = font:GetFont()
|
||||
if(_G["ChatFrame" .. frame:GetID()]:IsVisible()) then
|
||||
frame:SetFont(f, s + 2)
|
||||
else
|
||||
frame:SetFont(f, s - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,134 @@
|
||||
local mod = Chatter:NewModule("Invite Links", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Invite Links"]
|
||||
|
||||
local gsub = _G.string.gsub
|
||||
local ipairs = _G.ipairs
|
||||
local fmt = _G.string.format
|
||||
local sub = _G.string.sub
|
||||
local InviteUnit = _G.InviteUnit
|
||||
local next = _G.next
|
||||
local type = _G.type
|
||||
local IsAltKeyDown = _G.IsAltKeyDown
|
||||
local match = _G.string.match
|
||||
|
||||
local options = {
|
||||
addWord = {
|
||||
type = "input",
|
||||
name = L["Add Word"],
|
||||
desc = L["Add word to your invite trigger list"],
|
||||
get = function() end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.words[v:lower()] = v
|
||||
end
|
||||
},
|
||||
removeWord = {
|
||||
type = "select",
|
||||
name = L["Remove Word"],
|
||||
desc = L["Remove a word from your invite trigger list"],
|
||||
get = function() end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.words[v:lower()] = nil
|
||||
end,
|
||||
values = function() return mod.db.profile.words end,
|
||||
confirm = function(info, v) return (L["Remove this word from your trigger list?"]) end
|
||||
},
|
||||
altClick = {
|
||||
type = "toggle",
|
||||
name = L["Alt-click name to invite"],
|
||||
width = "double",
|
||||
desc = L["Lets you alt-click player names to invite them to your party."],
|
||||
get = function() return mod.db.profile.altClickToinvite end,
|
||||
set = function(i, v) mod.db.profile.altClickToinvite = v end
|
||||
}
|
||||
}
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
words = {},
|
||||
altClickToInvite = true
|
||||
}
|
||||
}
|
||||
|
||||
local words
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace(self:GetName(), defaults)
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
words = self.db.profile.words
|
||||
if not next(words) then
|
||||
words[L["invite"]] = L["invite"]
|
||||
words[L["inv"]] = L["inv"]
|
||||
end
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
self:RawHook(nil, "SetItemRef", true)
|
||||
end
|
||||
|
||||
local style = "|cffffffff|Hinvite:%s|h[%s]|h|r"
|
||||
local valid_events = {
|
||||
CHAT_MSG_SAY = true,
|
||||
CHAT_MSG_CHANNEL = true,
|
||||
CHAT_MSG_WHISPER = true,
|
||||
CHAT_MSG_OFFICER = true,
|
||||
CHAT_MSG_GUILD = true
|
||||
}
|
||||
|
||||
local function addLinks(m, t, p)
|
||||
if words[t:lower()] and p ~= "_" then
|
||||
t = fmt(style, arg2, t)
|
||||
return t .. p
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if not text then
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
if valid_events[event] and type(arg2) == "string" then
|
||||
text = gsub(text, "((%w+)(.?))", addLinks)
|
||||
end
|
||||
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:SetItemRef(link, text, button)
|
||||
local linkType = sub(link, 1, 6)
|
||||
-- Chatter:Print(IsAltKeyDown(), linkType, self.db.profile.altClickToInvite)
|
||||
if IsAltKeyDown() and linkType == "player" and self.db.profile.altClickToInvite then
|
||||
local name = match(link, "player:([^:]+)")
|
||||
InviteUnit(name)
|
||||
return nil
|
||||
elseif linkType == "invite" then
|
||||
local name = sub(link, 8)
|
||||
InviteUnit(name)
|
||||
return nil
|
||||
end
|
||||
return self.hooks.SetItemRef(link, text, button)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Gives you more flexibility in how you invite people to your group."]
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,228 @@
|
||||
local mod = Chatter:NewModule("Chat Copy", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Copy Chat"]
|
||||
|
||||
local lines = {}
|
||||
local table_concat = _G.table.concat
|
||||
local CreateFrame = _G.CreateFrame
|
||||
local GetSpellInfo = _G.GetSpellInfo
|
||||
local select = _G.select
|
||||
local tinsert = _G.tinsert
|
||||
local tostring = _G.tostring
|
||||
|
||||
local PaneBackdrop = {
|
||||
bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
|
||||
edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]],
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local InsetBackdrop = {
|
||||
bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
|
||||
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local tex = select(3, GetSpellInfo(586))
|
||||
local buttons = {}
|
||||
local defaults = {
|
||||
profile = {
|
||||
copyIcon = false,
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("CopyChat", defaults)
|
||||
|
||||
local frame = CreateFrame("Frame", "ChatterCopyFrame", UIParent)
|
||||
tinsert(UISpecialFrames, "ChatterCopyFrame")
|
||||
frame:SetBackdrop(PaneBackdrop)
|
||||
frame:SetBackdropColor(0,0,0,1)
|
||||
frame:SetWidth(500)
|
||||
frame:SetHeight(400)
|
||||
frame:SetPoint("CENTER", UIParent, "CENTER")
|
||||
frame:Hide()
|
||||
frame:SetFrameStrata("DIALOG")
|
||||
self.frame = frame
|
||||
|
||||
local scrollArea = CreateFrame("ScrollFrame", "ChatterCopyScroll", frame, "UIPanelScrollFrameTemplate")
|
||||
scrollArea:SetPoint("TOPLEFT", frame, "TOPLEFT", 8, -30)
|
||||
scrollArea:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 8)
|
||||
|
||||
local editBox = CreateFrame("EditBox", nil, frame)
|
||||
editBox:SetMultiLine(true)
|
||||
editBox:SetMaxLetters(99999)
|
||||
editBox:EnableMouse(true)
|
||||
editBox:SetAutoFocus(false)
|
||||
editBox:SetFontObject(ChatFontNormal)
|
||||
editBox:SetWidth(400)
|
||||
editBox:SetHeight(270)
|
||||
editBox:SetScript("OnEscapePressed", function() frame:Hide() end)
|
||||
self.editBox = editBox
|
||||
|
||||
scrollArea:SetScrollChild(editBox)
|
||||
|
||||
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
||||
close:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
|
||||
end
|
||||
|
||||
local options
|
||||
function mod:GetOptions()
|
||||
options = options or {
|
||||
guildNotes = {
|
||||
order=100,
|
||||
type = "toggle",
|
||||
name = L["Show copy icon"],
|
||||
desc = L["Toggle the copy icon on the chat frame."],
|
||||
get = function()
|
||||
return mod.db.profile.copyIcon
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.copyIcon = v
|
||||
mod:HideCopyButton(v)
|
||||
end,
|
||||
},
|
||||
}
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
local button = self:MakeCopyButton(frame)
|
||||
local tab = _G["ChatFrame" .. frame:GetID()]
|
||||
self:HookScript(tab, "OnShow")
|
||||
self:HookScript(tab, "OnHide")
|
||||
tab.copyButton = button
|
||||
if self.db.profile.copyIcon then
|
||||
tab.copyButton:Show()
|
||||
end
|
||||
end
|
||||
function mod:OnEnable()
|
||||
Chatter:AddMenuHook(self, "Menu")
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
self:MakeCopyButton(cf)
|
||||
end
|
||||
for index,f in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[f]
|
||||
self:MakeCopyButton(cf)
|
||||
end
|
||||
for i = 1, #buttons do
|
||||
local p = buttons[i]:GetParent()
|
||||
local tab = _G["ChatFrame" .. p:GetID()]
|
||||
self:HookScript(tab, "OnShow")
|
||||
self:HookScript(tab, "OnHide")
|
||||
tab.copyButton = buttons[i]
|
||||
if self.db.profile.copyIcon then
|
||||
tab.copyButton:Show()
|
||||
else
|
||||
tab.copyButton:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
Chatter:RemoveMenuHook(self)
|
||||
for i = 1, #buttons do
|
||||
buttons[i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:HideCopyButton(val)
|
||||
if not val then
|
||||
for i = 1, #buttons do
|
||||
buttons[i]:Hide()
|
||||
end
|
||||
else
|
||||
for i = 1, #buttons do
|
||||
buttons[i]:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:MakeCopyButton(frame)
|
||||
for index,cb in ipairs(buttons) do
|
||||
if cb:GetParent() == frame then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local button = CreateFrame("Button", nil, frame)
|
||||
button:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, -5)
|
||||
button:SetHeight(10)
|
||||
button:SetWidth(10)
|
||||
button:SetNormalTexture(tex)
|
||||
button:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]])
|
||||
button:SetScript("OnClick", function() mod:Copy(frame) end)
|
||||
button:SetScript("OnEnter", function(self)
|
||||
self:SetHeight(28)
|
||||
self:SetWidth(28)
|
||||
GameTooltip:SetOwner(self)
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:AddLine(L["Copy text from this frame."])
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
button:SetScript("OnLeave", function(self)
|
||||
button:SetHeight(10)
|
||||
button:SetWidth(10)
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
button:Hide()
|
||||
tinsert(buttons, button)
|
||||
return button
|
||||
end
|
||||
|
||||
local menuButtons = {}
|
||||
function mod:Menu(chatTab, button)
|
||||
local frame = _G["ChatFrame" .. chatTab:GetID()]
|
||||
|
||||
local info = menuButtons[chatTab:GetID()]
|
||||
if not info then
|
||||
info = {}
|
||||
info.text = L["Copy Text"]
|
||||
info.func = function() mod:Copy(frame) end
|
||||
info.notCheckable = 1;
|
||||
menuButtons[chatTab:GetID()] = info
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
||||
function mod:Copy(frame)
|
||||
local _, size = frame:GetFont()
|
||||
FCF_SetChatWindowFontSize(frame, frame, 0.01)
|
||||
local lineCt = self:GetLines(frame:GetRegions())
|
||||
local text = table_concat(lines, "\n", 1, lineCt)
|
||||
FCF_SetChatWindowFontSize(frame, frame, size)
|
||||
self.frame:Show()
|
||||
self.editBox:SetText(text)
|
||||
self.editBox:HighlightText(0)
|
||||
end
|
||||
|
||||
function mod:GetLines(...)
|
||||
local ct = 1
|
||||
for i = select("#", ...), 1, -1 do
|
||||
local region = select(i, ...)
|
||||
if region:GetObjectType() == "FontString" then
|
||||
lines[ct] = tostring(region:GetText())
|
||||
ct = ct + 1
|
||||
end
|
||||
end
|
||||
return ct - 1
|
||||
end
|
||||
|
||||
function mod:OnShow(cft)
|
||||
local cfn = cft:GetName():match("ChatFrame%d")
|
||||
if cfn and _G[cfn]:IsVisible() and self.db.profile.copyIcon then
|
||||
cft.copyButton:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnHide(cft)
|
||||
local cfn = cft:GetName():match("ChatFrame%d")
|
||||
if cfn and _G[cfn]:IsVisible() then
|
||||
cft.copyButton:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you copy text out of your chat frames."]
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
local frame = CreateFrame("Frame")
|
||||
|
||||
LibStub("AceHook-3.0"):Embed(frame)
|
||||
|
||||
local strmatch = strmatch
|
||||
|
||||
-- GUILD_MOTD_TEMPLATE = "Guild Message of the Day: %s"; -- %s is the guild MOTD
|
||||
|
||||
local pattern = GUILD_MOTD_TEMPLATE:
|
||||
gsub("[-%%+*.()%[%]]", "%%%1"):
|
||||
gsub("%%%%s", "(.+)")
|
||||
|
||||
local gmotdData
|
||||
|
||||
function frame:AddMessage(frame, text, ...)
|
||||
local gmotd
|
||||
if text then
|
||||
gmotd = strmatch(text, pattern)
|
||||
end
|
||||
if gmotd then
|
||||
gmotdData={text,...}
|
||||
self:UnhookAll()
|
||||
else
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
end
|
||||
|
||||
frame:RawHook(ChatFrame1, "AddMessage", true)
|
||||
|
||||
|
||||
local delay=2.5
|
||||
frame:SetScript("OnUpdate", function(self, expired)
|
||||
delay=delay-expired
|
||||
if delay<0 then
|
||||
self:Hide()
|
||||
self:UnhookAll()
|
||||
if gmotdData then
|
||||
ChatFrame1:AddMessage(unpack(gmotdData))
|
||||
gmotdData=nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,615 @@
|
||||
local mod = Chatter:NewModule("Edit Box Polish", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Edit Box Polish"]
|
||||
|
||||
local Media = LibStub("LibSharedMedia-3.0")
|
||||
local backgrounds, borders, fonts = {}, {}, {}
|
||||
local CreateFrame = _G.CreateFrame
|
||||
local max = _G.max
|
||||
local pairs = _G.pairs
|
||||
local select = _G.select
|
||||
|
||||
local VALID_ATTACH_POINTS = {
|
||||
TOP = L["Top"],
|
||||
BOTTOM = L["Bottom"],
|
||||
FREE = L["Free-floating"],
|
||||
LOCK = L["Free-floating, Locked"]
|
||||
}
|
||||
|
||||
local function updateEditBox(method, ...)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame" .. i .. "EditBox"]
|
||||
f[method](f, ...)
|
||||
end
|
||||
for index,name in ipairs(mod.TempChatFrames) do
|
||||
local cf = _G[name.."EditBox"]
|
||||
if cf then
|
||||
cf[method](cf,...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local options = {
|
||||
background = {
|
||||
type = "select",
|
||||
name = L["Background texture"],
|
||||
desc = L["Background texture"],
|
||||
values = Media:HashTable("background"),
|
||||
dialogControl = "LSM30_Background",
|
||||
get = function() return mod.db.profile.background end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.background = v
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
border = {
|
||||
type = "select",
|
||||
name = L["Border texture"],
|
||||
desc = L["Border texture"],
|
||||
dialogControl = "LSM30_Border",
|
||||
values = Media:HashTable("border"),
|
||||
get = function() return mod.db.profile.border end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.border = v
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
backgroundColor = {
|
||||
type = "color",
|
||||
name = L["Background color"],
|
||||
desc = L["Background color"],
|
||||
hasAlpha = true,
|
||||
get = function()
|
||||
local c = mod.db.profile.backgroundColor
|
||||
return c.r, c.g, c.b, c.a
|
||||
end,
|
||||
set = function(info, r, g, b, a)
|
||||
local c = mod.db.profile.backgroundColor
|
||||
c.r, c.g, c.b, c.a = r, g, b, a
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
borderColor = {
|
||||
type = "color",
|
||||
name = L["Border color"],
|
||||
desc = L["Border color"],
|
||||
hasAlpha = true,
|
||||
get = function()
|
||||
local c = mod.db.profile.borderColor
|
||||
return c.r, c.g, c.b, c.a
|
||||
end,
|
||||
set = function(info, r, g, b, a)
|
||||
local c = mod.db.profile.borderColor
|
||||
c.r, c.g, c.b, c.a = r, g, b, a
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
inset = {
|
||||
type = "range",
|
||||
name = L["Background Inset"],
|
||||
desc = L["Background Inset"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.inset end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.inset = v
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
tileSize = {
|
||||
type = "range",
|
||||
name = L["Tile Size"],
|
||||
desc = L["Tile Size"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.tileSize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.tileSize = v
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
edgeSize = {
|
||||
type = "range",
|
||||
name = L["Edge Size"],
|
||||
desc = L["Edge Size"],
|
||||
min = 1,
|
||||
max = 64,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.edgeSize end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.edgeSize = v
|
||||
mod:SetBackdrop()
|
||||
end
|
||||
},
|
||||
attach = {
|
||||
type = "select",
|
||||
name = L["Attach to..."],
|
||||
desc = L["Attach edit box to..."],
|
||||
get = function() return mod.db.profile.attach end,
|
||||
values = VALID_ATTACH_POINTS,
|
||||
set = function(info, v)
|
||||
mod.db.profile.attach = v
|
||||
-- we loop in set attach anyways
|
||||
mod:SetAttach()
|
||||
end
|
||||
},
|
||||
colorByChannel = {
|
||||
type = "toggle",
|
||||
name = L["Color border by channel"],
|
||||
desc = L["Sets the frame's border color to the color of your currently active channel"],
|
||||
get = function()
|
||||
return mod.db.profile.colorByChannel
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.colorByChannel = v
|
||||
if v then
|
||||
mod:RawHook("ChatEdit_UpdateHeader", "SetBorderByChannel", true)
|
||||
else
|
||||
if mod:IsHooked("ChatEdit_UpdateHeader") then
|
||||
mod:Unhook("ChatEdit_UpdateHeader")
|
||||
local c = mod.db.profile.borderColor
|
||||
for _, frame in ipairs(self.frames) do
|
||||
frame:SetBackdropBorderColor(c.r, c.g, c.b, c.a)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
useAltKey = {
|
||||
type = "toggle",
|
||||
name = L["Use Alt key for cursor movement"],
|
||||
desc = L["Requires the Alt key to be held down to move the cursor in chat"],
|
||||
get = function()
|
||||
return mod.db.profile.useAlt
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.useAlt = v
|
||||
updateEditBox("SetAltArrowKeyMode", v)
|
||||
end
|
||||
},
|
||||
font = {
|
||||
type = "select",
|
||||
name = L["Font"],
|
||||
dialogControl = "LSM30_Font",
|
||||
desc = L["Select the font to use for the edit box"],
|
||||
values = Media:HashTable("font"),
|
||||
get = function() return mod.db.profile.font end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.font = v
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local ff = _G["ChatFrame"..i.."EditBox"]
|
||||
local _, s, m = ff:GetFont()
|
||||
ff:SetFont(Media:Fetch("font", v), s, m)
|
||||
end
|
||||
end
|
||||
},
|
||||
height = {
|
||||
type = "range",
|
||||
name = L["Height"],
|
||||
desc = L["Select the height of the edit box"],
|
||||
min = 5,
|
||||
max = 50,
|
||||
step = 1,
|
||||
bigStep = 1,
|
||||
get = function() return mod.db.profile.height end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.height = v
|
||||
mod:UpdateHeight()
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
background = "Blizzard Tooltip",
|
||||
border = "Blizzard Tooltip",
|
||||
hideDialog = true,
|
||||
backgroundColor = {r = 0, g = 0, b = 0, a = 1},
|
||||
borderColor = {r = 1, g = 1, b = 1, a = 1},
|
||||
inset = 3,
|
||||
edgeSize = 12,
|
||||
tileSize = 16,
|
||||
height = 22,
|
||||
attach = "BOTTOM",
|
||||
colorByChannel = true,
|
||||
useAlt = false,
|
||||
font = (function()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local ff = _G["ChatFrame"..i.."EditBox"]
|
||||
local f = ff:GetFont()
|
||||
for k,v in pairs(Media:HashTable("font")) do
|
||||
if v == f then return k end
|
||||
end
|
||||
end
|
||||
end)()
|
||||
}
|
||||
}
|
||||
|
||||
function mod:LibSharedMedia_Registered(mediaType, key)
|
||||
--for k, v in pairs(Media:List("background")) do
|
||||
-- backgrounds[v] = v
|
||||
--end
|
||||
--for k, v in pairs(Media:List("border")) do
|
||||
-- borders[v] = v
|
||||
--end
|
||||
--for k, v in pairs(Media:List("font")) do
|
||||
-- fonts[v] = v
|
||||
--end
|
||||
-- If we were missing this media, reset it now
|
||||
if mediaType == "font" and key == self.db.profile.font then
|
||||
for _, frame in ipairs(self.frames) do
|
||||
local f = frame:GetParent()
|
||||
if f then
|
||||
local font, s, m = f:GetFont()
|
||||
f:SetFont(Media:Fetch("font", self.db.profile.font), s, m)
|
||||
end
|
||||
end
|
||||
end
|
||||
if mediaType == "border" and key == self.db.profile.border then
|
||||
self:SetBackdrop()
|
||||
end
|
||||
if mediaType == "background" and key == self.db.profile.background then
|
||||
self:SetBackdrop()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("EditBox", defaults)
|
||||
Media.RegisterCallback(mod, "LibSharedMedia_Registered")
|
||||
self.frames = {}
|
||||
self:LibSharedMedia_Registered()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local parent = _G["ChatFrame"..i.."EditBox"]
|
||||
local frame = CreateFrame("Frame", nil, parent)
|
||||
frame:SetFrameStrata("DIALOG")
|
||||
frame:SetFrameLevel(parent:GetFrameLevel() - 1)
|
||||
frame:SetAllPoints(parent)
|
||||
frame:Hide()
|
||||
parent.lDrag = CreateFrame("Frame", nil, parent)
|
||||
parent.lDrag:SetWidth(15)
|
||||
parent.lDrag:SetPoint("TOPLEFT", parent, "TOPLEFT")
|
||||
parent.lDrag:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT")
|
||||
parent.rDrag = CreateFrame("Frame", nil, parent)
|
||||
parent.rDrag:SetWidth(15)
|
||||
parent.rDrag:SetPoint("TOPRIGHT", parent, "TOPRIGHT")
|
||||
parent.rDrag:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT")
|
||||
parent.lDrag.left = true
|
||||
parent.frame = frame
|
||||
tinsert(self.frames, frame)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(chatframe)
|
||||
local parent = _G[chatframe:GetName().."EditBox"]
|
||||
local frame = CreateFrame("Frame", nil, parent)
|
||||
frame:SetFrameStrata("DIALOG")
|
||||
frame:SetFrameLevel(parent:GetFrameLevel() - 1)
|
||||
frame:SetAllPoints(parent)
|
||||
parent.lDrag = CreateFrame("Frame", nil, parent)
|
||||
parent.lDrag:SetWidth(15)
|
||||
parent.lDrag:SetPoint("TOPLEFT", parent, "TOPLEFT")
|
||||
parent.lDrag:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT")
|
||||
parent.rDrag = CreateFrame("Frame", nil, parent)
|
||||
parent.rDrag:SetWidth(15)
|
||||
parent.rDrag:SetPoint("TOPRIGHT", parent, "TOPRIGHT")
|
||||
parent.rDrag:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT")
|
||||
parent.lDrag.left = true
|
||||
parent.frame = frame
|
||||
tinsert(self.frames, frame)
|
||||
local name = chatframe:GetName()
|
||||
local f = _G[name.."EditBox"]
|
||||
_G[name.."EditBoxLeft"]:Hide()
|
||||
_G[name.."EditBoxRight"]:Hide()
|
||||
_G[name.."EditBoxMid"]:Hide()
|
||||
_G[name.."EditBoxFocusLeft"]:SetTexture(nil)
|
||||
_G[name.."EditBoxFocusRight"]:SetTexture(nil)
|
||||
_G[name.."EditBoxFocusMid"]:SetTexture(nil)
|
||||
f:Hide()
|
||||
frame:Show()
|
||||
local font, s, m = f:GetFont()
|
||||
f:SetFont(Media:Fetch("font", self.db.profile.font), s, m)
|
||||
self:SetAttach(nil, self.db.profile.editX, self.db.profile.editY, self.db.profile.editW)
|
||||
self:SetBackdrop()
|
||||
self:UpdateHeight()
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
self:LibSharedMedia_Registered()
|
||||
updateEditBox("SetAltArrowKeyMode", mod.db.profile.useAlt)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame"..i.."EditBox"]
|
||||
_G["ChatFrame"..i.."EditBoxLeft"]:Hide()
|
||||
_G["ChatFrame"..i.."EditBoxRight"]:Hide()
|
||||
_G["ChatFrame"..i.."EditBoxMid"]:Hide()
|
||||
_G["ChatFrame"..i.."EditBoxFocusLeft"]:SetTexture(nil)
|
||||
_G["ChatFrame"..i.."EditBoxFocusRight"]:SetTexture(nil)
|
||||
_G["ChatFrame"..i.."EditBoxFocusMid"]:SetTexture(nil)
|
||||
f:Hide()
|
||||
self.frames[i]:Show()
|
||||
local font, s, m = f:GetFont()
|
||||
f:SetFont(Media:Fetch("font", self.db.profile.font), s, m)
|
||||
self:SetAttach(nil, self.db.profile.editX, self.db.profile.editY, self.db.profile.editW)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local f = _G[name.."EditBox"]
|
||||
_G[name.."EditBoxLeft"]:Hide()
|
||||
_G[name.."EditBoxRight"]:Hide()
|
||||
_G[name.."EditBoxMid"]:Hide()
|
||||
_G[name.."EditBoxFocusLeft"]:SetTexture(nil)
|
||||
_G[name.."EditBoxFocusRight"]:SetTexture(nil)
|
||||
_G[name.."EditBoxFocusMid"]:SetTexture(nil)
|
||||
f:Hide()
|
||||
self.frames[NUM_CHAT_WINDOWS+index]:Show()
|
||||
local font, s, m = f:GetFont()
|
||||
f:SetFont(Media:Fetch("font", self.db.profile.font), s, m)
|
||||
self:SetAttach(nil, self.db.profile.editX, self.db.profile.editY, self.db.profile.editW)
|
||||
end
|
||||
-- make sure they all show
|
||||
for index,frame in ipairs(self.frames) do
|
||||
frame:Show()
|
||||
end
|
||||
self:SecureHook("ChatEdit_DeactivateChat")
|
||||
self:SecureHook("ChatEdit_SetLastActiveWindow")
|
||||
self:SetBackdrop()
|
||||
self:UpdateHeight()
|
||||
if self.db.profile.colorByChannel then
|
||||
self:RawHook("ChatEdit_UpdateHeader", "SetBorderByChannel", true)
|
||||
end
|
||||
self:SecureHook("FCF_Tab_OnClick")
|
||||
end
|
||||
|
||||
function mod:FCF_Tab_OnClick(frame,button)
|
||||
if self.db.profile.attach == "TOP" and GetCVar("chatStyle") ~= "classic" then
|
||||
local chatFrame = _G["ChatFrame"..frame:GetID()];
|
||||
ChatEdit_DeactivateChat(chatFrame.editBox)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local f = _G["ChatFrame"..i.."EditBox"]
|
||||
_G["ChatFrame"..i.."EditBoxLeft"]:Show()
|
||||
_G["ChatFrame"..i.."EditBoxRight"]:Show()
|
||||
_G["ChatFrame"..i.."EditBoxMid"]:Show()
|
||||
f:SetAltArrowKeyMode(true)
|
||||
f:EnableMouse(true)
|
||||
f.frame:Hide()
|
||||
self:SetAttach("BOTTOM")
|
||||
f:SetFont(Media:Fetch("font", defaults.profile.font), 14)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local f = _G[name.."EditBox"]
|
||||
_G[name.."EditBoxLeft"]:Show()
|
||||
_G[name.."EditBoxRight"]:Show()
|
||||
_G[name.."EditBoxMid"]:Show()
|
||||
f:SetAltArrowKeyMode(true)
|
||||
f:EnableMouse(true)
|
||||
f.frame:Hide()
|
||||
self:SetAttach("BOTTOM")
|
||||
f:SetFont(Media:Fetch("font", defaults.profile.font), 14)
|
||||
end
|
||||
end
|
||||
|
||||
-- changed the Hide to SetAlpha(0), the new ChatSystem OnHide handlers go though some looping
|
||||
-- when in IM style and Classic style, cause heavy delays on the chat edit box.
|
||||
function mod:ChatEdit_SetLastActiveWindow(frame)
|
||||
if self.db.profile.hideDialog and frame:IsShown() then
|
||||
frame:SetAlpha(0)
|
||||
else
|
||||
frame:SetAlpha(1)
|
||||
end
|
||||
frame:EnableMouse(true)
|
||||
end
|
||||
|
||||
function mod:ChatEdit_DeactivateChat(frame)
|
||||
if self.db.profile.hideDialog and frame:IsShown() then
|
||||
frame:SetAlpha(0)
|
||||
frame:EnableMouse(false)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:SetBackdrop()
|
||||
for _, frame in ipairs(self.frames) do
|
||||
frame:SetBackdrop({
|
||||
bgFile = Media:Fetch("background", self.db.profile.background),
|
||||
edgeFile = Media:Fetch("border", self.db.profile.border),
|
||||
tile = true,
|
||||
tileSize = self.db.profile.tileSize,
|
||||
edgeSize = self.db.profile.edgeSize,
|
||||
insets = {left = self.db.profile.inset, right = self.db.profile.inset, top = self.db.profile.inset, bottom = self.db.profile.inset}
|
||||
})
|
||||
local c = self.db.profile.backgroundColor
|
||||
frame:SetBackdropColor(c.r, c.g, c.b, c.a)
|
||||
|
||||
local c = self.db.profile.borderColor
|
||||
frame:SetBackdropBorderColor(c.r, c.g, c.b, c.a)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:SetBorderByChannel(...)
|
||||
self.hooks.ChatEdit_UpdateHeader(...)
|
||||
for index, frame in ipairs(self.frames) do
|
||||
local f = _G["ChatFrame"..index.."EditBox"]
|
||||
local attr = f:GetAttribute("chatType")
|
||||
if attr == "CHANNEL" then
|
||||
local chan = f:GetAttribute("channelTarget")
|
||||
if chan == 0 then
|
||||
local c = self.db.profile.borderColor
|
||||
frame:SetBackdropBorderColor(c.r, c.g, c.b, c.a)
|
||||
else
|
||||
local r, g, b = GetMessageTypeColor("CHANNEL" .. chan)
|
||||
frame:SetBackdropBorderColor(r, g, b, 1)
|
||||
end
|
||||
else
|
||||
local r, g, b = GetMessageTypeColor(attr)
|
||||
frame:SetBackdropBorderColor(r, g, b, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local function startMoving(self)
|
||||
self:StartMoving()
|
||||
end
|
||||
|
||||
local function stopMoving(self)
|
||||
self:StopMovingOrSizing()
|
||||
mod.db.profile.editX = self:GetLeft()
|
||||
mod.db.profile.editY = self:GetTop()
|
||||
mod.db.profile.editW = self:GetRight() - self:GetLeft()
|
||||
end
|
||||
|
||||
local cfHeight
|
||||
local function constrainHeight(self)
|
||||
self:GetParent():SetHeight(cfHeight)
|
||||
end
|
||||
|
||||
local function startDragging(self)
|
||||
cfHeight = self:GetParent():GetHeight()
|
||||
self:GetParent():StartSizing(not self.left and "TOPRIGHT" or "TOPLEFT")
|
||||
self:SetScript("OnUpdate", constrainHeight)
|
||||
end
|
||||
|
||||
local function stopDragging(self)
|
||||
local parent = self:GetParent()
|
||||
parent:StopMovingOrSizing()
|
||||
self:SetScript("OnUpdate", nil)
|
||||
mod.db.profile.editX = parent:GetLeft()
|
||||
mod.db.profile.editY = parent:GetTop()
|
||||
mod.db.profile.editW = parent:GetWidth()
|
||||
end
|
||||
|
||||
function mod:SetAttach(val, x, y, w)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local frame = _G["ChatFrame" .. i .. "EditBox"]
|
||||
local val = val or self.db.profile.attach
|
||||
if not x and val == "FREE" then
|
||||
if self.db.profile.editX and self.db.profile.editY then
|
||||
x, y, w = self.db.profile.editX, self.db.profile.editY, self.db.profile.editW
|
||||
else
|
||||
x, y, w = frame:GetLeft(), frame:GetTop(), max(frame:GetWidth(), (frame:GetRight() or 0) - (frame:GetLeft() or 0))
|
||||
end
|
||||
end
|
||||
if not w or w < 10 then w = 100 end
|
||||
frame:ClearAllPoints()
|
||||
-- Turn off clamping
|
||||
if val ~= "FREE" then
|
||||
frame:SetMovable(false)
|
||||
frame.lDrag:EnableMouse(false)
|
||||
frame.rDrag:EnableMouse(false)
|
||||
frame:SetScript("OnMouseDown", nil)
|
||||
frame:SetScript("OnMouseUp", nil)
|
||||
frame.lDrag:EnableMouse(false)
|
||||
frame.rDrag:EnableMouse(false)
|
||||
frame.lDrag:SetScript("OnMouseDown", nil)
|
||||
frame.rDrag:SetScript("OnMouseDown", nil)
|
||||
frame.lDrag:SetScript("OnMouseUp", nil)
|
||||
frame.rDrag:SetScript("OnMouseUp", nil)
|
||||
end
|
||||
|
||||
if val == "TOP" then
|
||||
-- When on top we need to prevent left clicking from activating the edit box.
|
||||
frame:SetPoint("BOTTOMLEFT", frame.chatFrame, "TOPLEFT", 0, 3)
|
||||
frame:SetPoint("BOTTOMRIGHT", frame.chatFrame, "TOPRIGHT", 0, 3)
|
||||
elseif val == "BOTTOM" then
|
||||
frame:SetPoint("TOPLEFT", frame.chatFrame, "BOTTOMLEFT", 0, -8)
|
||||
frame:SetPoint("TOPRIGHT", frame.chatFrame, "BOTTOMRIGHT", 0, -8)
|
||||
elseif val == "FREE" then
|
||||
if i == 1 then
|
||||
frame:SetFrameLevel(frame:GetFrameLevel()+1)
|
||||
end
|
||||
frame:EnableMouse(true)
|
||||
frame:SetMovable(true)
|
||||
frame:SetResizable(true)
|
||||
frame:SetScript("OnMouseDown", startMoving)
|
||||
frame:SetScript("OnMouseUp", stopMoving)
|
||||
frame:SetWidth(w)
|
||||
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
|
||||
frame:SetMinResize(40, 1)
|
||||
|
||||
frame.lDrag:EnableMouse(true)
|
||||
frame.rDrag:EnableMouse(true)
|
||||
|
||||
frame.lDrag:SetScript("OnMouseDown", startDragging)
|
||||
frame.rDrag:SetScript("OnMouseDown", startDragging)
|
||||
|
||||
frame.lDrag:SetScript("OnMouseUp", stopDragging)
|
||||
frame.rDrag:SetScript("OnMouseUp", stopDragging)
|
||||
elseif val == "LOCK" then
|
||||
frame:SetWidth(self.db.profile.editW or w)
|
||||
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.db.profile.editX or x, self.db.profile.editY or y)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local frame = _G[name .. "EditBox"]
|
||||
local val = val or self.db.profile.attach
|
||||
if not x and val == "FREE" then
|
||||
x, y, w = frame:GetLeft(), frame:GetTop(), max(frame:GetWidth(), (frame:GetRight() or 0) - (frame:GetLeft() or 0))
|
||||
end
|
||||
if not w or w < 10 then w = 100 end
|
||||
frame:ClearAllPoints()
|
||||
if val ~= "FREE" then
|
||||
frame:SetMovable(false)
|
||||
frame.lDrag:EnableMouse(false)
|
||||
frame.rDrag:EnableMouse(false)
|
||||
frame:SetScript("OnMouseDown", nil)
|
||||
frame:SetScript("OnMouseUp", nil)
|
||||
frame.lDrag:EnableMouse(false)
|
||||
frame.rDrag:EnableMouse(false)
|
||||
frame.lDrag:SetScript("OnMouseDown", nil)
|
||||
frame.rDrag:SetScript("OnMouseDown", nil)
|
||||
frame.lDrag:SetScript("OnMouseUp", nil)
|
||||
frame.rDrag:SetScript("OnMouseUp", nil)
|
||||
end
|
||||
if val == "TOP" then
|
||||
frame:SetPoint("BOTTOMLEFT", _G[name], "TOPLEFT", 0, 3)
|
||||
frame:SetPoint("BOTTOMRIGHT", _G[name], "TOPRIGHT", 0, 3)
|
||||
elseif val == "BOTTOM" then
|
||||
frame:SetPoint("TOPLEFT", _G[name], "BOTTOMLEFT", 0, -8)
|
||||
frame:SetPoint("TOPRIGHT", _G[name], "BOTTOMRIGHT", 0, -8)
|
||||
elseif val == "FREE" then
|
||||
frame:EnableMouse(true)
|
||||
frame:SetMovable(true)
|
||||
frame:SetResizable(true)
|
||||
frame:SetScript("OnMouseDown", startMoving)
|
||||
frame:SetScript("OnMouseUp", stopMoving)
|
||||
frame:SetWidth(w)
|
||||
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
|
||||
frame:SetMinResize(40, 1)
|
||||
frame.lDrag:EnableMouse(true)
|
||||
frame.rDrag:EnableMouse(true)
|
||||
frame.lDrag:SetScript("OnMouseDown", startDragging)
|
||||
frame.rDrag:SetScript("OnMouseDown", startDragging)
|
||||
frame.lDrag:SetScript("OnMouseUp", stopDragging)
|
||||
frame.rDrag:SetScript("OnMouseUp", stopDragging)
|
||||
elseif val == "LOCK" then
|
||||
frame:SetWidth(self.db.profile.editW or w)
|
||||
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.db.profile.editX or x, self.db.profile.editY or y)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you customize the position and look of the edit box"]
|
||||
end
|
||||
|
||||
function mod:UpdateHeight()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local ff = _G["ChatFrame"..i.."EditBox"]
|
||||
ff:SetHeight(mod.db.profile.height)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local ff = _G[name.."EditBox"]
|
||||
ff:SetHeight(mod.db.profile.height)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
local mod = Chatter:NewModule("Editbox History", "AceHook-3.0" )
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Edit Box History"]
|
||||
|
||||
local history, enabled
|
||||
local defaults = { realm = { history = { } } }
|
||||
local editbox = DEFAULT_CHAT_FRAME.editBox
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Editbox History", defaults)
|
||||
history = self.db.realm.history
|
||||
|
||||
-- Hook adding lines
|
||||
self:SecureHook( editbox, "AddHistoryLine" )
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
-- Keeping state if we're enabled or not
|
||||
enable = false
|
||||
for _, line in ipairs( history ) do
|
||||
editbox:AddHistoryLine( line )
|
||||
end
|
||||
enabled = true
|
||||
end
|
||||
|
||||
function mod:AddHistoryLine( object, line )
|
||||
-- While in 'OnEnable' this code just returns
|
||||
if not self:IsEnabled() or not enabled then return end
|
||||
|
||||
local history = history
|
||||
tinsert( history, line )
|
||||
|
||||
-- clear out the excess values
|
||||
for i=1, #history - object:GetHistoryLines() do
|
||||
tremove( history, 1 )
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Remembers the history of the editbox across sessions."]
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
local mod = Chatter:NewModule("Group Say (/gr)", "AceHook-3.0", "AceConsole-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Group Say (/gr)"]
|
||||
|
||||
local GetNumPartyMembers = _G.GetNumPartyMembers
|
||||
local IsInInstance = _G.IsInInstance
|
||||
local GetNumPartyMembers = _G.GetNumPartyMembers
|
||||
local GetNumRaidMembers = _G.GetNumRaidMembers
|
||||
local SendChatMessage = _G.SendChatMessage
|
||||
|
||||
function mod:Decorate(frame)
|
||||
self:HookScript(_G[frame:GetName().."EditBox"], "OnTextChanged")
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, 10 do
|
||||
self:HookScript(_G["ChatFrame" .. i .. "EditBox"], "OnTextChanged")
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name.."EditBox"]
|
||||
if cf then
|
||||
self:HookScript(cf, "OnTextChanged")
|
||||
end
|
||||
end
|
||||
|
||||
if not self.slashCommandRegistered then
|
||||
self:RegisterChatCommand("gr", "SendChatMessage")
|
||||
self.slashCommandRegistered = true
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnTextChanged(obj)
|
||||
local text = obj:GetText()
|
||||
if text:sub(1, 4) == "/gr " then
|
||||
obj:SetText(self:GetGroupDistribution(true) .. text:sub(5));
|
||||
ChatEdit_ParseText(obj, 0)
|
||||
end
|
||||
self.hooks[obj].OnTextChanged(obj)
|
||||
end
|
||||
|
||||
function mod:SendChatMessage(input)
|
||||
SendChatMessage(input, self:GetGroupDistribution())
|
||||
end
|
||||
|
||||
function mod:GetGroupDistribution(slash)
|
||||
local inInstance, kind = IsInInstance()
|
||||
if inInstance and (kind == "pvp") then
|
||||
return slash and "/bg " or "BATTLEGROUND"
|
||||
end
|
||||
if GetNumRaidMembers() > 0 then
|
||||
return slash and "/ra " or "RAID"
|
||||
end
|
||||
if GetNumPartyMembers() > 0 then
|
||||
return slash and "/p " or "PARTY"
|
||||
end
|
||||
return slash and "/s " or "SAY"
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Provides a /gr slash command to let you speak in your group (raid, party, or battleground) automatically."]
|
||||
end
|
||||
@@ -0,0 +1,253 @@
|
||||
local mod = Chatter:NewModule("Highlights", "AceHook-3.0", "AceEvent-3.0", "LibSink-2.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Highlights"]
|
||||
|
||||
local Media = LibStub("LibSharedMedia-3.0")
|
||||
local PlaySoundFile = _G.PlaySoundFile
|
||||
local UnitName = _G.UnitName
|
||||
local pairs = _G.pairs
|
||||
local select = _G.select
|
||||
local type = _G.type
|
||||
local gsub = _G.string.gsub
|
||||
local ChatFrame_GetMessageEventFilters = _G.ChatFrame_GetMessageEventFilters
|
||||
local defSound = {["None"] = [[Interface\Quiet.mp3]]}
|
||||
Media:Register("sound", "Loot Chime", [[Sound\interface\igLootCreature.wav]])
|
||||
Media:Register("sound", "Whisper Ping", [[Sound\interface\iTellMessage.wav]])
|
||||
Media:Register("sound", "Magic Click", [[Sound\interface\MagicClick.wav]])
|
||||
|
||||
local player = UnitName("player")
|
||||
local defaults = {
|
||||
profile = {
|
||||
words = {
|
||||
[player:lower()] = player
|
||||
},
|
||||
sound = true,
|
||||
soundFile = "None",
|
||||
useSink = true,
|
||||
rerouteMessage = true,
|
||||
customChannels = {},
|
||||
sinkOptions = {}
|
||||
}
|
||||
}
|
||||
|
||||
local options = {
|
||||
defaultOptions = {
|
||||
type = "group",
|
||||
name = L["Options"],
|
||||
order = 1,
|
||||
args = {
|
||||
sound = {
|
||||
type = "toggle",
|
||||
name = L["Use sound"],
|
||||
desc = L["Play a soundfile when one of your keywords is said."],
|
||||
get = function()
|
||||
return mod.db.profile.sound
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.sound = v
|
||||
end
|
||||
},
|
||||
sink = {
|
||||
type = "toggle",
|
||||
name = L["Show SCT message"],
|
||||
desc = L["Show highlights in your SCT mod"],
|
||||
order = 21,
|
||||
get = function()
|
||||
return mod.db.profile.useSink
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.useSink = v
|
||||
end
|
||||
},
|
||||
rerouteMessage = {
|
||||
type = "toggle",
|
||||
name = L["Reroute whole message to SCT"],
|
||||
desc = L["Reroute whole message to SCT instead of just displaying 'who said keyword in channel'"],
|
||||
order = 22,
|
||||
get = function()
|
||||
return mod.db.profile.rerouteMessage
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.rerouteMessage = v
|
||||
end,
|
||||
disabled = function() return not mod.db.profile.useSink end
|
||||
},
|
||||
soundFile = {
|
||||
type = "select",
|
||||
name = L["Sound File"],
|
||||
desc = L["Sound file to play"],
|
||||
get = function()
|
||||
return mod.db.profile.soundFile
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.soundFile = v
|
||||
PlaySoundFile(Media:Fetch("sound", v))
|
||||
end,
|
||||
dialogControl = "LSM30_Sound",
|
||||
values = function () if Media:HashTable("sound") then return Media:HashTable("sound") else return defSound end end,
|
||||
disabled = function() return not mod.db.profile.sound end
|
||||
},
|
||||
addWord = {
|
||||
type = "input",
|
||||
name = L["Add Word"],
|
||||
desc = L["Add word to your highlight list"],
|
||||
get = function() end,
|
||||
set = function(info, v)
|
||||
-- no whitespace only stuff
|
||||
if v:match("^%s*$") then return end
|
||||
mod.db.profile.words[v:lower()] = v
|
||||
end
|
||||
},
|
||||
removeWord = {
|
||||
type = "select",
|
||||
name = L["Remove Word"],
|
||||
desc = L["Remove a word from your highlight list"],
|
||||
get = function() end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.words[v:lower()] = nil
|
||||
end,
|
||||
values = function() return mod.db.profile.words end,
|
||||
confirm = function(info, v) return (L["Remove this word from your highlights?"]) end
|
||||
}
|
||||
}
|
||||
},
|
||||
config = {
|
||||
type = "group",
|
||||
name = L["Custom Channel Sounds"],
|
||||
args = {}
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Highlight", defaults)
|
||||
self:AddCustomChannels(GetChannelList())
|
||||
self:SetSinkStorage(self.db.profile.sinkOptions)
|
||||
options.output = self:GetSinkAce3OptionsDataTable()
|
||||
end
|
||||
|
||||
local words
|
||||
function mod:OnEnable()
|
||||
words = self.db.profile.words
|
||||
self:RegisterEvent("CHAT_MSG_SAY", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_GUILD", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_BATTLEGROUND", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_BATTLEGROUND_LEADER", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_OFFICER", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_PARTY", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_RAID_LEADER", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_RAID", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_RAID_WARNING", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_SAY", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_WHISPER", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_BN_WHISPER", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_BN_CONVERSATION", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_YELL", "ParseChat")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
||||
self:AddCustomChannels(GetChannelList())
|
||||
self:AddCustomChannels(
|
||||
"YELL", L["Yell"],
|
||||
"GUILD", L["Guild"],
|
||||
"OFFICER", L["Officer"],
|
||||
"RAID", L["Raid"],
|
||||
"PARTY", L["Party"],
|
||||
"RAID_WARNING", L["Raid Warning"],
|
||||
"SAY", L["Say"],
|
||||
"BATTLEGROUND", L["Battleground"],
|
||||
"BATTLEGROUND_LEADER", L["Battleground"],
|
||||
"WHISPER", L["Whisper"],
|
||||
"BN_WHISPER", L["RealID Whisper"],
|
||||
"BN_CONVERSATION", L["RealID Conversation"]
|
||||
)
|
||||
end
|
||||
|
||||
function mod:CHAT_MSG_CHANNEL_NOTICE(evt, notice)
|
||||
self:AddCustomChannels(GetChannelList())
|
||||
end
|
||||
|
||||
function mod:AddCustomChannels(...)
|
||||
-- excludeChannels(EnumerateServerChannels())
|
||||
for i = 1, select("#", ...), 2 do
|
||||
local id, name = select(i, ...)
|
||||
if not options[name:gsub(" ", "_")] then
|
||||
options.config.args[name:gsub(" ", "_")] = {
|
||||
type = "select",
|
||||
name = name,
|
||||
values = Media:HashTable("sound") or {},
|
||||
desc = L["Play a sound when a message is received in this channel"],
|
||||
order = type(id) == "number" and 103 or 102,
|
||||
get = function() return self.db.profile.customChannels[id] or "None" end,
|
||||
set = function(info, v)
|
||||
self.db.profile.customChannels[id] = v
|
||||
PlaySoundFile(Media:Fetch("sound", v))
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ParseChat(evt, msg, sender, ...)
|
||||
if sender == player then return end
|
||||
|
||||
local filters = ChatFrame_GetMessageEventFilters(evt)
|
||||
if filters then
|
||||
for i, filterFunc in ipairs(filters) do
|
||||
local filtered, new_message = filterFunc(DEFAULT_CHAT_FRAME, evt, msg, sender, ...)
|
||||
if filtered then
|
||||
return
|
||||
end
|
||||
msg = new_message or msg
|
||||
end
|
||||
end
|
||||
|
||||
local msg = msg:lower()
|
||||
for k, v in pairs(words) do
|
||||
if msg:find(k) then
|
||||
self:Highlight(msg, sender, k, select(7, ...), evt)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if evt == "CHAT_MSG_CHANNEL" then
|
||||
local num = select(6, ...)
|
||||
local snd = self.db.profile.customChannels[num]
|
||||
if snd then
|
||||
PlaySoundFile(Media:Fetch("sound", snd))
|
||||
return
|
||||
end
|
||||
else
|
||||
local e = evt:gsub("^CHAT_MSG_", "")
|
||||
local snd = self.db.profile.customChannels[e]
|
||||
if snd then
|
||||
PlaySoundFile(Media:Fetch("sound", snd))
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Highlight(msg, who, what, where, event)
|
||||
if not where or #where == 0 then
|
||||
where = _G[event] or event:gsub("CHAT_MSG_", "")
|
||||
end
|
||||
if self.db.profile.sound then
|
||||
PlaySoundFile(Media:Fetch("sound", self.db.profile.soundFile))
|
||||
end
|
||||
if self.db.profile.useSink then
|
||||
if mod.db.profile.rerouteMessage then
|
||||
msg = gsub( msg, "|h[^|]+|h(.-)|h", "%1" )
|
||||
self:Pour((L["[%s] %s: %s"]):format(where, who, msg), 1, 1, 0, nil, 24, "OUTLINE", false)
|
||||
else
|
||||
self:Pour((L["%s said '%s' in %s"]):format(who, what, where), 1, 1, 0, nil, 24, "OUTLINE", false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Alerts you when someone says a keyword or speaks in a specified channel."]
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
-- vim: ts=4 noexpandtab
|
||||
@@ -0,0 +1,56 @@
|
||||
local mod = Chatter:NewModule("Justify Text")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Text Justification"]
|
||||
mod.toggleLabel = L["Enable text justification"]
|
||||
|
||||
local defaults = {
|
||||
profile = {}
|
||||
}
|
||||
|
||||
local VALID_JUSTIFICATIONS = {
|
||||
LEFT = L["Left"],
|
||||
RIGHT = L["Right"],
|
||||
CENTER = L["Center"]
|
||||
}
|
||||
|
||||
local options = {}
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("JustifyText", defaults)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local s = "FRAME_" .. i
|
||||
local f = _G["ChatFrame" .. i]
|
||||
options[s] = {
|
||||
type = "select",
|
||||
name = L["Chat Frame "] .. i,
|
||||
desc = L["Chat Frame "] .. i,
|
||||
values = VALID_JUSTIFICATIONS,
|
||||
get = function() return self.db.profile[s] or "LEFT" end,
|
||||
set = function(info, v)
|
||||
self.db.profile[s] = v
|
||||
f:SetJustifyH(v)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetJustifyH(self.db.profile["FRAME_" .. i] or "LEFT")
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetJustifyH("LEFT")
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you set the justification of text in your chat frames."]
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
local mod = Chatter:NewModule("Link Hover", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Link Hover"]
|
||||
|
||||
local strmatch = _G.string.match
|
||||
local linkTypes = {
|
||||
item = true,
|
||||
enchant = true,
|
||||
spell = true,
|
||||
quest = true,
|
||||
-- player = true
|
||||
}
|
||||
|
||||
function mod:Decorate(frame)
|
||||
self:HookScript(frame, "OnHyperlinkEnter", enter)
|
||||
self:HookScript(frame, "OnHyperlinkLeave", leave)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local frame = _G["ChatFrame"..i]
|
||||
self:HookScript(frame, "OnHyperlinkEnter", enter)
|
||||
self:HookScript(frame, "OnHyperlinkLeave", leave)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:HookScript(cf, "OnHyperlinkEnter", enter)
|
||||
self:HookScript(cf, "OnHyperlinkLeave", leave)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnHyperlinkEnter(f, link)
|
||||
local t = strmatch(link, "^(.-):")
|
||||
if linkTypes[t] then
|
||||
ShowUIPanel(GameTooltip)
|
||||
GameTooltip:SetOwner(UIParent, "ANCHOR_CURSOR")
|
||||
GameTooltip:SetHyperlink(link)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnHyperlinkLeave(f, link)
|
||||
local t = strmatch(link, "^(.-):")
|
||||
if linkTypes[t] then
|
||||
HideUIPanel(GameTooltip)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Makes link tooltips show when you hover them in chat."]
|
||||
end
|
||||
@@ -0,0 +1,714 @@
|
||||
local mod = Chatter:NewModule("Player Class Colors", "AceHook-3.0", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
local AceTab = LibStub("AceTab-3.0")
|
||||
|
||||
mod.modName = L["Player Names"]
|
||||
|
||||
local local_names = {}
|
||||
local leftBracket, rightBracket, separator
|
||||
local colorSelfInText, emphasizeSelfInText
|
||||
local gsub = _G.string.gsub
|
||||
local strmatch = _G.string.match
|
||||
local find = _G.string.find
|
||||
local pairs = _G.pairs
|
||||
local wipe = _G.wipe
|
||||
local string_format = _G.string.format
|
||||
local GetQuestDifficultyColor = _G.GetQuestDifficultyColor
|
||||
local GetChannelName = _G.GetChannelName
|
||||
local GetFriendInfo = _G.GetFriendInfo
|
||||
local GetGuildRosterInfo = _G.GetGuildRosterInfo
|
||||
local GetGuildRosterSelection = _G.GetGuildRosterSelection
|
||||
local GetGuildRosterShowOffline = _G.GetGuildRosterShowOffline
|
||||
local GetNumFriends = _G.GetNumFriends
|
||||
local GetNumGuildMembers = _G.GetNumGuildMembers
|
||||
local GetNumPartyMembers = _G.GetNumPartyMembers
|
||||
local GetNumRaidMembers = _G.GetNumRaidMembers
|
||||
local GetNumWhoResults = _G.GetNumWhoResults
|
||||
local GetWhoInfo = _G.GetWhoInfo
|
||||
local GuildRoster = _G.GuildRoster
|
||||
local SetGuildRosterSelection = _G.SetGuildRosterSelection
|
||||
local SetGuildRosterShowOffline = _G.SetGuildRosterShowOffline
|
||||
local UnitClass = _G.UnitClass
|
||||
local UnitExists = _G.UnitExists
|
||||
local UnitIsFriend = _G.UnitIsFriend
|
||||
local UnitIsPlayer = _G.UnitIsPlayer
|
||||
local UnitLevel = _G.UnitLevel
|
||||
local UnitName = _G.UnitName
|
||||
|
||||
local floor = _G.math.floor
|
||||
local select = _G.select
|
||||
local setmetatable = _G.setmetatable
|
||||
local sqrt = _G.sqrt
|
||||
local tinsert = _G.tinsert
|
||||
local type = _G.type
|
||||
|
||||
local player = UnitName("player")
|
||||
|
||||
|
||||
local channels = {
|
||||
GUILD = {},
|
||||
PARTY = {},
|
||||
RAID = {}
|
||||
}
|
||||
local colorMethods = {
|
||||
CLASS = L["Class"],
|
||||
NAME = L["Name"],
|
||||
NONE = L["None"],
|
||||
}
|
||||
|
||||
local defaults = {
|
||||
realm = {
|
||||
names = {},
|
||||
levels = {},
|
||||
},
|
||||
profile = {
|
||||
saveData = false,
|
||||
nameColoring = "CLASS",
|
||||
leftBracket = "[",
|
||||
rightBracket = "]",
|
||||
separator = ":",
|
||||
useTabComplete = true,
|
||||
colorSelfInText = true,
|
||||
emphasizeSelfInText = true,
|
||||
},
|
||||
global = {}
|
||||
}
|
||||
|
||||
defaults.global.classes = {}
|
||||
for _, class in ipairs(CLASS_SORT_ORDER) do
|
||||
defaults.global.classes[class] = LOCALIZED_CLASS_NAMES_MALE[class]
|
||||
end
|
||||
local default_nick_color = { ["r"] = 0.627, ["g"] = 0.627, ["b"] = 0.627 }
|
||||
|
||||
local localizedToSystemClass = table.invert(defaults.global.classes)
|
||||
|
||||
|
||||
local tabComplete
|
||||
do
|
||||
function tabComplete(t, text, pos)
|
||||
local word = text:sub(pos)
|
||||
if #word == 0 then return end
|
||||
local cf = ChatEdit_GetActiveWindow()
|
||||
local channel = cf:GetAttribute("chatType")
|
||||
if channel == "CHANNEL" then
|
||||
local cn = select(2, GetChannelName(cf:GetAttribute("channelTarget")))
|
||||
channel = cn and cn:lower() or ""
|
||||
elseif channel == "OFFICER" then
|
||||
channel = "GUILD"
|
||||
elseif channel == "RAID_WARNING" or channel == "RAID_LEADER" or channel == "BATTLEGROUND" or channel == "BATTLEGROUND_LEADER" then
|
||||
channel = "RAID"
|
||||
end
|
||||
if channels[channel] then
|
||||
for k, v in pairs(channels[channel]) do
|
||||
if k:lower():match("^" .. word:lower()) then
|
||||
tinsert(t, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
end
|
||||
|
||||
local getNameColor
|
||||
do
|
||||
local sq2 = sqrt(2)
|
||||
local pi = _G.math.pi
|
||||
local cos = _G.math.cos
|
||||
local fmod = _G.math.fmod
|
||||
local strbyte = _G.strbyte
|
||||
local t = {}
|
||||
|
||||
-- http://www.tecgraf.puc-rio.br/~mgattass/color/HSVtoRGB.htm
|
||||
|
||||
|
||||
local function HSVtoRGB(h, s, v)
|
||||
if ( s == 0 ) then
|
||||
--achromatic=fail
|
||||
t.r = v
|
||||
t.g = v
|
||||
t.b = v
|
||||
if not t.r then t.r = 0 end
|
||||
if not t.g then t.g = 0 end
|
||||
if not t.b then t.b = 0 end
|
||||
return t.r,t.g,t.b
|
||||
end
|
||||
h = h/60
|
||||
local i = floor(h)
|
||||
local i1 = v * (1 - s)
|
||||
local i2 = v * (1 - s * (h - i))
|
||||
local i3 = v * (1 - s * (1 - (h - i)))
|
||||
if i == 0 then
|
||||
-- return v, i3, i1
|
||||
t.r = v
|
||||
t.g = i3
|
||||
t.b = i1
|
||||
elseif i == 1 then
|
||||
-- return i2, v, i1
|
||||
t.r = i2
|
||||
t.g = v
|
||||
t.b = i1
|
||||
elseif i == 2 then
|
||||
-- return i1, v, i3
|
||||
t.r = i1
|
||||
t.g = v
|
||||
t.b = i3
|
||||
elseif i == 3 then
|
||||
-- return i3, i2, v
|
||||
t.r = i3
|
||||
t.g = i2
|
||||
t.b = v
|
||||
elseif i == 4 then
|
||||
-- return i3, i1, v
|
||||
t.r = i3
|
||||
t.g = i1
|
||||
t.b = v
|
||||
elseif i == 5 then
|
||||
-- return v, i1, i2
|
||||
t.r = v
|
||||
t.g = i1
|
||||
t.b = i2
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Chatter HSVtoRGB failed")
|
||||
end
|
||||
if not t.r then t.r = 0 end
|
||||
if not t.g then t.g = 0 end
|
||||
if not t.b then t.b = 0 end
|
||||
return t.r,t.g,t.b
|
||||
end
|
||||
|
||||
function getNameColor(name)
|
||||
local seed = 5381 --old seed: 5124
|
||||
local h, s, v = 1, 1, 1
|
||||
local r, g, b
|
||||
for i = 1, #name do
|
||||
seed = 33 * seed + strbyte(name, i) --used to use 29 here
|
||||
end
|
||||
-- h = fmod(seed, 255) / 255
|
||||
h = fmod(seed, 360) --changed the HSVtoRGB to acompany this change
|
||||
if (h > 220) and (h < 270) then
|
||||
h = h + 60
|
||||
end
|
||||
t.r, t.g, t.b = HSVtoRGB(h, s, v)
|
||||
|
||||
return t
|
||||
end
|
||||
end
|
||||
|
||||
local cache = {};
|
||||
|
||||
local function wipeCache()
|
||||
wipe(cache)
|
||||
end
|
||||
|
||||
local function updateSaveData(v)
|
||||
if v then
|
||||
for k, v in pairs(local_names) do
|
||||
mod.db.realm.names[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mod:OnInitialize()
|
||||
|
||||
self.db = Chatter.db:RegisterNamespace("PlayerNames", defaults)
|
||||
for k, v in pairs(self.db.realm.names) do
|
||||
if type(v) == "string" then
|
||||
self.db.realm.names[k] = {class = v}
|
||||
end
|
||||
end
|
||||
|
||||
if self.db.global and self.db.global.names then
|
||||
self.db.global.names = nil -- get rid of old data
|
||||
end
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mod:OnEnable()
|
||||
self:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
self:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
self:RegisterEvent("WHO_LIST_UPDATE")
|
||||
self:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
self:RegisterEvent("CHAT_MSG_SYSTEM", "WHO_LIST_UPDATE")
|
||||
self:RegisterEvent("FRIENDLIST_UPDATE")
|
||||
self:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_JOIN")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_LEAVE")
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL", "CHAT_MSG_CHANNEL_JOIN")
|
||||
|
||||
leftBracket, rightBracket, separator = self.db.profile.leftBracket, self.db.profile.rightBracket, self.db.profile.separator
|
||||
colorSelfInText, emphasizeSelfInText = self.db.profile.colorSelfInText, self.db.profile.emphasizeSelfInText
|
||||
if IsInGuild() then
|
||||
GuildRoster()
|
||||
end
|
||||
self:RAID_ROSTER_UPDATE()
|
||||
self:PARTY_MEMBERS_CHANGED()
|
||||
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,frame in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[frame]
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
if self.db.profile.useTabComplete then
|
||||
AceTab:RegisterTabCompletion("Chatter", nil, tabComplete)
|
||||
end
|
||||
|
||||
if CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS.RegisterCallback then
|
||||
CUSTOM_CLASS_COLORS:RegisterCallback(wipeCache)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
if AceTab:IsTabCompletionRegistered("Chatter") then
|
||||
AceTab:UnregisterTabCompletion("Chatter")
|
||||
end
|
||||
|
||||
if CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS.UnregisterCallback then
|
||||
CUSTOM_CLASS_COLORS:UnregisterCallback(wipeCache)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:ClearCustomClassColorCache()
|
||||
end
|
||||
|
||||
function mod:AddPlayer(name, class, level, save)
|
||||
if name and class and class ~= UNKNOWN then
|
||||
if save or self.db.realm.names[name] then -- if we already have an entry saved from elsewhere, we update it regardless of the requested "save" type - nothing else makes sense
|
||||
self.db.realm.names[name] = self.db.realm.names[name] or {}
|
||||
self.db.realm.names[name].class = class
|
||||
if level and level ~= 0 then
|
||||
self.db.realm.names[name].level = level
|
||||
end
|
||||
else
|
||||
local_names[name] = local_names[name] or {}
|
||||
local_names[name].class = class
|
||||
if level and level ~= 0 then
|
||||
local_names[name].level = level
|
||||
end
|
||||
end
|
||||
cache[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function mod:FRIENDLIST_UPDATE(evt)
|
||||
for i = 1, GetNumFriends() do
|
||||
local name, level, class = GetFriendInfo(i)
|
||||
if class then
|
||||
self:AddPlayer(name, localizedToSystemClass[class], level, self.db.profile.saveFriends)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
function mod:GUILD_ROSTER_UPDATE(evt)
|
||||
local n = GetNumGuildMembers()
|
||||
if not n or n == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local offline = GetGuildRosterShowOffline()
|
||||
local selection = GetGuildRosterSelection()
|
||||
self:UnregisterEvent("GUILD_ROSTER_UPDATE")
|
||||
|
||||
SetGuildRosterShowOffline(true)
|
||||
SetGuildRosterSelection(0)
|
||||
GetGuildRosterInfo(0)
|
||||
n = GetNumGuildMembers()
|
||||
for k, v in pairs(channels.GUILD) do
|
||||
channels.GUILD[k] = nil
|
||||
end
|
||||
for i = 1, n do
|
||||
local name, _, _, level, _, _, _, _, online, _, class = GetGuildRosterInfo(i)
|
||||
if online then
|
||||
channels.GUILD[name] = name
|
||||
end
|
||||
self:AddPlayer(name, class, level, self.db.profile.saveGuild)
|
||||
end
|
||||
SetGuildRosterShowOffline(offline)
|
||||
SetGuildRosterSelection(selection)
|
||||
|
||||
self:RegisterEvent("GUILD_ROSTER_UPDATE")
|
||||
end
|
||||
]]
|
||||
|
||||
function mod:GUILD_ROSTER_UPDATE(evt)
|
||||
if not IsInGuild() then return end
|
||||
wipe( channels.GUILD )
|
||||
for i = 1, GetNumGuildMembers() do
|
||||
local name, _, _, level, _, _, _, _, online, _, class = GetGuildRosterInfo(i)
|
||||
if name then
|
||||
if online then
|
||||
channels.GUILD[name] = name
|
||||
end
|
||||
self:AddPlayer(name, class, level, self.db.profile.saveGuild)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:RAID_ROSTER_UPDATE(evt)
|
||||
wipe(channels.RAID)
|
||||
|
||||
for i = 1, GetNumRaidMembers() do
|
||||
local n, _, _, l, _, c = GetRaidRosterInfo(i)
|
||||
if n and c and l then
|
||||
channels.RAID[n] = true
|
||||
self:AddPlayer(n, c, l, self.db.profile.saveParty)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:PARTY_MEMBERS_CHANGED(evt)
|
||||
wipe(channels.PARTY)
|
||||
|
||||
for i = 1, GetNumPartyMembers() do
|
||||
local n = UnitName("party" .. i)
|
||||
local _, c = UnitClass("party" .. i)
|
||||
local l = UnitLevel("party" .. i)
|
||||
channels.PARTY[n] = true
|
||||
self:AddPlayer(n, c, l, self.db.profile.saveParty)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:PLAYER_TARGET_CHANGED(evt)
|
||||
if not UnitExists("target") or not UnitIsPlayer("target") or not UnitIsFriend("player", "target") then return end
|
||||
local _, c = UnitClass("target")
|
||||
local l = UnitLevel("target")
|
||||
self:AddPlayer(UnitName("target"), c, l, self.db.profile.saveTarget)
|
||||
end
|
||||
|
||||
function mod:UPDATE_MOUSEOVER_UNIT(evt)
|
||||
if not UnitExists("mouseover") or not UnitIsPlayer("mouseover") or not UnitIsFriend("player", "mouseover") then return end
|
||||
local _, c = UnitClass("mouseover")
|
||||
local l = UnitLevel("mouseover")
|
||||
self:AddPlayer(UnitName("mouseover"), c, l, self.db.profile.saveTarget)
|
||||
end
|
||||
|
||||
function mod:WHO_LIST_UPDATE(evt)
|
||||
if GetNumWhoResults() <= 3 or self.db.profile.saveAllWho then
|
||||
for i = 1, GetNumWhoResults() do
|
||||
local name, _, level, _, _, _, class = GetWhoInfo(i)
|
||||
if class then
|
||||
self:AddPlayer(name, class, level, self.db.profile.saveWho)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:CHAT_MSG_CHANNEL_JOIN(evt, _, name, _, _, _, _, _, _, chan)
|
||||
channels[chan:lower()] = channels[chan:lower()] or {}
|
||||
channels[chan:lower()][name] = true
|
||||
end
|
||||
|
||||
function mod:CHAT_MSG_CHANNEL_LEAVE(evt, _, name, _, _, _, _, _, _, chan)
|
||||
if not channels[chan:lower()] then return end
|
||||
channels[chan:lower()][name] = nil
|
||||
end
|
||||
|
||||
local function changeName(msgHeader, name, extra, msgCnt,displayName, msgBody)
|
||||
if name ~= player then
|
||||
if emphasizeSelfInText then
|
||||
msgBody = msgBody:gsub("("..player..")" , "|cffffff00>|r%1|cffffff00<|r"):gsub("("..player:lower()..")" , "|cffffff00>|r%1|cffffff00<|r")
|
||||
end
|
||||
if colorSelfInText then
|
||||
msgBody = msgBody:gsub("("..player..")" , "|cffff0000%1|r"):gsub("("..player:lower()..")" , "|cffff0000%1|r")
|
||||
end
|
||||
end
|
||||
|
||||
if not strmatch( displayName, "|cff" ) then
|
||||
displayName = mod:ColorName( name )
|
||||
end
|
||||
|
||||
cache[name] = displayName
|
||||
|
||||
local level
|
||||
local tab = mod.db.realm.names[name] or local_names[name]
|
||||
if tab then
|
||||
level = mod.db.profile.includeLevel and tab.level or nil
|
||||
end
|
||||
|
||||
if level and (level ~= 80 or not mod.db.profile.excludeMaxLevel) then
|
||||
if mod.db.profile.levelByDiff then
|
||||
local c = GetQuestDifficultyColor(level)
|
||||
level = ("|cff%02x%02x%02x%s|r"):format(c.r * 255, c.g * 255, c.b * 255, level)
|
||||
displayName = ("%s%s%s"):format( displayName, separator, level )
|
||||
else
|
||||
-- If we already have a color -- steal it and use it to color the level
|
||||
if strmatch( displayName, "|cff......" ) then
|
||||
-- This will seriously fuck up the string if there is already more than 1 color ... FIXME
|
||||
level = gsub(displayName, "((|cff......).-|r)", function (string, color)
|
||||
return ("%s%s|r"):format( color, level )
|
||||
end )
|
||||
end
|
||||
displayName = ("%s%s%s"):format( displayName, separator, level )
|
||||
end
|
||||
end
|
||||
|
||||
return ("|Hplayer:%s%s%s|h%s%s%s|h%s"):format(name, extra, msgCnt, leftBracket, displayName, rightBracket, msgBody)
|
||||
end
|
||||
|
||||
function mod:ColorName( name )
|
||||
local class
|
||||
local tab = mod.db.realm.names[name] or local_names[name]
|
||||
if tab then class = tab.class end
|
||||
|
||||
-- already known?
|
||||
if cache[name] then
|
||||
name = cache[name]
|
||||
else
|
||||
local coloring = mod.db.profile.nameColoring
|
||||
|
||||
-- not yet colored by blizzy
|
||||
if coloring ~= "NONE" then
|
||||
local c = default_nick_color
|
||||
if coloring == "CLASS" then
|
||||
c = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class] or default_nick_color
|
||||
elseif coloring == "NAME" then
|
||||
c = getNameColor(name)
|
||||
end
|
||||
|
||||
name = ("|cff%02x%02x%02x%s|r"):format(c.r * 255, c.g * 255, c.b * 255, name )
|
||||
end
|
||||
end
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
if text and type(text) == "string" then
|
||||
text = text:gsub("(|Hplayer:([^|:]+)([:%d+]*)([^|]*)|h%[([^%]]+)%]|h)(.-)$", changeName)
|
||||
end
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Provides options to color player names, add player levels, and add tab completion of player names."]
|
||||
end
|
||||
|
||||
local options
|
||||
|
||||
function mod:GetOptions()
|
||||
if not options then -- save RAM / load time
|
||||
options = {
|
||||
save = {
|
||||
type = "group",
|
||||
name = L["Save Data"],
|
||||
desc = L["Save data between sessions. Will increase memory usage"],
|
||||
args = {
|
||||
guild = {
|
||||
type = "toggle",
|
||||
name = L["Guild"],
|
||||
desc = L["Save class data from guild between sessions."],
|
||||
get = function()
|
||||
return mod.db.profile.saveGuild
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveGuild = v
|
||||
updateSaveData(v)
|
||||
end
|
||||
},
|
||||
group = {
|
||||
type = "toggle",
|
||||
name = L["Group"],
|
||||
desc = L["Save class data from groups between sessions."],
|
||||
get = function()
|
||||
return mod.db.profile.saveGroup
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveGroup = v
|
||||
updateSaveData(v)
|
||||
end
|
||||
},
|
||||
friend = {
|
||||
type = "toggle",
|
||||
name = L["Friends"],
|
||||
desc = L["Save class data from friends between sessions."],
|
||||
get = function()
|
||||
return mod.db.profile.saveFriends
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveFriends = v
|
||||
updateSaveData(v)
|
||||
end
|
||||
},
|
||||
target = {
|
||||
type = "toggle",
|
||||
name = L["Target/Mouseover"],
|
||||
desc = L["Save class data from target/mouseover between sessions."],
|
||||
get = function()
|
||||
return mod.db.profile.saveTarget
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveTarget = v
|
||||
updateSaveData(v)
|
||||
end
|
||||
},
|
||||
who = {
|
||||
type = "toggle",
|
||||
name = L["Who"],
|
||||
desc = L["Save class data from /who queries between sessions."],
|
||||
order = 104,
|
||||
get = function()
|
||||
return mod.db.profile.saveWho
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveWho = v
|
||||
updateSaveData(v)
|
||||
end
|
||||
},
|
||||
saveAllWho = {
|
||||
type = "toggle",
|
||||
name = L["Save all /who data"],
|
||||
desc = L["Will save all data for large /who queries"],
|
||||
disabled = function() return not mod.db.profile.saveWho end,
|
||||
order = 105,
|
||||
get = function()
|
||||
return mod.db.profile.saveAllWho
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.saveAllWho = v
|
||||
end
|
||||
},
|
||||
resetDB = {
|
||||
type = "execute",
|
||||
name = L["Reset Data"],
|
||||
desc = L["Destroys all your saved class/level data"],
|
||||
func = function() wipe( mod.db.realm.names ) end,
|
||||
order = 101,
|
||||
confirm = function() return L["Are you sure you want to delete all your saved class/level data?"] end
|
||||
}
|
||||
}
|
||||
},
|
||||
leftbracket = {
|
||||
type = "input",
|
||||
name = L["Left Bracket"],
|
||||
desc = L["Character to use for the left bracket"],
|
||||
get = function() return mod.db.profile.leftBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.leftBracket = v
|
||||
leftBracket = v
|
||||
end
|
||||
},
|
||||
rightbracket = {
|
||||
type = "input",
|
||||
name = L["Right Bracket"],
|
||||
desc = L["Character to use for the right bracket"],
|
||||
get = function() return mod.db.profile.rightBracket end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.rightBracket = v
|
||||
rightBracket = v
|
||||
end
|
||||
},
|
||||
separator = {
|
||||
type = "input",
|
||||
name = L["Separator"],
|
||||
desc = L["Character to use between the name and level"],
|
||||
get = function() return mod.db.profile.separator end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.separator = v
|
||||
separator = v
|
||||
end
|
||||
},
|
||||
useTabComplete = {
|
||||
type = "toggle",
|
||||
name = L["Use Tab Complete"],
|
||||
desc = L["Use tab key to automatically complete character names."],
|
||||
get = function() return mod.db.profile.useTabComplete end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.useTabComplete = v
|
||||
if v and not AceTab:IsTabCompletionRegistered("Chatter") then
|
||||
AceTab:RegisterTabCompletion("Chatter", nil, tabComplete)
|
||||
elseif not v and AceTab:IsTabCompletionRegistered("Chatter") then
|
||||
AceTab:UnregisterTabCompletion("Chatter")
|
||||
end
|
||||
end
|
||||
},
|
||||
colorSelfInText = {
|
||||
type = "toggle",
|
||||
name = L["Color self in messages"],
|
||||
desc = L["Color own charname in messages."],
|
||||
get = function() return mod.db.profile.colorSelfInText end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.colorSelfInText = v
|
||||
colorSelfInText = v
|
||||
end
|
||||
},
|
||||
emphasizeSelfInText = {
|
||||
type = "toggle",
|
||||
name = L["Emphasize self in messages"],
|
||||
desc = L["Add surrounding brackets to own charname in messages."],
|
||||
width = "double",
|
||||
get = function() return mod.db.profile.emphasizeSelfInText end,
|
||||
set = function(i, v)
|
||||
mod.db.profile.emphasizeSelfInText = v
|
||||
emphasizeSelfInText = v
|
||||
end
|
||||
},
|
||||
levelHeader = {
|
||||
type = "header",
|
||||
name = L["Level Options"],
|
||||
order = 104
|
||||
},
|
||||
includeLevel = {
|
||||
type = "toggle",
|
||||
name = L["Include level"],
|
||||
desc = L["Include the player's level"],
|
||||
order = 105,
|
||||
get = function() return mod.db.profile.includeLevel end,
|
||||
set = function(info, val)
|
||||
mod.db.profile.includeLevel = val
|
||||
wipeCache()
|
||||
end
|
||||
},
|
||||
excludeMaxLevel = {
|
||||
type = "toggle",
|
||||
name = L["Exclude max levels"],
|
||||
desc = L["Exclude level display for max level characters"],
|
||||
order = 105,
|
||||
get = function() return mod.db.profile.excludeMaxLevel end,
|
||||
set = function(info, val)
|
||||
mod.db.profile.excludeMaxLevel = val
|
||||
wipeCache()
|
||||
end,
|
||||
hidden = function() return not mod.db.profile.includeLevel end
|
||||
},
|
||||
colorLevelByDifficulty = {
|
||||
type = "toggle",
|
||||
name = L["Color level by difficulty"],
|
||||
desc = L["Color level by difficulty"],
|
||||
order = 105,
|
||||
get = function()
|
||||
return mod.db.profile.levelByDiff
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.levelByDiff = v
|
||||
wipeCache()
|
||||
end,
|
||||
hidden = function() return not mod.db.profile.includeLevel end
|
||||
},
|
||||
colorBy = {
|
||||
type = "select",
|
||||
name = L["Color Player Names By..."],
|
||||
desc = L["Select a method for coloring player names"],
|
||||
values = colorMethods,
|
||||
get = function() return mod.db.profile.nameColoring end,
|
||||
set = function(info, val)
|
||||
mod.db.profile.nameColoring = val
|
||||
wipeCache()
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,90 @@
|
||||
local mod = Chatter:NewModule("Scrollback")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Scrollback"]
|
||||
mod.toggleLabel = L["Enable Scrollback length modification"]
|
||||
|
||||
local defaults = {
|
||||
profile = {}
|
||||
}
|
||||
|
||||
local options = {}
|
||||
|
||||
local cache = setmetatable({}, {__mode='k'})
|
||||
|
||||
local function acquire()
|
||||
local t = next(cache) or {}
|
||||
cache[t] = nil
|
||||
return t
|
||||
end
|
||||
|
||||
local function reclaim(t)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
cache[t] = true
|
||||
end
|
||||
|
||||
local function setlines(frame, lines)
|
||||
if frame:GetMaxLines() ~= lines then
|
||||
local history = acquire()
|
||||
for regions = frame:GetNumRegions(),1,-1 do
|
||||
local region = select(regions, frame:GetRegions())
|
||||
if region:GetObjectType() == "FontString" then
|
||||
table.insert(history, {region:GetText(), region:GetTextColor() })
|
||||
end
|
||||
end
|
||||
|
||||
frame:SetMaxLines(lines or 250)
|
||||
|
||||
Chatter.loading = true
|
||||
|
||||
for k,v in pairs(history) do
|
||||
frame:AddMessage(unpack(v))
|
||||
end
|
||||
|
||||
Chatter.loading = false
|
||||
|
||||
reclaim(history)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Scrollback", defaults)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local s = "FRAME_" .. i
|
||||
local frame = _G["ChatFrame" .. i]
|
||||
options[s] = {
|
||||
type = "range",
|
||||
name = L["Chat Frame "] .. i,
|
||||
desc = L["Chat Frame "] .. i,
|
||||
min = 250,
|
||||
max = 2500,
|
||||
step = 10,
|
||||
get = function() return self.db.profile[s] or 250 end,
|
||||
set = function(info, value)
|
||||
self.db.profile[s] = value
|
||||
setlines(frame, value)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
setlines(_G["ChatFrame"..i], self.db.profile["FRAME_"..i])
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
setlines(_G["ChatFrame"..i], 250)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you set the scrollback length of your chat frames."]
|
||||
end
|
||||
@@ -0,0 +1,74 @@
|
||||
local mod = Chatter:NewModule("Server Positioning", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Server Positioning"]
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
windowdata = {
|
||||
['*'] = {
|
||||
-- Blizzard defaults
|
||||
width = 430,
|
||||
height = 120,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Server Positioning", defaults)
|
||||
self.db.RegisterCallback(self, "OnProfileChanged", "UpdateWindowData")
|
||||
self.db.RegisterCallback(self, "OnProfileCopied", "UpdateWindowData")
|
||||
self.db.RegisterCallback(self, "OnProfileReset", "UpdateWindowData")
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Disable server side storage of chat frame position and size."]
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
self:RawHook('SetChatWindowSavedPosition', true)
|
||||
self:RawHook('GetChatWindowSavedPosition', true)
|
||||
self:RawHook('SetChatWindowSavedDimensions', true)
|
||||
self:RawHook('GetChatWindowSavedDimensions', true)
|
||||
self:UpdateWindowData()
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
self:UnhookAll()
|
||||
self:UpdateWindowData()
|
||||
end
|
||||
|
||||
function mod:SetChatWindowSavedPosition(id, point, xOffset, yOffset)
|
||||
local data = self.db.profile.windowdata[id]
|
||||
data.point, data.xOffset, data.yOffset = point, xOffset, yOffset
|
||||
end
|
||||
|
||||
function mod:GetChatWindowSavedPosition(id)
|
||||
local data = self.db.profile.windowdata[id]
|
||||
if not data.point then
|
||||
data.point, data.xOffset, data.yOffset = self.hooks.GetChatWindowSavedPosition(id)
|
||||
end
|
||||
return data.point, data.xOffset, data.yOffset
|
||||
end
|
||||
|
||||
function mod:SetChatWindowSavedDimensions(id, width, height)
|
||||
local data = self.db.profile.windowdata[id]
|
||||
data.width, data.height = width, height
|
||||
end
|
||||
|
||||
function mod:GetChatWindowSavedDimensions(id)
|
||||
local data = self.db.profile.windowdata[id]
|
||||
if not data.width then
|
||||
data.width, data.height = self.hooks.GetChatWindowSavedDimensions(id)
|
||||
end
|
||||
return data.width, data.height
|
||||
end
|
||||
|
||||
function mod:UpdateWindowData()
|
||||
for i = 1,NUM_CHAT_WINDOWS do
|
||||
local frame = _G["ChatFrame"..i]
|
||||
if frame and type(frame.GetID) == "function" then
|
||||
FloatingChatFrame_Update(frame:GetID())
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,98 @@
|
||||
local mod = Chatter:NewModule("Message Splitting", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Message Split"]
|
||||
|
||||
function mod:Info()
|
||||
return L["Allows you to type messages longer than normal, and splits message that are too long."]
|
||||
end
|
||||
|
||||
local function ChatEdit_SendText(editBox, addHistory, doParse)
|
||||
if doParse then
|
||||
ChatEdit_ParseText(editBox, 1);
|
||||
end
|
||||
|
||||
local type = editBox:GetAttribute("chatType");
|
||||
local text = editBox:GetText();
|
||||
if ( strfind(text, "%s*[^%s]+") ) then
|
||||
if ( type == "WHISPER") then
|
||||
local target = editBox:GetAttribute("tellTarget");
|
||||
ChatEdit_SetLastToldTarget(target);
|
||||
SendChatMessage(text, type, editBox.language, target);
|
||||
elseif ( type == "CHANNEL") then
|
||||
SendChatMessage(text, type, editBox.language, editBox:GetAttribute("channelTarget"));
|
||||
else
|
||||
SendChatMessage(text, type, editBox.language);
|
||||
end
|
||||
if ( addHistory ) then
|
||||
ChatEdit_AddHistory(editBox);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local MAX = 256
|
||||
local getChunk
|
||||
do
|
||||
local buf = {}
|
||||
function getChunk(text, start)
|
||||
local stack = 0
|
||||
local first = nil
|
||||
buf = wipe(buf)
|
||||
if start > #text then return nil end
|
||||
for i = start, start + MAX - 1 do
|
||||
local byte = text:sub(i, i)
|
||||
local bit = text:sub(i, i+1)
|
||||
if bit == "|c" or bit == "|H" then
|
||||
first = first or i
|
||||
stack = stack + 1
|
||||
elseif (bit == "|r" or bit == "|h") and stack > 0 and first then
|
||||
stack = stack - 1
|
||||
if stack == 0 then
|
||||
tinsert(buf, text:sub(first, i))
|
||||
first = nil
|
||||
end
|
||||
elseif (byte == " " or byte == "") and stack == 0 and first then
|
||||
tinsert(buf, text:sub(first or 1, i))
|
||||
first = nil
|
||||
else
|
||||
first = first or i
|
||||
end
|
||||
end
|
||||
if #buf == 0 then return nil end
|
||||
local str = table.concat(buf, "")
|
||||
return start + #str, str
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnterPressed(editBox)
|
||||
local text = editBox:GetText()
|
||||
if #text <= 255 then
|
||||
ChatEdit_OnEnterPressed(editBox)
|
||||
return
|
||||
end
|
||||
|
||||
local first = true
|
||||
for start, chunk in getChunk, text, 1 do
|
||||
editBox:SetText(chunk)
|
||||
ChatEdit_SendText(editBox, true, first);
|
||||
first = false
|
||||
end
|
||||
|
||||
local type = editBox:GetAttribute("chatType");
|
||||
if ( ChatTypeInfo[type].sticky == 1 ) then
|
||||
editBox:SetAttribute("stickyType", type);
|
||||
end
|
||||
|
||||
ChatEdit_OnEscapePressed(editBox);
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
ChatFrameEditBox:SetMaxLetters(2048)
|
||||
ChatFrameEditBox:SetMaxBytes(2048)
|
||||
|
||||
self:RawHookScript(ChatFrameEditBox, "OnEnterPressed")
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
ChatFrameEditBox:SetMaxLetters(256)
|
||||
ChatFrameEditBox:SetMaxBytes(256)
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
local mod = Chatter:NewModule("Sticky Channels")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Sticky Channels"]
|
||||
|
||||
local pairs = _G.pairs
|
||||
|
||||
local channels = {
|
||||
SAY = L["Say"],
|
||||
EMOTE = L["Emote"],
|
||||
YELL = L["Yell"],
|
||||
OFFICER = L["Officer"],
|
||||
RAID_WARNING = L["Raid Warning"],
|
||||
WHISPER = L["Whisper"],
|
||||
BN_WHISPER = L["RealID Whisper"],
|
||||
CHANNEL = L["Custom channels"]
|
||||
}
|
||||
local options = {}
|
||||
local defaults = {profile = {}}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("StickyChannels", defaults)
|
||||
for k, v in pairs(channels) do
|
||||
defaults.profile[k] = true
|
||||
options[k] = {
|
||||
type = "toggle",
|
||||
name = v,
|
||||
desc = (L["Make %s sticky"]):format(v),
|
||||
get = function() return mod.db.profile[k] end,
|
||||
set = function(info, v)
|
||||
mod.db.profile[k] = v
|
||||
ChatTypeInfo[k].sticky = v and 1 or 0
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for k, v in pairs(channels) do
|
||||
ChatTypeInfo[k].sticky = self.db.profile[k] and 1 or 0
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
ChatTypeInfo.EMOTE.sticky = 0
|
||||
ChatTypeInfo.YELL.sticky = 0
|
||||
ChatTypeInfo.OFFICER.sticky = 0
|
||||
ChatTypeInfo.RAID_WARNING.sticky = 0
|
||||
ChatTypeInfo.WHISPER.sticky = 0
|
||||
ChatTypeInfo.CHANNEL.sticky = 0
|
||||
ChatTypeInfo.BN_WHISPER.sticky = 0
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Makes channels you select sticky."]
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
local mod = Chatter:NewModule("Tell Target (/tt)", "AceHook-3.0", "AceEvent-3.0", "AceConsole-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Tell Target (/tt)"]
|
||||
|
||||
local UnitIsPlayer = _G.UnitIsPlayer
|
||||
local UnitCanAssist = _G.UnitCanAssist
|
||||
local UnitIsCharmed = _G.UnitIsCharmed
|
||||
local SendChatMessage = _G.SendChatMessage
|
||||
local UnitIsSameServer = _G.UnitIsSameServer
|
||||
local UnitName = _G.UnitName
|
||||
|
||||
local gsub = _G.string.gsub
|
||||
|
||||
function mod:OnEnable()
|
||||
-- self:SecureHook("ChatEdit_ParseText")
|
||||
for i = 1, 10 do
|
||||
self:HookScript(_G["ChatFrame" .. i .. "EditBox"], "OnTextChanged")
|
||||
end
|
||||
if not self.slashCommandRegistered then
|
||||
self:RegisterChatCommand("tt", "SendChatMessage")
|
||||
self.slashCommandRegistered = true
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnTextChanged(obj)
|
||||
local text = obj:GetText()
|
||||
if text:sub(1, 4) == "/tt " then
|
||||
self:TellTarget(obj.chatFrame, text:sub(5))
|
||||
end
|
||||
self.hooks[obj].OnTextChanged(obj)
|
||||
end
|
||||
|
||||
function mod:TellTarget(frame, msg)
|
||||
local unitname, realm
|
||||
if UnitIsPlayer("target") and (UnitIsFriend("player", "target") or UnitIsCharmed("target")) then
|
||||
unitname, realm = UnitName("target")
|
||||
if unitname then unitname = gsub(unitname, " ", "") end
|
||||
if unitname and not UnitIsSameServer("player", "target") then
|
||||
unitname = unitname .. "-" .. gsub(realm, " ", "")
|
||||
end
|
||||
end
|
||||
ChatFrame_SendTell((unitname or "InvalidTarget"), frame)
|
||||
_G[frame:GetName() .. "EditBox"]:SetText(msg)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Enables the /tt command to send a tell to your target."]
|
||||
end
|
||||
|
||||
function mod:SendChatMessage(input)
|
||||
if UnitIsPlayer("target") and (UnitCanAssist("player", "target") or UnitIsCharmed("target"))then
|
||||
SendChatMessage(input, "WHISPER", nil, UnitName("target"))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
local mod = Chatter:NewModule("Timestamps", "AceHook-3.0","AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Timestamps"]
|
||||
|
||||
local date = _G.date
|
||||
|
||||
local SELECTED_FORMAT
|
||||
local COLOR
|
||||
local FORMATS = {
|
||||
["%I:%M:%S %p"] = L["HH:MM:SS AM (12-hour)"],
|
||||
["%I:%M:S"] = L["HH:MM (12-hour)"],
|
||||
["%X"] = L["HH:MM:SS (24-hour)"],
|
||||
["%I:%M"] = L["HH:MM (12-hour)"],
|
||||
["%H:%M"] = L["HH:MM (24-hour)"],
|
||||
["%M:%S"] = L["MM:SS"],
|
||||
}
|
||||
local CHATFRAMES = {
|
||||
["Frame1"] = L["Chat Frame "].."1",
|
||||
["Frame3"] = L["Chat Frame "].."3",
|
||||
["Frame4"] = L["Chat Frame "].."4",
|
||||
["Frame5"] = L["Chat Frame "].."5",
|
||||
["Frame6"] = L["Chat Frame "].."6",
|
||||
["Frame7"] = L["Chat Frame "].."7",
|
||||
["Frame8"] = L["Chat Frame "].."8",
|
||||
["Frame9"] = L["Chat Frame "].."9",
|
||||
["Frame10"] = L["Chat Frame "].."10",
|
||||
["Frame11"] = L["Chat Frame "].."11",
|
||||
["Frame12"] = L["Chat Frame "].."12",
|
||||
["Frame13"] = L["Chat Frame "].."13",
|
||||
["Frame14"] = L["Chat Frame "].."14",
|
||||
["Frame15"] = L["Chat Frame "].."15",
|
||||
["Frame16"] = L["Chat Frame "].."16",
|
||||
["Frame17"] = L["Chat Frame "].."17",
|
||||
["Frame18"] = L["Chat Frame "].."18",
|
||||
}
|
||||
|
||||
local defaults = {
|
||||
profile = { format = "%X", color = { r = 0.45, g = 0.45, b = 0.45 }, frames = {["Frame1"] = true, ["Frame3"] = true, ["Frame4"] = true, ["Frame5"] = true, ["Frame6"] = true, ["Frame7"] = true} }
|
||||
}
|
||||
|
||||
local options = {
|
||||
format = {
|
||||
type = "select",
|
||||
name = L["Timestamp format"],
|
||||
desc = L["Timestamp format"],
|
||||
values = FORMATS,
|
||||
get = function() return mod.db.profile.format end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.format = v
|
||||
SELECTED_FORMAT = ("[" .. v .. "]")
|
||||
end
|
||||
},
|
||||
customFormat = {
|
||||
type = "input",
|
||||
name = L["Custom format (advanced)"],
|
||||
desc = L["Enter a custom time format. See http://www.lua.org/pil/22.1.html for a list of valid formatting symbols."],
|
||||
get = function() return mod.db.profile.customFormat end,
|
||||
set = function(info, v)
|
||||
if #v == 0 then v = nil end
|
||||
mod.db.profile.customFormat = v
|
||||
SELECTED_FORMAT = v
|
||||
end,
|
||||
order = 101
|
||||
},
|
||||
color = {
|
||||
type = "color",
|
||||
name = L["Timestamp color"],
|
||||
desc = L["Timestamp color"],
|
||||
get = function()
|
||||
local c = mod.db.profile.color
|
||||
return c.r, c.g, c.b
|
||||
end,
|
||||
set = function(info, r, g, b, a)
|
||||
local c = mod.db.profile.color
|
||||
c.r, c.g, c.b = r, g, b
|
||||
COLOR = ("%02x%02x%02x"):format(r * 255, g * 255, b * 255)
|
||||
end,
|
||||
disabled = function() return mod.db.profile.colorByChannel end
|
||||
},
|
||||
useChannelColor = {
|
||||
type = "toggle",
|
||||
name = L["Use channel color"],
|
||||
desc = L["Color timestamps the same as the channel they appear in."],
|
||||
get = function()
|
||||
return mod.db.profile.colorByChannel
|
||||
end,
|
||||
set = function(info, v)
|
||||
mod.db.profile.colorByChannel = v
|
||||
end
|
||||
},
|
||||
frames = {
|
||||
type = "multiselect",
|
||||
name = L["Per chat frame settings"],
|
||||
desc = L["Choose which chat frames display timestamps"],
|
||||
values = CHATFRAMES,
|
||||
get = function(info, k) return mod.db.profile.frames[k] end,
|
||||
set = function(info, k, v) mod.db.profile.frames[k] = v end,
|
||||
},
|
||||
}
|
||||
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("Timestamps", defaults)
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
if not self:IsHooked(frame,"AddMessage") then
|
||||
self:RawHook(frame, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
SELECTED_FORMAT = mod.db.profile.customFormat or ("[" .. self.db.profile.format .. "]")
|
||||
local c = self.db.profile.color
|
||||
COLOR = ("%02x%02x%02x"):format(c.r * 255, c.g * 255, c.b * 255)
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
if cf ~= COMBATLOG then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
self:RawHook(cf, "AddMessage", true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:AddMessage(frame, text, ...)
|
||||
local id = frame:GetID()
|
||||
if id and self.db.profile.frames["Frame"..id] and not(CHAT_TIMESTAMP_FORMAT) then
|
||||
if not Chatter.loading then
|
||||
if not text then
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
if self.db.profile.colorByChannel then
|
||||
text = date(SELECTED_FORMAT) .. text
|
||||
else
|
||||
text = "|cff"..COLOR..date(SELECTED_FORMAT).."|r".. text
|
||||
end
|
||||
end
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
return self.hooks[frame].AddMessage(frame, text, ...)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Adds timestamps to chat."]
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
local mod = Chatter:NewModule("Tiny Chat")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["Tiny Chat"]
|
||||
|
||||
function mod:Info()
|
||||
return L["Allows you to make the chat frames much smaller than usual."]
|
||||
end
|
||||
|
||||
function mod:Decorate(frame)
|
||||
frame:SetMinResize(50, 20)
|
||||
frame:SetMaxResize(5000, 5000)
|
||||
end
|
||||
|
||||
function mod:OnEnable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetMinResize(50, 20)
|
||||
cf:SetMaxResize(5000, 5000)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetMinResize(50, 20)
|
||||
cf:SetMaxResize(5000, 5000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnDisable()
|
||||
for i = 1, NUM_CHAT_WINDOWS do
|
||||
local cf = _G["ChatFrame" .. i]
|
||||
cf:SetMinResize(296, 75)
|
||||
cf:SetMaxResize(608, 400)
|
||||
end
|
||||
for index,name in ipairs(self.TempChatFrames) do
|
||||
local cf = _G[name]
|
||||
if cf then
|
||||
cf:SetMinResize(296, 75)
|
||||
cf:SetMaxResize(608, 400)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,535 @@
|
||||
local mod = Chatter:NewModule("URL Copy", "AceHook-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("Chatter")
|
||||
mod.modName = L["URL Copy"]
|
||||
|
||||
local gsub = _G.string.gsub
|
||||
local ipairs = _G.ipairs
|
||||
local pairs = _G.pairs
|
||||
local fmt = _G.string.format
|
||||
local sub = _G.string.sub
|
||||
|
||||
local tlds
|
||||
local style = "|cffffffff|Hurl:%s|h[%s]|h|r"
|
||||
local function Link(link, ...)
|
||||
if link == nil then
|
||||
return ""
|
||||
end
|
||||
return mod:RegisterMatch(fmt(style, link, link))
|
||||
end
|
||||
local function Link_TLD(link, tld, ...)
|
||||
if link == nil or tld == nil then
|
||||
return ""
|
||||
end
|
||||
if tlds[tld:upper()] then
|
||||
return mod:RegisterMatch(fmt(style, link, link))
|
||||
else
|
||||
return mod:RegisterMatch(link)
|
||||
end
|
||||
end
|
||||
|
||||
local patterns = {
|
||||
-- X://Y url
|
||||
{ pattern = "^(%a[%w%.+-]+://%S+)", matchfunc=Link},
|
||||
{ pattern = "%f[%S](%a[%w%.+-]+://%S+)", matchfunc=Link},
|
||||
-- www.X.Y url
|
||||
{ pattern = "^(www%.[-%w_%%]+%.%S+)", matchfunc=Link},
|
||||
{ pattern = "%f[%S](www%.[-%w_%%]+%.%S+)", matchfunc=Link},
|
||||
-- "W X"@Y.Z email (this is seriously a valid email)
|
||||
--{ pattern = '^(%"[^%"]+%"@[-%w_%%%.]+%.(%a%a+))', matchfunc=Link_TLD},
|
||||
--{ pattern = '%f[%S](%"[^%"]+%"@[-%w_%%%.]+%.(%a%a+))', matchfunc=Link_TLD},
|
||||
-- X@Y.Z email
|
||||
{ pattern = "(%S+@[-%w_%%%.]+%.(%a%a+))", matchfunc=Link_TLD},
|
||||
-- XXX.YYY.ZZZ.WWW:VVVV/UUUUU IPv4 address with port and path
|
||||
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link},
|
||||
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link},
|
||||
-- XXX.YYY.ZZZ.WWW:VVVV IPv4 address with port (IP of ts server for example)
|
||||
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link},
|
||||
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d:[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link},
|
||||
-- XXX.YYY.ZZZ.WWW/VVVVV IPv4 address with path
|
||||
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%/%S+)", matchfunc=Link},
|
||||
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%/%S+)", matchfunc=Link},
|
||||
-- XXX.YYY.ZZZ.WWW IPv4 address
|
||||
{ pattern = "^([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%)%f[%D]", matchfunc=Link},
|
||||
{ pattern = "%f[%S]([0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%.[0-2]?%d?%d%)%f[%D]", matchfunc=Link},
|
||||
-- X.Y.Z:WWWW/VVVVV url with port and path
|
||||
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link_TLD},
|
||||
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d/%S+)", matchfunc=Link_TLD},
|
||||
-- X.Y.Z:WWWW url with port (ts server for example)
|
||||
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link_TLD},
|
||||
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+):[0-6]?%d?%d?%d?%d)%f[%D]", matchfunc=Link_TLD},
|
||||
-- X.Y.Z/WWWWW url with path
|
||||
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+)/%S+)", matchfunc=Link_TLD},
|
||||
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+)/%S+)", matchfunc=Link_TLD},
|
||||
-- X.Y.Z url
|
||||
{ pattern = "^([-%w_%%%.]+[-%w_%%]%.(%a%a+))", matchfunc=Link_TLD},
|
||||
{ pattern = "%f[%S]([-%w_%%%.]+[-%w_%%]%.(%a%a+))", matchfunc=Link_TLD},
|
||||
}
|
||||
|
||||
local options = {
|
||||
mangleMumble = {
|
||||
type = "toggle",
|
||||
name = L["Parse Mumble links"],
|
||||
desc = L["Automatically inject your character's name into Mumble links, so you connect with your username prefilled."],
|
||||
get = function() return mod.db.profile.mangleMumble end,
|
||||
set = function(info, v) mod.db.profile.mangleMumble = v end
|
||||
},
|
||||
mangleTeamspeak = {
|
||||
type = "toggle",
|
||||
name = L["Parse Teamspeak 3 links"],
|
||||
desc = L["Automatically inject your character's name into Teamspeak 3 links, so you connect with your username prefilled."],
|
||||
get = function() return mod.db.profile.mangleTeamspeak end,
|
||||
set = function(info, v) mod.db.profile.mangleTeamspeak = v end
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
|
||||
local defaults = {
|
||||
profile = {
|
||||
mangleMumble = true,
|
||||
mangleTeamspeak = true
|
||||
}
|
||||
}
|
||||
local events = {
|
||||
"CHAT_MSG_BATTLEGROUND", "CHAT_MSG_BATTLEGROUND_LEADER",
|
||||
"CHAT_MSG_CHANNEL", "CHAT_MSG_EMOTE",
|
||||
"CHAT_MSG_GUILD", "CHAT_MSG_OFFICER",
|
||||
"CHAT_MSG_PARTY", "CHAT_MSG_RAID",
|
||||
"CHAT_MSG_RAID_LEADER", "CHAT_MSG_RAID_WARNING", "CHAT_MSG_PARTY_LEADER",
|
||||
"CHAT_MSG_SAY", "CHAT_MSG_WHISPER","CHAT_MSG_BN_WHISPER",
|
||||
"CHAT_MSG_WHISPER_INFORM", "CHAT_MSG_YELL", "CHAT_MSG_BN_WHISPER_INFORM","CHAT_MSG_BN_CONVERSATION"
|
||||
}
|
||||
function mod:OnInitialize()
|
||||
self.db = Chatter.db:RegisterNamespace("UrlCopy", defaults)
|
||||
end
|
||||
function mod:OnEnable()
|
||||
for _,event in ipairs(events) do
|
||||
ChatFrame_AddMessageEventFilter(event, self.filterFunc)
|
||||
end
|
||||
self:RawHook("SetItemRef", true)
|
||||
end
|
||||
function mod:OnDisable()
|
||||
for _,event in ipairs(events) do
|
||||
ChatFrame_RemoveMessageEventFilter(event, self.filterFunc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local tokennum, matchTable = 1, {}
|
||||
mod.filterFunc = function(frame, event, msg, ...)
|
||||
if not msg then return false, msg, ... end
|
||||
for i, v in ipairs(patterns) do
|
||||
msg = gsub(msg, v.pattern, v.matchfunc)
|
||||
end
|
||||
for k,v in pairs(matchTable) do
|
||||
msg = gsub(msg, k, v)
|
||||
matchTable[k] = nil
|
||||
end
|
||||
return false, msg, ...
|
||||
end
|
||||
function mod:RegisterMatch(text)
|
||||
local token = "\255\254\253"..tokennum.."\253\254\255"
|
||||
matchTable[token] = gsub(text, "%%", "%%%%")
|
||||
tokennum = tokennum + 1
|
||||
return token
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Popup Box ]]--
|
||||
local currentLink
|
||||
|
||||
StaticPopupDialogs["ChatterUrlCopyDialog"] = {
|
||||
text = "URL - Ctrl-C to copy",
|
||||
button2 = CLOSE,
|
||||
hasEditBox = 1,
|
||||
hasWideEditBox = 1,
|
||||
OnShow = function()
|
||||
local editBox = _G[this:GetName().."WideEditBox"]
|
||||
if editBox then
|
||||
editBox:SetText(currentLink)
|
||||
editBox:SetFocus()
|
||||
editBox:HighlightText(0)
|
||||
end
|
||||
local button = _G[this:GetName().."Button2"]
|
||||
if button then
|
||||
button:ClearAllPoints()
|
||||
button:SetWidth(200)
|
||||
button:SetPoint("CENTER", editBox, "CENTER", 0, -30)
|
||||
end
|
||||
end,
|
||||
EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
|
||||
timeout = 0,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1,
|
||||
maxLetters=1024, -- this otherwise gets cached from other dialogs which caps it at 10..20..30...
|
||||
}
|
||||
|
||||
local mangleLinkForVoiceChat
|
||||
do
|
||||
--[[
|
||||
mumble://192.168.1.102:50008?version=1.2.0
|
||||
mumble://foo:bar@192.168.1.102:50008?version=1.2.0
|
||||
mumble://:bar@192.168.1.102:50008?version=1.2.0
|
||||
]]--
|
||||
|
||||
-- Messes with Mumble links to inject our own username. Nifty magical!
|
||||
local function injectCharacterNameForMumble(scheme, connstr)
|
||||
local pre, post = strsplit("@", connstr, 2)
|
||||
local new
|
||||
if post then
|
||||
local user, password = strsplit(":", pre, 2)
|
||||
if password then
|
||||
new = UnitName("player") .. ":" .. password
|
||||
else
|
||||
new = UnitName("player")
|
||||
end
|
||||
new = new .. "@" .. post
|
||||
else
|
||||
new = UnitName("player") .. "@" .. pre
|
||||
end
|
||||
return scheme .. new
|
||||
end
|
||||
|
||||
local buff = {}
|
||||
local function addTS3Nickname(...)
|
||||
wipe(buff)
|
||||
for i = 1, select("#", ...) do
|
||||
local chunk = select(i, ...)
|
||||
local key, val = strsplit("=", chunk, 2)
|
||||
if val then
|
||||
if strlower(key) ~= "nickname" then
|
||||
tinsert(buff, chunk)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not gotName then
|
||||
local nick = "nickname=" .. UnitName("player")
|
||||
tinsert(buff, nick)
|
||||
end
|
||||
return table.concat(buff, "&")
|
||||
end
|
||||
|
||||
--[[
|
||||
ts3server://ts3.hoster.com
|
||||
ts3server://ts3.hoster.com?
|
||||
ts3server://ts3.hoster.com?port=9987&
|
||||
ts3server://ts3.hoster.com?port=9987&nickname=UserNickname&password=serverPassword
|
||||
]]--
|
||||
|
||||
local function injectCharacterNameForTeamspeak(scheme, connstr)
|
||||
local url, query = strsplit("?", connstr, 2)
|
||||
if query then
|
||||
query = addTS3Nickname(strsplit("&", query))
|
||||
else
|
||||
query = "nickname=" .. UnitName("player")
|
||||
end
|
||||
return scheme .. url .. "?" .. query
|
||||
end
|
||||
|
||||
function mangleLinkForVoiceChat(text)
|
||||
if mod.db.profile.mangleMumble then
|
||||
text = text:gsub("^(mumble://)([^/?]+)", injectCharacterNameForMumble)
|
||||
end
|
||||
if mod.db.profile.mangleTeamspeak then
|
||||
text = text:gsub("^(ts3server://)(.+)", injectCharacterNameForTeamspeak)
|
||||
end
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mod:SetItemRef(link, text, button)
|
||||
if sub(link, 1, 3) == "url" then
|
||||
currentLink = sub(link, 5)
|
||||
currentLink = mangleLinkForVoiceChat(currentLink)
|
||||
|
||||
StaticPopup_Show("ChatterUrlCopyDialog")
|
||||
return
|
||||
end
|
||||
return self.hooks.SetItemRef(link, text, button)
|
||||
end
|
||||
|
||||
function mod:Info()
|
||||
return L["Lets you copy URLs out of chat."]
|
||||
end
|
||||
|
||||
function mod:GetOptions()
|
||||
return options
|
||||
end
|
||||
|
||||
tlds = {
|
||||
ONION = true,
|
||||
-- Copied from http://data.iana.org/TLD/tlds-alpha-by-domain.txt
|
||||
-- Version 2008041301, Last Updated Mon Apr 21 08:07:00 2008 UTC
|
||||
AC = true,
|
||||
AD = true,
|
||||
AE = true,
|
||||
AERO = true,
|
||||
AF = true,
|
||||
AG = true,
|
||||
AI = true,
|
||||
AL = true,
|
||||
AM = true,
|
||||
AN = true,
|
||||
AO = true,
|
||||
AQ = true,
|
||||
AR = true,
|
||||
ARPA = true,
|
||||
AS = true,
|
||||
ASIA = true,
|
||||
AT = true,
|
||||
AU = true,
|
||||
AW = true,
|
||||
AX = true,
|
||||
AZ = true,
|
||||
BA = true,
|
||||
BB = true,
|
||||
BD = true,
|
||||
BE = true,
|
||||
BF = true,
|
||||
BG = true,
|
||||
BH = true,
|
||||
BI = true,
|
||||
BIZ = true,
|
||||
BJ = true,
|
||||
BM = true,
|
||||
BN = true,
|
||||
BO = true,
|
||||
BR = true,
|
||||
BS = true,
|
||||
BT = true,
|
||||
BV = true,
|
||||
BW = true,
|
||||
BY = true,
|
||||
BZ = true,
|
||||
CA = true,
|
||||
CAT = true,
|
||||
CC = true,
|
||||
CD = true,
|
||||
CF = true,
|
||||
CG = true,
|
||||
CH = true,
|
||||
CI = true,
|
||||
CK = true,
|
||||
CL = true,
|
||||
CM = true,
|
||||
CN = true,
|
||||
CO = true,
|
||||
COM = true,
|
||||
COOP = true,
|
||||
CR = true,
|
||||
CU = true,
|
||||
CV = true,
|
||||
CX = true,
|
||||
CY = true,
|
||||
CZ = true,
|
||||
DE = true,
|
||||
DJ = true,
|
||||
DK = true,
|
||||
DM = true,
|
||||
DO = true,
|
||||
DZ = true,
|
||||
EC = true,
|
||||
EDU = true,
|
||||
EE = true,
|
||||
EG = true,
|
||||
ER = true,
|
||||
ES = true,
|
||||
ET = true,
|
||||
EU = true,
|
||||
FI = true,
|
||||
FJ = true,
|
||||
FK = true,
|
||||
FM = true,
|
||||
FO = true,
|
||||
FR = true,
|
||||
GA = true,
|
||||
GB = true,
|
||||
GD = true,
|
||||
GE = true,
|
||||
GF = true,
|
||||
GG = true,
|
||||
GH = true,
|
||||
GI = true,
|
||||
GL = true,
|
||||
GM = true,
|
||||
GN = true,
|
||||
GOV = true,
|
||||
GP = true,
|
||||
GQ = true,
|
||||
GR = true,
|
||||
GS = true,
|
||||
GT = true,
|
||||
GU = true,
|
||||
GW = true,
|
||||
GY = true,
|
||||
HK = true,
|
||||
HM = true,
|
||||
HN = true,
|
||||
HR = true,
|
||||
HT = true,
|
||||
HU = true,
|
||||
ID = true,
|
||||
IE = true,
|
||||
IL = true,
|
||||
IM = true,
|
||||
IN = true,
|
||||
INFO = true,
|
||||
INT = true,
|
||||
IO = true,
|
||||
IQ = true,
|
||||
IR = true,
|
||||
IS = true,
|
||||
IT = true,
|
||||
JE = true,
|
||||
JM = true,
|
||||
JO = true,
|
||||
JOBS = true,
|
||||
JP = true,
|
||||
KE = true,
|
||||
KG = true,
|
||||
KH = true,
|
||||
KI = true,
|
||||
KM = true,
|
||||
KN = true,
|
||||
KP = true,
|
||||
KR = true,
|
||||
KW = true,
|
||||
KY = true,
|
||||
KZ = true,
|
||||
LA = true,
|
||||
LB = true,
|
||||
LC = true,
|
||||
LI = true,
|
||||
LK = true,
|
||||
LR = true,
|
||||
LS = true,
|
||||
LT = true,
|
||||
LU = true,
|
||||
LV = true,
|
||||
LY = true,
|
||||
MA = true,
|
||||
MC = true,
|
||||
MD = true,
|
||||
ME = true,
|
||||
MG = true,
|
||||
MH = true,
|
||||
MIL = true,
|
||||
MK = true,
|
||||
ML = true,
|
||||
MM = true,
|
||||
MN = true,
|
||||
MO = true,
|
||||
MOBI = true,
|
||||
MP = true,
|
||||
MQ = true,
|
||||
MR = true,
|
||||
MS = true,
|
||||
MT = true,
|
||||
MU = true,
|
||||
MUSEUM = true,
|
||||
MV = true,
|
||||
MW = true,
|
||||
MX = true,
|
||||
MY = true,
|
||||
MZ = true,
|
||||
NA = true,
|
||||
NAME = true,
|
||||
NC = true,
|
||||
NE = true,
|
||||
NET = true,
|
||||
NF = true,
|
||||
NG = true,
|
||||
NI = true,
|
||||
NL = true,
|
||||
NO = true,
|
||||
NP = true,
|
||||
NR = true,
|
||||
NU = true,
|
||||
NZ = true,
|
||||
OM = true,
|
||||
ORG = true,
|
||||
PA = true,
|
||||
PE = true,
|
||||
PF = true,
|
||||
PG = true,
|
||||
PH = true,
|
||||
PK = true,
|
||||
PL = true,
|
||||
PM = true,
|
||||
PN = true,
|
||||
PR = true,
|
||||
PRO = true,
|
||||
PS = true,
|
||||
PT = true,
|
||||
PW = true,
|
||||
PY = true,
|
||||
QA = true,
|
||||
RE = true,
|
||||
RO = true,
|
||||
RS = true,
|
||||
RU = true,
|
||||
RW = true,
|
||||
SA = true,
|
||||
SB = true,
|
||||
SC = true,
|
||||
SD = true,
|
||||
SE = true,
|
||||
SG = true,
|
||||
SH = true,
|
||||
SI = true,
|
||||
SJ = true,
|
||||
SK = true,
|
||||
SL = true,
|
||||
SM = true,
|
||||
SN = true,
|
||||
SO = true,
|
||||
SR = true,
|
||||
ST = true,
|
||||
SU = true,
|
||||
SV = true,
|
||||
SY = true,
|
||||
SZ = true,
|
||||
TC = true,
|
||||
TD = true,
|
||||
TEL = true,
|
||||
TF = true,
|
||||
TG = true,
|
||||
TH = true,
|
||||
TJ = true,
|
||||
TK = true,
|
||||
TL = true,
|
||||
TM = true,
|
||||
TN = true,
|
||||
TO = true,
|
||||
TP = true,
|
||||
TR = true,
|
||||
TRAVEL = true,
|
||||
TT = true,
|
||||
TV = true,
|
||||
TW = true,
|
||||
TZ = true,
|
||||
UA = true,
|
||||
UG = true,
|
||||
UK = true,
|
||||
UM = true,
|
||||
US = true,
|
||||
UY = true,
|
||||
UZ = true,
|
||||
VA = true,
|
||||
VC = true,
|
||||
VE = true,
|
||||
VG = true,
|
||||
VI = true,
|
||||
VN = true,
|
||||
VU = true,
|
||||
WF = true,
|
||||
WS = true,
|
||||
YE = true,
|
||||
YT = true,
|
||||
YU = true,
|
||||
ZA = true,
|
||||
ZM = true,
|
||||
ZW = true,
|
||||
}
|
||||
Reference in New Issue
Block a user