Files
moon-well-ui/data/addon/ForeverUI/SocialChat.lua
T
Adrestie 5842eb7a2b ForeverUI : code en anglais, commentaires resserres, code mort retire
Traduction
- Identifiants en anglais dans tout le module : addon, ecrans d'accueil,
  outils Python, banc d'essai et patcheur C#.
- Fichiers au nom francais renommes (Gabarits.lua -> Templates.lua,
  Textes_*.lua -> Texts_*.lua, deployer.py -> deploy.py,
  tools/patcheur -> tools/patcher, etc.).
- Commandes /fui et options de deploy.py en anglais (--check, --server,
  --remove-dbc).
- Cles des variables sauvegardees et de data/dbc/statistics.json
  traduites, sans reprise des anciennes cles.
- API de la micro-barre : ForeverUI.AddMicroButton(def) avec les champs
  name, atlasSet, after, tooltip, onClick, ready, et
  ForeverUI.UpdateMicro(name, isOpen).
- Commentaires reecrits en anglais, courts, sans dates ni historique ;
  les fonctions au nom peu parlant et leurs parametres sont expliques.

Code mort
- Exports, fonctions et variables jamais lus retires.
- Retires a la demande des modules : ForeverUI.PvPJauge, les exports
  FondEntete / TuilerEntete / Polices de TradeSkill, l'art legacy-up-c60,
  honorfill(half)blue et inv_misc_book_09, leurs entrees d'atlas et les
  parties d'outils correspondantes.

Verifications : liaisons des noms comparees avant et apres, banc vert,
chemins de textures inchanges, generateurs reproduisant les fichiers,
patcheur identique octet pour octet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 09:15:52 +02:00

325 lines
11 KiB
Lua

-- ForeverUI: the Chat page of the Social window (client tab 4): chat channels.
-- camelot uses a separate window (blizzard_channels); here channels stay a tab, as in WotLK,
-- after the client's ChannelFrame. Voice chat is left out: the client menu gets no voice
-- fields, so it offers no voice lines.
local ForeverUI = ForeverUI or {}
_G.ForeverUI = ForeverUI
local S = ForeverUI.Social
if not S or not S.registerPage then
return
end
local C = {}
S.Chat = C
local SEP = string.char(92)
local P = {
listW = 172, frameBoxY1 = -60, frameBoxBottom = 32, gap = 4,
rowH = 20, memberH = 15, rosterTitleH = 18,
addW = 80, buttonBottom = 4, buttonRight = -6,
leader = "Interface" .. SEP .. "GroupFrame" .. SEP .. "UI-Group-LeaderIcon",
assistant = "Interface" .. SEP .. "GroupFrame" .. SEP .. "UI-Group-AssistantIcon",
highlight = "Interface" .. SEP .. "QuestFrame" .. SEP .. "UI-QuestTitleHighlight",
plus = "common-button-list-plus", minus = "common-button-list-minus",
plate = "common-button-list-collapseexpand",
}
local txt = S.txt
local function selected()
return GetSelectedDisplayChannel() or 0
end
-- ---------- Channel list
local function createRow(l)
l:RegisterForClicks("LeftButtonUp", "RightButtonUp")
l.plate = ForeverUI.CreateNineSlice(l, P.plate, 12, { 0, 0, 0, 0 }, "BACKGROUND") or {}
l.text = l:CreateFontString(nil, "ARTWORK", "GameFontNormalSmallLeft")
l.text:SetPoint("LEFT", l, "LEFT", 5, 0)
l.text:SetPoint("RIGHT", l, "RIGHT", -20, 0)
l.text:SetHeight(12)
l.sign = l:CreateTexture(nil, "ARTWORK")
l.sign:SetPoint("RIGHT", l, "RIGHT", -6, 0)
l:SetHighlightTexture(P.highlight)
local s = l:GetHighlightTexture()
if s then s:SetBlendMode("ADD") end
l:SetScript("OnClick", function(self, button) C.click(self, button) end)
end
local function populateRow(l, i)
local name, header, collapsed, number, count, active, category = GetChannelDisplayInfo(i)
l.channel, l.header, l.active, l.category = nil, header, active, category
l:UnlockHighlight()
if header then
for _, t in ipairs(l.plate) do t:Show() end
l.text:ClearAllPoints()
l.text:SetPoint("LEFT", l, "LEFT", 5, 0)
l.text:SetPoint("RIGHT", l, "RIGHT", -20, 0)
l.text:SetText((NORMAL_FONT_COLOR_CODE or "|cffffd200") .. (name or "") .. "|r")
if count then
ForeverUI.SetAtlas(l.sign, collapsed and P.plus or P.minus, false)
l.sign:Show()
l:Enable()
else
l.sign:Hide()
l:Disable()
end
else
for _, t in ipairs(l.plate) do t:Hide() end
l.sign:Hide()
l.text:ClearAllPoints()
l.text:SetPoint("LEFT", l, "LEFT", 10, 0)
l.text:SetPoint("RIGHT", l, "RIGHT", -4, 0)
local num = number and (number .. ". ") or ""
if active then
local tail = ""
if category == "CHANNEL_CATEGORY_GROUP" and count then
tail = " (" .. count .. ")"
end
l.text:SetText((HIGHLIGHT_FONT_COLOR_CODE or "|cffffffff") .. num .. (name or "") .. tail .. "|r")
l:Enable()
else
l.text:SetText((GRAY_FONT_COLOR_CODE or "|cff808080") .. num .. (name or "") .. "|r")
l:Disable()
end
l.channel = name
if i == selected() then l:LockHighlight() end
end
end
-- Channel menu, as ChannelList_ShowDropdown. Its fields are set here: the client reads them
-- from its own ChannelButtonN rows.
local function channelMenu(id)
local name, _, _, _, _, active, category = GetChannelDisplayInfo(id)
HideDropDownMenu(1)
local d = ChannelListDropDown
if not d then return end
d.global = (category == "CHANNEL_CATEGORY_WORLD") and 1 or nil
d.group = (category == "CHANNEL_CATEGORY_GROUP") and 1 or nil
d.custom = (category == "CHANNEL_CATEGORY_CUSTOM") and 1 or nil
d.initialize = ChannelListDropDown_Initialize
d.displayMode = "MENU"
d.id = id
d.voice = nil
d.voiceActive = nil
d.active = active
d.channelName = name
ToggleDropDownMenu(1, nil, d, "cursor")
end
-- ChannelList_OnClick
function C.click(l, button)
PlaySound("igMainMenuOptionCheckBoxOn")
if ChannelListDropDown then ChannelListDropDown.clicked = nil end
local id = l.index
if button == "LeftButton" then
HideDropDownMenu(1)
if l.header then
local _, _, collapsed = GetChannelDisplayInfo(id)
if collapsed then ExpandChannelHeader(id) else CollapseChannelHeader(id) end
elseif l.active then
SetSelectedDisplayChannel(id)
C.update()
end
elseif l.channel then
if l.category == "CHANNEL_CATEGORY_WORLD" then
channelMenu(id)
end
if l.active then
GetNumChannelMembers(id)
if ChannelListDropDown then ChannelListDropDown.clicked = id end
if l.category ~= "CHANNEL_CATEGORY_WORLD" then channelMenu(id) end
end
end
end
-- ---------- Members
local function createMember(l)
l:RegisterForClicks("LeftButtonUp", "RightButtonUp")
l.rank = l:CreateTexture(nil, "ARTWORK")
l.rank:SetWidth(12)
l.rank:SetHeight(12)
l.rank:SetPoint("LEFT", l, "LEFT", 2, 1)
l.name = l:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
l.name:SetJustifyH("LEFT")
l.name:SetPoint("LEFT", l, "LEFT", 16, 0)
l.name:SetPoint("RIGHT", l, "RIGHT", -4, 0)
l:SetHighlightTexture(P.highlight)
local s = l:GetHighlightTexture()
if s then s:SetBlendMode("ADD") end
l:SetScript("OnClick", function(self, button)
-- ChannelRoster_OnClick: right click only
if button == "RightButton" and ChannelRosterFrame_ShowDropdown then
ForeverUI.UnitMenu.open(ChannelRosterFrame_ShowDropdown, self.index)
end
end)
end
local function fillMember(l, i)
local name, owner, moderator = GetChannelRosterInfo(selected(), i)
l.name:SetText(name)
if owner then
l.rank:SetTexture(P.leader)
l.rank:Show()
elseif moderator then
l.rank:SetTexture(P.assistant)
l.rank:Show()
else
l.rank:Hide()
end
end
-- ---------- Update
function C.update()
if not C.list then return end
C.list:Update(GetNumDisplayChannels() or 0)
-- ChannelRoster_Update
local id = selected()
local name, _, _, _, count, _, category = GetChannelDisplayInfo(id)
if not count then
C.title:SetText("")
C.members:Update(0)
else
local tail = (category == "CHANNEL_CATEGORY_GROUP") and (" (" .. count .. ")") or ""
C.title:SetText((name or "") .. tail)
C.members:Update(count)
end
end
-- New channel window: our popup holds the fields and buttons of the client dialog
-- (ChannelFrameDaughterFrame). Joining a channel writes DEFAULT_CHAT_FRAME.channelList;
-- written by addon code, that list and every channel message would be tainted. So OK and
-- Enter stay the client's (ChannelFrameDaughterFrame_Okay); fields and buttons are only moved
-- and reskinned, and the dialog shows none of its own art.
local function createNewChannel()
local a = S.createPopup("ForeverUIChannelNewFrame", 230, 170)
a.title:SetText(txt("CHANNEL_NEW_CHANNEL"))
local l1 = a:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
l1:SetPoint("TOPLEFT", a, "TOPLEFT", 22, -36)
l1:SetText(txt("CHANNEL_CHANNEL_NAME"))
local daughter = ChannelFrameDaughterFrame
local name = ChannelFrameDaughterFrameChannelName
local password = ChannelFrameDaughterFrameChannelPassword
local ok = ChannelFrameDaughterFrameOkayButton
local cancel = ChannelFrameDaughterFrameCancelButton
if not (daughter and name and password and ok and cancel) then
return a
end
-- The client dialog: parented to UIParent (the client's ChannelFrame tab is never shown),
-- over our popup, above it, without its art.
daughter:SetParent(UIParent)
daughter:ClearAllPoints()
daughter:SetAllPoints(a)
daughter:SetFrameStrata(a:GetFrameStrata())
daughter:SetFrameLevel(a:GetFrameLevel() + 10)
daughter:EnableMouse(false)
if daughter.SetBackdrop then daughter:SetBackdrop(nil) end
for _, r in ipairs({ daughter:GetRegions() }) do
r:SetAlpha(0)
end
for _, suffix in ipairs({ "VoiceChat", "DetailCloseButton" }) do
ForeverUI.Suppress(_G["ChannelFrameDaughterFrame" .. suffix])
end
-- Its two edit boxes, at the place and size of ours
local function field(b)
b:SetWidth(180)
b:SetHeight(20)
b:SetFontObject(ChatFontNormal or GameFontHighlightSmall)
b:SetTextInsets(6, 6, 0, 0)
S.skinInput(b)
local tag = _G[b:GetName() .. "Label"]
if tag then tag:SetAlpha(0) end
local optional = _G[b:GetName() .. "Optional"]
if optional then optional:SetAlpha(0) end
end
field(name)
name:ClearAllPoints()
name:SetPoint("TOPLEFT", l1, "BOTTOMLEFT", 2, -4)
local l2 = a:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
l2:SetPoint("TOPLEFT", name, "BOTTOMLEFT", -2, -10)
l2:SetText(txt("PASSWORD") .. " |cffffffff" .. txt("OPTIONAL_PARENS") .. "|r")
field(password)
password:ClearAllPoints()
password:SetPoint("TOPLEFT", l2, "BOTTOMLEFT", 2, -4)
-- Its two buttons, at the place and size of ours
for _, b in ipairs({ ok, cancel }) do
b:SetWidth(96)
b:SetHeight(S.G.buttonH)
b:SetNormalFontObject(GameFontNormal)
b:SetHighlightFontObject(GameFontHighlight)
if b.SetDisabledFontObject then b:SetDisabledFontObject(GameFontDisable) end
b:ClearAllPoints()
end
ok:SetPoint("BOTTOMLEFT", a, "BOTTOMLEFT", 12, 12)
cancel:SetPoint("LEFT", ok, "RIGHT", 4, 0)
-- The popup and the dialog open and close together: OK, Enter, Escape and Cancel close the
-- client dialog, our close button the popup.
a:HookScript("OnShow", function()
daughter:Show()
name:SetText("")
password:SetText("")
name:SetFocus()
end)
a:HookScript("OnHide", function() daughter:Hide() end)
daughter:HookScript("OnHide", function() a:Hide() end)
a.name, a.password, a.ok, a.cancel = name, password, ok, cancel
return a
end
-- Builds the Chat page. frame: page frame inside the Social window.
local function build(frame)
local left = ForeverUI.CreateInset(frame, "ForeverUIChannelListInset")
left:SetPoint("TOPLEFT", S.frame, "TOPLEFT", 4, P.frameBoxY1)
left:SetPoint("BOTTOMLEFT", S.frame, "BOTTOMLEFT", 4, P.frameBoxBottom)
left:SetWidth(P.listW)
local right = ForeverUI.CreateInset(frame, "ForeverUIChannelRosterInset")
right:SetPoint("TOPLEFT", left, "TOPRIGHT", P.gap, 0)
right:SetPoint("BOTTOMRIGHT", S.frame, "BOTTOMRIGHT", -6, P.frameBoxBottom)
C.list = S.createList(left, "ForeverUIChannelList", P.rowH, createRow, populateRow)
C.list:SetPoint("TOPLEFT", left, "TOPLEFT", 4, -4)
C.list:SetPoint("BOTTOMRIGHT", left, "BOTTOMRIGHT", -16, 4)
C.title = right:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
C.title:SetPoint("TOPLEFT", right, "TOPLEFT", 8, -6)
C.title:SetPoint("TOPRIGHT", right, "TOPRIGHT", -8, -6)
C.title:SetJustifyH("LEFT")
C.title:SetHeight(13)
C.members = S.createList(right, "ForeverUIChannelRoster", P.memberH, createMember, fillMember)
C.members:SetPoint("TOPLEFT", right, "TOPLEFT", 4, -4 - P.rosterTitleH)
C.members:SetPoint("BOTTOMRIGHT", right, "BOTTOMRIGHT", -16, 4)
C.new = createNewChannel()
C.add = S.button(frame, txt("ADD"), P.addW)
C.add:SetPoint("BOTTOMRIGHT", S.frame, "BOTTOMRIGHT", P.buttonRight, P.buttonBottom)
C.add:SetScript("OnClick", function()
if C.new:IsShown() then C.new:Hide() else C.new:Show() end
end)
end
S.registerPage(4, {
build = build,
title = function() return txt("CHAT_CHANNELS") end,
update = C.update,
hide = function() if C.new then C.new:Hide() end end,
})
local listener = CreateFrame("Frame")
for _, ev in ipairs({ "PLAYER_ENTERING_WORLD", "CHANNEL_UI_UPDATE", "PARTY_MEMBERS_CHANGED",
"PARTY_LEADER_CHANGED", "RAID_ROSTER_UPDATE", "CHANNEL_COUNT_UPDATE", "CHANNEL_ROSTER_UPDATE",
"IGNORELIST_UPDATE", "CHANNEL_FLAGS_UPDATED" }) do
listener:RegisterEvent(ev)
end
listener:SetScript("OnEvent", function()
if C.list and C.list:IsVisible() then C.update() end
end)