Files
moon-well-ui/data/addon/ForeverUI/SocialWho.lua
T

274 lines
11 KiB
Lua

-- ForeverUI : la page "Who" de la fenetre Social (onglet 2 du client).
--
-- La page reprend WotLK (FriendsFrame.lua et .xml du client, WhoList_Update
-- et WhoFrame) -- saisie, totaux, boutons -- habille comme le reste de la
-- fenetre. LA LISTE DES JOUEURS est celle de camelot (2026-09-26, demande de
-- l'utilisateur) : camelot range son "Qui" dans le chercheur de groupe
-- (blizzard_groupfinder_vanillastyle, charge par [Family]\WhoList.xml),
-- LFGWhoListFrame.
--
-- RELEVE camelot (wholist.xml et .lua) :
-- carte LFGWhoListButtonTemplate, 69 de haut, large comme la liste ;
-- fond common-button-list-large, choisie
-- common-button-list-large-selected, survol
-- common-button-list-large-hover en ADD ; pas d'ecart entre les
-- cartes ; pas d'en-tetes de colonnes, pas de tri. Les trois
-- images en NEUF TRANCHES, coins de 9 (mesures sur l'art 169 x 69) :
-- etirees d'un bloc, leurs angles se deformaient (2026-09-26)
-- textes GameFontNormalMed1 (SystemFont_Med2, ombre 1,-1, or) :
-- ligne 1 le nom (10, -6) jusqu'au bord droit ; ligne 2, 6 plus
-- bas, LFG_WHO_LEVEL, la race (+10), la classe (+10, teinte
-- RAID_CLASS_COLORS) en blanc ; ligne 3, 6 plus bas, la colonne
-- variable -- whoSortValue = 1 : la zone -- puis la guilde (+10)
-- en FRIENDS_GRAY_COLOR
-- clics gauche : la selection, un second clic la retire ; droit :
-- FriendsFrame_ShowDropdown(nom, 1)
-- infobulle si le nom, le niveau ou la colonne variable sont coupes : le
-- nom, WHO_LIST_LEVEL_TOOLTIP, la colonne variable
--
-- ECARTS : 3.3.5 n'a ni GameFontNormalMed1 (on en tire une de SystemFont_Med2,
-- qu'il a), ni LFG_WHO_LEVEL / WHO_LIST_LEVEL_TOOLTIP (UNIT_LEVEL_TEMPLATE,
-- "Level %d", dans la langue du client), ni IsTruncated (la largeur du texte
-- comparee a celle du champ). Les lignes 1 a 3 sont posees a hauteur fixe,
-- la classe et la guilde bornees au bord droit a la hauteur de leur ligne.
--
-- RELEVE WotLK (ce qui entoure la liste) :
-- donnees numWhos, totalCount = GetNumWhoResults() ;
-- name, guild, level, race, class, zone, classFileName =
-- GetWhoInfo(i) ; SendWho(texte)
-- totaux format(WHO_FRAME_TOTAL_TEMPLATE, total), suivi de
-- format(WHO_FRAME_SHOWN_TEMPLATE, 50) au-dela de
-- MAX_WHOS_FROM_SERVER
-- saisie Entree : SendWho(texte), puis la saisie perd le focus
-- boutons REFRESH (85) : SendWho(texte), plus de selection ; ADD_FRIEND
-- (120) : AddFriend(nom) ; GROUP_INVITE (120) : InviteUnit(nom) ;
-- les deux derniers eteints sans selection
-- ecran SetWhoToUI(1) a l'affichage de WhoFrame, 0 au masquage : les
-- resultats d'un /who viennent dans la fenetre, pas dans le chat
local ForeverUI = ForeverUI or {}
_G.ForeverUI = ForeverUI
local S = ForeverUI.Social
if not S or not S.inscrirePage then
return
end
local W = {}
S.Who = W
local P = {
encadreX1 = 4, encadreY1 = -60, encadreX2 = -6, encadreY2 = 74,
listeX = 4, listeY = -4, listeX2 = -22, listeX2Seule = -4, listeBas = 4,
carteH = 69, coin = 9, texteH = 13, texteX = 10, texteY = -6, ecartLigne = 6, ecartMot = 10,
fond = "common-button-list-large",
choisie = "common-button-list-large-selected",
survol = "common-button-list-large-hover",
totauxY = 58, saisieY = 30, saisieH = 20, saisieX = 12,
boutonBas = 4, boutonDroite = -6, refreshL = 85, boutonL = 120,
}
local txt = S.txt
local function actif(b, oui)
if b.Activer then b:Activer(oui) elseif oui then b:Enable() else b:Disable() end
end
-- GameFontNormalMed1 de camelot, tiree de SystemFont_Med2
local function police()
if W.police then return W.police end
local f = CreateFont("ForeverUIFontNormalMed1")
f:SetFontObject(SystemFont_Med2)
f:SetShadowOffset(1, -1)
f:SetShadowColor(0, 0, 0)
f:SetTextColor(1, 0.82, 0)
W.police = f
return f
end
-- IsTruncated, que 3.3.5 n'a pas : un champ de largeur fixee trop etroit
local function tronque(fs)
local l = fs:GetWidth()
return l and l > 0 and fs:GetStringWidth() > l + 0.5
end
local function niveauTexte(niveau)
return string.format(txt("UNIT_LEVEL_TEMPLATE"), niveau or 0)
end
function W.maj()
if not W.liste then return end
local nombre, total = GetNumWhoResults()
nombre, total = nombre or 0, total or 0
local shown = ""
if total > (MAX_WHOS_FROM_SERVER or 50) then
shown = string.format(txt("WHO_FRAME_SHOWN_TEMPLATE"), MAX_WHOS_FROM_SERVER or 50)
end
W.totaux:SetText(string.format(txt("WHO_FRAME_TOTAL_TEMPLATE"), total) .. " " .. shown)
if W.choisi and W.choisi > nombre then W.choisi = nil end
W.nomChoisi = W.choisi and GetWhoInfo(W.choisi) or nil
actif(W.ajouter, W.choisi ~= nil)
actif(W.inviter, W.choisi ~= nil)
W.liste:Maj(nombre)
end
-- -------------------------------------------------------------- les cartes
local function montrer(tranches, oui)
for _, t in ipairs(tranches) do
if oui then t:Show() else t:Hide() end
end
end
local function creerCarte(l)
l:RegisterForClicks("LeftButtonUp", "RightButtonUp")
local bords = { 0, 0, 0, 0 }
l.fond = ForeverUI.CreateNineSlice(l, P.fond, P.coin, bords, "BACKGROUND") or {}
l.choisie = ForeverUI.CreateNineSlice(l, P.choisie, P.coin, bords, "BORDER") or {}
montrer(l.choisie, false)
-- le survol : la couche HIGHLIGHT, que le bouton montre sous la souris
l.survol = ForeverUI.CreateNineSlice(l, P.survol, P.coin, bords, "HIGHLIGHT") or {}
for _, t in ipairs(l.survol) do t:SetBlendMode("ADD") end
local blanc = HIGHLIGHT_FONT_COLOR or { r = 1, g = 1, b = 1 }
local gris = FRIENDS_GRAY_COLOR or { r = 0.486, g = 0.518, b = 0.541 }
local function texte(couleur)
local fs = l:CreateFontString(nil, "ARTWORK")
fs:SetFontObject(police())
fs:SetJustifyH("LEFT")
fs:SetHeight(P.texteH)
if couleur then fs:SetTextColor(couleur.r, couleur.g, couleur.b) end
return fs
end
-- les centres des lignes 2 et 3, pour borner la classe et la guilde
local y2 = P.texteY - P.texteH - P.ecartLigne
local y3 = y2 - P.texteH - P.ecartLigne
l.nom = texte()
l.nom:SetPoint("TOPLEFT", l, "TOPLEFT", P.texteX, P.texteY)
l.nom:SetPoint("TOPRIGHT", l, "TOPRIGHT", 0, P.texteY)
l.niveau = texte(blanc)
l.niveau:SetPoint("TOPLEFT", l.nom, "BOTTOMLEFT", 0, -P.ecartLigne)
l.race = texte(blanc)
l.race:SetPoint("LEFT", l.niveau, "RIGHT", P.ecartMot, 0)
l.classe = texte(blanc)
l.classe:SetPoint("LEFT", l.race, "RIGHT", P.ecartMot, 0)
l.classe:SetPoint("RIGHT", l, "TOPRIGHT", 0, y2 - P.texteH / 2)
l.variable = texte(gris)
l.variable:SetPoint("TOPLEFT", l.niveau, "BOTTOMLEFT", 0, -P.ecartLigne)
l.guilde = texte(gris)
l.guilde:SetPoint("LEFT", l.variable, "RIGHT", P.ecartMot, 0)
l.guilde:SetPoint("RIGHT", l, "TOPRIGHT", 0, y3 - P.texteH / 2)
l:SetScript("OnClick", function(self, bouton)
if bouton == "LeftButton" then
if W.choisi == self.index then W.choisi = nil else W.choisi = self.index end
W.maj()
else
FriendsFrame_ShowDropdown(GetWhoInfo(self.index), 1)
end
PlaySound("igMainMenuOptionCheckBoxOn")
end)
l:SetScript("OnEnter", function(self)
if self.bulle then
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
GameTooltip:SetText(self.bulle[1])
GameTooltip:AddLine(self.bulle[2], 1, 1, 1)
GameTooltip:AddLine(self.bulle[3], 1, 1, 1)
GameTooltip:Show()
end
end)
l:SetScript("OnLeave", function() GameTooltip:Hide() end)
end
-- LFGWhoListButtonMixin:InitButton
local function remplirCarte(l, index)
local nom, guilde, niveau, race, classe, zone, fichier = GetWhoInfo(index)
local c = fichier and RAID_CLASS_COLORS and RAID_CLASS_COLORS[fichier] or HIGHLIGHT_FONT_COLOR
l.nom:SetText(nom)
l.niveau:SetText(niveauTexte(niveau))
l.race:SetText(race)
l.classe:SetText(classe)
l.classe:SetTextColor(c.r, c.g, c.b)
l.variable:SetText(zone)
l.guilde:SetText(guilde)
montrer(l.choisie, W.choisi == index)
if tronque(l.variable) or tronque(l.niveau) or tronque(l.nom) then
l.bulle = { nom, niveauTexte(niveau), zone }
else
l.bulle = nil
end
end
local function construire(cadre)
local encadre = ForeverUI.CreateInset(cadre, "ForeverUIWhoInset")
encadre:SetPoint("TOPLEFT", S.cadre, "TOPLEFT", P.encadreX1, P.encadreY1)
encadre:SetPoint("BOTTOMRIGHT", S.cadre, "BOTTOMRIGHT", P.encadreX2, P.encadreY2)
W.liste = S.creerListe(encadre, "ForeverUIWhoList", P.carteH, creerCarte, remplirCarte)
W.liste:SuivreBarre({ "TOPLEFT", encadre, "TOPLEFT", P.listeX, P.listeY },
{ "BOTTOMRIGHT", encadre, "BOTTOMRIGHT", P.listeX2, P.listeBas }, P.listeX2Seule)
W.totaux = cadre:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
W.totaux:SetPoint("BOTTOM", S.cadre, "BOTTOM", 0, P.totauxY)
-- LA SAISIE : le champ de camelot (InputBoxVisualTemplate), comme la
-- recherche du grimoire
local b = CreateFrame("EditBox", "ForeverUIWhoEditBox", cadre)
b:SetAutoFocus(false)
b:SetHeight(P.saisieH)
b:SetPoint("BOTTOMLEFT", S.cadre, "BOTTOMLEFT", P.saisieX, P.saisieY)
b:SetPoint("BOTTOMRIGHT", S.cadre, "BOTTOMRIGHT", -P.saisieX, P.saisieY)
b:SetFontObject(ChatFontNormal or GameFontHighlightSmall)
b:SetTextInsets(6, 6, 0, 0)
local g = b:CreateTexture(nil, "BACKGROUND")
ForeverUI.SetAtlas(g, "common-search-border-left", true)
g:SetWidth(8) g:SetHeight(20)
g:SetPoint("LEFT", b, "LEFT", -5, 0)
local d = b:CreateTexture(nil, "BACKGROUND")
ForeverUI.SetAtlas(d, "common-search-border-right", true)
d:SetWidth(8) d:SetHeight(20)
d:SetPoint("RIGHT", b, "RIGHT", 0, 0)
local m = b:CreateTexture(nil, "BACKGROUND")
ForeverUI.SetAtlas(m, "common-search-border-middle", true)
m:SetHeight(20)
m:SetPoint("LEFT", g, "RIGHT", 0, 0)
m:SetPoint("RIGHT", d, "LEFT", 0, 0)
b:SetScript("OnEnterPressed", function(self)
SendWho(self:GetText())
self:ClearFocus()
end)
b:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
W.saisie = b
W.inviter = S.bouton(cadre, txt("GROUP_INVITE"), P.boutonL)
W.inviter:SetPoint("BOTTOMRIGHT", S.cadre, "BOTTOMRIGHT", P.boutonDroite, P.boutonBas)
W.inviter:SetScript("OnClick", function()
if W.nomChoisi then InviteUnit(W.nomChoisi) end
end)
W.ajouter = S.bouton(cadre, txt("ADD_FRIEND"), P.boutonL)
W.ajouter:SetPoint("RIGHT", W.inviter, "LEFT", 0, 0)
W.ajouter:SetScript("OnClick", function()
if W.nomChoisi then AddFriend(W.nomChoisi) end
end)
W.rafraichir = S.bouton(cadre, txt("REFRESH"), P.refreshL)
W.rafraichir:SetPoint("RIGHT", W.ajouter, "LEFT", 0, 0)
W.rafraichir:SetScript("OnClick", function()
SendWho(W.saisie:GetText())
W.choisi = nil
end)
end
S.inscrirePage(2, {
construire = construire,
titre = function() return txt("WHO_LIST") end,
maj = W.maj,
-- WhoFrame OnShow / OnHide
montrer = function() SetWhoToUI(1) end,
cacher = function() SetWhoToUI(0) end,
})
local veilleur = CreateFrame("Frame")
veilleur:RegisterEvent("WHO_LIST_UPDATE")
veilleur:SetScript("OnEvent", function()
if W.liste and W.liste:IsVisible() then W.maj() end
end)