Files
moon-well-ui/data/addon/ForeverUI/SocialChat.lua
T
Adrestie d110de1cbe Chat et barres d'auras a la DA de camelot ; plus aucune globale du client ecrite par l'addon
- Chat : cadre, barre et bouton de retour, colonne, bouton d'amis de camelot ;
  au repos fond, onglets, colonne et saisie s'effacent, allumage au survol
- Barres d'ameliorations et d'affaiblissements (Buffs.lua) : grille, bordures
  par type, clignotement, repli, regroupement, enchantements d'arme
- Souillure : StaticPopupDialogs n'est plus reaffectee (BindEnchant bloque) ;
  menus deroulants, suivi des objectifs, choix d'icone, ajout de canal et
  carte du monde n'ecrivent plus les globales du client ; menus d'unite :
  lignes protegees servies par des boutons securises hors combat, grisees en
  combat ; seule MAP_QUEST_DIFFICULTY reste, par decision
- Gestionnaire d'ensembles : plus d'appel GetEquipmentSetIconInfo(nil)
- Banc : garde des globales ecrites (bytecode Lua 5.1), faux client durci

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:36:19 +02:00

358 lines
13 KiB
Lua

-- ForeverUI : la page "Chat" de la fenetre Social (onglet 4 du client) --
-- les canaux de discussion.
--
-- camelot met ses canaux dans une fenetre a part (blizzard_channels) ; la
-- decision de l'utilisateur (2026-09-26) les garde en onglet, comme WotLK.
-- La page reprend donc ChannelFrame (ChannelFrame.lua et .xml du client),
-- habillee comme le reste de la fenetre.
--
-- RELEVE WotLK :
-- liste GetNumDisplayChannels ; name, header, collapsed, channelNumber,
-- count, active, category = GetChannelDisplayInfo(i). En-tete : nom dore, "+" replie / "-"
-- deplie, cliquable seulement s'il a un compte. Canal actif :
-- "N. nom" en blanc, "(count)" en plus pour la categorie GROUP ;
-- inactif : en gris, et desactive. 20 lignes de 20.
-- clics en-tete : ExpandChannelHeader / CollapseChannelHeader ; canal
-- actif : SetSelectedDisplayChannel et la liste des membres ;
-- droit : le menu ChannelListDropDown (mot de passe, inviter,
-- rejoindre, quitter)
-- membres name, owner, moderator = GetChannelRosterInfo(canal, i) ; icone de chef
-- (UI-Group-LeaderIcon) pour le proprietaire, d'assistant
-- (UI-Group-AssistantIcon) pour un moderateur ; lignes de 15 ;
-- le titre : le nom du canal, et "(count)" pour GROUP ; clic
-- droit : ChannelRosterFrame_ShowDropdown (UnitPopup CHAT_ROSTER)
-- nouveau ADD (80) : nom (31 lettres) et mot de passe facultatif ;
-- JoinPermanentChannel(nom, mdp, DEFAULT_CHAT_FRAME:GetID(), 1),
-- CHAT_INVALID_NAME_NOTICE sinon, puis le canal inscrit dans la
-- liste du cadre de discussion (ChannelFrameDaughterFrame_Okay)
--
-- RETIRE (2026-09-26, demande de l'utilisateur) : tout ce qui touche au chat
-- vocal -- les cases d'adhesion automatique, les haut-parleurs des canaux et
-- des membres, le glisser vers la fenetre detachee du roster vocal. Le menu du
-- client ne recoit plus les champs de voix : il n'en propose plus les lignes.
local ForeverUI = ForeverUI or {}
_G.ForeverUI = ForeverUI
local S = ForeverUI.Social
if not S or not S.inscrirePage then
return
end
local C = {}
S.Chat = C
local SEP = string.char(92)
local P = {
listeL = 172, encadreY1 = -60, encadreBas = 32, ecart = 4,
ligneH = 20, membreH = 15, titreRosterH = 18,
ajouterL = 80, boutonBas = 4, boutonDroite = -6,
chef = "Interface" .. SEP .. "GroupFrame" .. SEP .. "UI-Group-LeaderIcon",
assistant = "Interface" .. SEP .. "GroupFrame" .. SEP .. "UI-Group-AssistantIcon",
surbrillance = "Interface" .. SEP .. "QuestFrame" .. SEP .. "UI-QuestTitleHighlight",
plus = "common-button-list-plus", moins = "common-button-list-minus",
plaque = "common-button-list-collapseexpand",
}
local txt = S.txt
local function choisi()
return GetSelectedDisplayChannel() or 0
end
-- ---------------------------------------------------------------- la liste
local function creerLigne(l)
l:RegisterForClicks("LeftButtonUp", "RightButtonUp")
l.plaque = ForeverUI.CreateNineSlice(l, P.plaque, 12, { 0, 0, 0, 0 }, "BACKGROUND") or {}
l.texte = l:CreateFontString(nil, "ARTWORK", "GameFontNormalSmallLeft")
l.texte:SetPoint("LEFT", l, "LEFT", 5, 0)
l.texte:SetPoint("RIGHT", l, "RIGHT", -20, 0)
l.texte:SetHeight(12)
l.signe = l:CreateTexture(nil, "ARTWORK")
l.signe:SetPoint("RIGHT", l, "RIGHT", -6, 0)
l:SetHighlightTexture(P.surbrillance)
local s = l:GetHighlightTexture()
if s then s:SetBlendMode("ADD") end
l:SetScript("OnClick", function(self, bouton) C.cliquer(self, bouton) end)
end
local function remplirLigne(l, i)
local nom, entete, replie, numero, compte, actif, categorie = GetChannelDisplayInfo(i)
l.canal, l.entete, l.actif, l.categorie = nil, entete, actif, categorie
l:UnlockHighlight()
if entete then
for _, t in ipairs(l.plaque) do t:Show() end
l.texte:ClearAllPoints()
l.texte:SetPoint("LEFT", l, "LEFT", 5, 0)
l.texte:SetPoint("RIGHT", l, "RIGHT", -20, 0)
l.texte:SetText((NORMAL_FONT_COLOR_CODE or "|cffffd200") .. (nom or "") .. "|r")
if compte then
ForeverUI.SetAtlas(l.signe, replie and P.plus or P.moins, false)
l.signe:Show()
l:Enable()
else
l.signe:Hide()
l:Disable()
end
else
for _, t in ipairs(l.plaque) do t:Hide() end
l.signe:Hide()
l.texte:ClearAllPoints()
l.texte:SetPoint("LEFT", l, "LEFT", 10, 0)
l.texte:SetPoint("RIGHT", l, "RIGHT", -4, 0)
local num = numero and (numero .. ". ") or ""
if actif then
local suite = ""
if categorie == "CHANNEL_CATEGORY_GROUP" and compte then
suite = " (" .. compte .. ")"
end
l.texte:SetText((HIGHLIGHT_FONT_COLOR_CODE or "|cffffffff") .. num .. (nom or "") .. suite .. "|r")
l:Enable()
else
l.texte:SetText((GRAY_FONT_COLOR_CODE or "|cff808080") .. num .. (nom or "") .. "|r")
l:Disable()
end
l.canal = nom
if i == choisi() then l:LockHighlight() end
end
end
-- LE MENU D'UN CANAL : ChannelList_ShowDropdown, dont on pose nous-memes les
-- champs -- le client les lit sur ses propres lignes ChannelButtonN.
local function menuCanal(id)
local nom, _, _, _, _, actif, categorie = GetChannelDisplayInfo(id)
HideDropDownMenu(1)
local d = ChannelListDropDown
if not d then return end
d.global = (categorie == "CHANNEL_CATEGORY_WORLD") and 1 or nil
d.group = (categorie == "CHANNEL_CATEGORY_GROUP") and 1 or nil
d.custom = (categorie == "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 = actif
d.channelName = nom
ToggleDropDownMenu(1, nil, d, "cursor")
end
-- ChannelList_OnClick
function C.cliquer(l, bouton)
PlaySound("igMainMenuOptionCheckBoxOn")
if ChannelListDropDown then ChannelListDropDown.clicked = nil end
local id = l.index
if bouton == "LeftButton" then
HideDropDownMenu(1)
if l.entete then
local _, _, replie = GetChannelDisplayInfo(id)
if replie then ExpandChannelHeader(id) else CollapseChannelHeader(id) end
elseif l.actif then
SetSelectedDisplayChannel(id)
C.maj()
end
elseif l.canal then
if l.categorie == "CHANNEL_CATEGORY_WORLD" then
menuCanal(id)
end
if l.actif then
GetNumChannelMembers(id)
if ChannelListDropDown then ChannelListDropDown.clicked = id end
if l.categorie ~= "CHANNEL_CATEGORY_WORLD" then menuCanal(id) end
end
end
end
-- -------------------------------------------------------------- les membres
local function creerMembre(l)
l:RegisterForClicks("LeftButtonUp", "RightButtonUp")
l.rang = l:CreateTexture(nil, "ARTWORK")
l.rang:SetWidth(12)
l.rang:SetHeight(12)
l.rang:SetPoint("LEFT", l, "LEFT", 2, 1)
l.nom = l:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
l.nom:SetJustifyH("LEFT")
l.nom:SetPoint("LEFT", l, "LEFT", 16, 0)
l.nom:SetPoint("RIGHT", l, "RIGHT", -4, 0)
l:SetHighlightTexture(P.surbrillance)
local s = l:GetHighlightTexture()
if s then s:SetBlendMode("ADD") end
l:SetScript("OnClick", function(self, bouton)
-- ChannelRoster_OnClick : le clic droit seulement
if bouton == "RightButton" and ChannelRosterFrame_ShowDropdown then
ForeverUI.MenuUnite.ouvrir(ChannelRosterFrame_ShowDropdown, self.index)
end
end)
end
local function remplirMembre(l, i)
local nom, proprietaire, moderateur = GetChannelRosterInfo(choisi(), i)
l.nom:SetText(nom)
if proprietaire then
l.rang:SetTexture(P.chef)
l.rang:Show()
elseif moderateur then
l.rang:SetTexture(P.assistant)
l.rang:Show()
else
l.rang:Hide()
end
end
-- ------------------------------------------------------------ la mise a jour
function C.maj()
if not C.liste then return end
C.liste:Maj(GetNumDisplayChannels() or 0)
-- ChannelRoster_Update
local id = choisi()
local nom, _, _, _, compte, _, categorie = GetChannelDisplayInfo(id)
if not compte then
C.titre:SetText("")
C.membres:Maj(0)
else
local suite = (categorie == "CHANNEL_CATEGORY_GROUP") and (" (" .. compte .. ")") or ""
C.titre:SetText((nom or "") .. suite)
C.membres:Maj(compte)
end
end
-- LA FENETRE "NOUVEAU CANAL" : notre annexe, et DEDANS les champs et les
-- boutons de la boite du client (ChannelFrameDaughterFrame). Rejoindre un
-- canal l'inscrit dans la liste du cadre de discussion
-- (DEFAULT_CHAT_FRAME.channelList) : ecrite par l'addon, cette liste
-- passerait a l'addon, et avec elle chaque message de canal que le client
-- traite (2026-09-26, le code doit etre propre). Le clic sur OK et la touche
-- Entree sont donc ceux du client -- ChannelFrameDaughterFrame_Okay, son code
-- a lui. Ses champs et ses boutons restent les enfants de sa boite ; ils
-- sont seulement poses dans notre annexe et habilles comme les notres. Sa
-- boite ne montre plus rien d'elle-meme : ni son fond, ni son titre, ni sa
-- croix, ni sa case de chat vocal.
local function creerNouveau()
local a = S.creerAnnexe("ForeverUIChannelNewFrame", 230, 170)
a.titre: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 fille = ChannelFrameDaughterFrame
local nom = ChannelFrameDaughterFrameChannelName
local mdp = ChannelFrameDaughterFrameChannelPassword
local ok = ChannelFrameDaughterFrameOkayButton
local annuler = ChannelFrameDaughterFrameCancelButton
if not (fille and nom and mdp and ok and annuler) then
return a
end
-- la boite du client : sous UIParent (ChannelFrame, l'onglet du client,
-- n'est pas montre), sur notre annexe, au-dessus d'elle, sans son art
fille:SetParent(UIParent)
fille:ClearAllPoints()
fille:SetAllPoints(a)
fille:SetFrameStrata(a:GetFrameStrata())
fille:SetFrameLevel(a:GetFrameLevel() + 10)
fille:EnableMouse(false)
if fille.SetBackdrop then fille:SetBackdrop(nil) end
for _, r in ipairs({ fille:GetRegions() }) do
r:SetAlpha(0)
end
for _, suffixe in ipairs({ "VoiceChat", "DetailCloseButton" }) do
ForeverUI.Suppress(_G["ChannelFrameDaughterFrame" .. suffixe])
end
-- ses deux champs, a la place et a la taille des notres
local function champ(b)
b:SetWidth(180)
b:SetHeight(20)
b:SetFontObject(ChatFontNormal or GameFontHighlightSmall)
b:SetTextInsets(6, 6, 0, 0)
S.habillerSaisie(b)
local etiquette = _G[b:GetName() .. "Label"]
if etiquette then etiquette:SetAlpha(0) end
local facultatif = _G[b:GetName() .. "Optional"]
if facultatif then facultatif:SetAlpha(0) end
end
champ(nom)
nom:ClearAllPoints()
nom:SetPoint("TOPLEFT", l1, "BOTTOMLEFT", 2, -4)
local l2 = a:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
l2:SetPoint("TOPLEFT", nom, "BOTTOMLEFT", -2, -10)
l2:SetText(txt("PASSWORD") .. " |cffffffff" .. txt("OPTIONAL_PARENS") .. "|r")
champ(mdp)
mdp:ClearAllPoints()
mdp:SetPoint("TOPLEFT", l2, "BOTTOMLEFT", 2, -4)
-- ses deux boutons, a la place et a la taille des notres
for _, b in ipairs({ ok, annuler }) do
b:SetWidth(96)
b:SetHeight(S.G.boutonH)
b:SetNormalFontObject(GameFontNormal)
b:SetHighlightFontObject(GameFontHighlight)
if b.SetDisabledFontObject then b:SetDisabledFontObject(GameFontDisable) end
b:ClearAllPoints()
end
ok:SetPoint("BOTTOMLEFT", a, "BOTTOMLEFT", 12, 12)
annuler:SetPoint("LEFT", ok, "RIGHT", 4, 0)
-- l'annexe et la boite s'ouvrent et se ferment ensemble : OK, Entree,
-- Echap et Annuler ferment la boite du client, notre croix l'annexe
a:HookScript("OnShow", function()
fille:Show()
nom:SetText("")
mdp:SetText("")
nom:SetFocus()
end)
a:HookScript("OnHide", function() fille:Hide() end)
fille:HookScript("OnHide", function() a:Hide() end)
a.nom, a.mdp, a.ok, a.annuler = nom, mdp, ok, annuler
return a
end
local function construire(cadre)
local gauche = ForeverUI.CreateInset(cadre, "ForeverUIChannelListInset")
gauche:SetPoint("TOPLEFT", S.cadre, "TOPLEFT", 4, P.encadreY1)
gauche:SetPoint("BOTTOMLEFT", S.cadre, "BOTTOMLEFT", 4, P.encadreBas)
gauche:SetWidth(P.listeL)
local droite = ForeverUI.CreateInset(cadre, "ForeverUIChannelRosterInset")
droite:SetPoint("TOPLEFT", gauche, "TOPRIGHT", P.ecart, 0)
droite:SetPoint("BOTTOMRIGHT", S.cadre, "BOTTOMRIGHT", -6, P.encadreBas)
C.liste = S.creerListe(gauche, "ForeverUIChannelList", P.ligneH, creerLigne, remplirLigne)
C.liste:SetPoint("TOPLEFT", gauche, "TOPLEFT", 4, -4)
C.liste:SetPoint("BOTTOMRIGHT", gauche, "BOTTOMRIGHT", -16, 4)
C.titre = droite:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
C.titre:SetPoint("TOPLEFT", droite, "TOPLEFT", 8, -6)
C.titre:SetPoint("TOPRIGHT", droite, "TOPRIGHT", -8, -6)
C.titre:SetJustifyH("LEFT")
C.titre:SetHeight(13)
C.membres = S.creerListe(droite, "ForeverUIChannelRoster", P.membreH, creerMembre, remplirMembre)
C.membres:SetPoint("TOPLEFT", droite, "TOPLEFT", 4, -4 - P.titreRosterH)
C.membres:SetPoint("BOTTOMRIGHT", droite, "BOTTOMRIGHT", -16, 4)
C.nouveau = creerNouveau()
C.ajouter = S.bouton(cadre, txt("ADD"), P.ajouterL)
C.ajouter:SetPoint("BOTTOMRIGHT", S.cadre, "BOTTOMRIGHT", P.boutonDroite, P.boutonBas)
C.ajouter:SetScript("OnClick", function()
if C.nouveau:IsShown() then C.nouveau:Hide() else C.nouveau:Show() end
end)
end
S.inscrirePage(4, {
construire = construire,
titre = function() return txt("CHAT_CHANNELS") end,
maj = C.maj,
cacher = function() if C.nouveau then C.nouveau:Hide() end end,
})
local veilleur = 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
veilleur:RegisterEvent(ev)
end
veilleur:SetScript("OnEvent", function()
if C.liste and C.liste:IsVisible() then C.maj() end
end)