Files
benilla-octo/crates/benilla-app/assets/ui/FriendsFrame.xml
T
SamandClaude Fable 5 a683d5524f the interface code is ours: the transcription debt is paid
- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that
- the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down
- a lost session ends at the login screen instead of silently re-authenticating and stealing the account back
- a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 19:21:03 +07:00

1183 lines
69 KiB
XML

<Ui xmlns="http://www.blizzard.com/wow/ui/">
<!--
The social window (decision 0668) — our FriendsFrame. The patch-chain FrameXML (mpqx
extraction, decision 0246) is the SPECIFICATION: `FriendsFrame.lua` (987 lines) and
`FriendsFrame.xml` (the FriendsListFrame / IgnoreListFrame / WhoFrame subtrees) fix the
global names addons bind to, the geometry, the row counts and the art paths, and the
strings are GlobalStrings' own. The code answering to all that is ours.
Shape: ONE window with a tab strip, and inside tab 1 a second Friends/Ignore toggle-tab
pair — the ref's own two-level arrangement, not a simplification. `FriendsFrame.selectedTab`
picks the sub-frame; `FriendsFrame.showFriendsList` picks between the two tab-1 lists.
Every list is a FAUX scroll: 10/20/17 fixed row buttons repainted from an offset, never a
row per friend. Row heights come from the ref's own constants (34/16/16 — note the friend
row's *button* is 31 tall while the scroll step is 34; both are the ref's).
SCOPE (stated, not hidden):
· Tab 3 GUILD is present but DISABLED — which is exactly what a character in no guild
sees in the reference (`InGuildCheck` → PanelTemplates_DisableTab). benilla has no
guild arc yet (decision 0434 §1 keeps it separate), so it is permanently that.
· Tab 4 RAID is NOT built. The ref's RaidFrame is the party/raid management pane, and
decision 0434 §6 defers the raid UI wholesale; an empty fourth panel would read as a
bug, so the tab is absent until that arc lands.
· The row right-click menu IS the shared UnitPopup "FRIEND" menu, addressed by name
(see `BenillaFriendsFrame_ShowDropdown`). Its TARGET/GUILD_* rows stay hidden by
UnitPopup's own deferred set, so what opens is Whisper / Invite / Cancel.
-->
<Script><![CDATA[
-- ── Strings (GlobalStrings.lua, verbatim) ───────────────────────────────────────────────
FRIENDS_LIST = "Friends List" -- l.1991
IGNORE_LIST = "Ignore List" -- l.2306
WHO_LIST = "Who List" -- l.5440
FRIENDS_LIST_TEMPLATE = "%s |cffffffff- %s|r %s" -- l.1993
FRIENDS_LIST_OFFLINE_TEMPLATE = "|cff999999%s - Offline|r" -- l.1992
FRIENDS_LEVEL_TEMPLATE = "Level %d %s" -- l.1990
WHO_FRAME_TOTAL_TEMPLATE = "%d Person Found" -- l.5438
WHO_FRAME_TOTAL_TEMPLATE_P1 = "%d People Found" -- l.5439
WHO_FRAME_SHOWN_TEMPLATE = "(%d displayed)" -- l.5437
WHO_TAG_ZONE = "z-" -- l.5449
ADD_FRIEND = "Add Friend" -- l.34
ADD_FRIEND_LABEL = "Enter name of friend to add:" -- l.35
REMOVE_FRIEND = "Remove Friend" -- l.3315
SEND_MESSAGE = "Send Message" -- l.3414
GROUP_INVITE = "Group Invite" -- l.2031
IGNORE_PLAYER = "Ignore Player" -- l.2307
ADD_IGNORE_LABEL = ADD_IGNORE_LABEL or "Enter name of player to ignore:"
STOP_IGNORE = "Remove Player" -- l.4202
UNKNOWN = "Unknown" -- l.4443
-- The ref's own display constants (FriendsFrame.lua l.1-10).
FRIENDS_TO_DISPLAY = 10
FRIENDS_FRAME_FRIEND_HEIGHT = 34
IGNORES_TO_DISPLAY = 20
FRIENDS_FRAME_IGNORE_HEIGHT = 16
WHOS_TO_DISPLAY = 17
FRIENDS_FRAME_WHO_HEIGHT = 16
MAX_WHOS_FROM_SERVER = 50
-- The who list's variable column (l.18-22): the dropdown picks which of the three the
-- middle column shows, and its `sortType` is what the header sort sends.
WHOFRAME_DROPDOWN_LIST = {
{ name = "Zone", sortType = "zone" },
{ name = "Guild", sortType = "guild" },
{ name = "Race", sortType = "race" },
}
BENILLA_FRIENDS_SUBFRAMES = {
"FriendsListFrame", "IgnoreListFrame", "WhoFrame",
}
-- Six of this window's buttons are live only while a row of the right kind is selected,
-- and each list re-decides all of its own on every repaint. One call per button, taking
-- the condition, keeps that decision readable as the one-liner it actually is.
local function set_enabled(button, on)
if on then
button:Enable()
else
button:Disable()
end
end
-- ── Sub-frame switching (ref FriendsFrame_ShowSubFrame l.25-33) ────────────────────────
function FriendsFrame_ShowSubFrame(frameName)
for i = 1, table.getn(BENILLA_FRIENDS_SUBFRAMES) do
local value = BENILLA_FRIENDS_SUBFRAMES[i]
if value == frameName then
getglobal(value):Show()
else
getglobal(value):Hide()
end
end
end
-- ── The row right-click menu (ref FriendsFrame_ShowDropdown l.35-47) ───────────────────
-- A row's right-click opens the shared UnitPopup "FRIEND" menu addressed by NAME rather
-- than by a unit token — which is the whole reason that menu exists: a friend or a /who
-- hit is a name with no unit behind it (they need not even be in the world). The kit
-- already supports that shape (`UnitPopup_ShowMenu(menu, which, unit, name)`), and its
-- WHISPER/INVITE rows fall back to the by-name calls when `unit` is nil.
--
-- `connected` gates the whole menu, ref-verbatim: there is nothing to offer an offline
-- player. A /who hit is by definition online, so that call passes 1.
function BenillaFriendsFrame_ShowDropdown(name, connected)
HideDropDownMenu(1)
if not connected or not name or name == "" then
return
end
BenillaFriendsDropDown.initialize = BenillaFriendsFrameDropDown_Initialize
BenillaFriendsDropDown.displayMode = "MENU"
BenillaFriendsDropDown.name = name
ToggleDropDownMenu(1, nil, BenillaFriendsDropDown, "cursor")
end
function BenillaFriendsFrameDropDown_Initialize()
UnitPopup_ShowMenu(getglobal(UIDROPDOWNMENU_OPEN_MENU), "FRIEND", nil,
BenillaFriendsDropDown.name)
end
-- ── The window's repaint (ref FriendsFrame_Update l.81-126) ────────────────────────────
-- Each tab swaps the four corner art textures as well as the sub-frame: the ref reuses one
-- 384x512 window shell for lists that want different bottom art.
function FriendsFrame_Update()
local frame = FriendsFrame
if frame.selectedTab == 1 then
FriendsFrameTopLeft:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-General-TopLeft")
FriendsFrameTopRight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-General-TopRight")
if frame.showFriendsList then
FriendsFrameBottomLeft:SetTexture("Interface\\FriendsFrame\\UI-FriendsFrame-BotLeft")
FriendsFrameBottomRight:SetTexture("Interface\\FriendsFrame\\UI-FriendsFrame-BotRight")
FriendsFrameTitleText:SetText(FRIENDS_LIST)
FriendsList_Update()
FriendsFrame_ShowSubFrame("FriendsListFrame")
else
FriendsFrameBottomLeft:SetTexture("Interface\\FriendsFrame\\UI-IgnoreFrame-BotLeft")
FriendsFrameBottomRight:SetTexture("Interface\\FriendsFrame\\UI-IgnoreFrame-BotRight")
FriendsFrameTitleText:SetText(IGNORE_LIST)
IgnoreList_Update()
FriendsFrame_ShowSubFrame("IgnoreListFrame")
end
elseif frame.selectedTab == 2 then
FriendsFrameTopLeft:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopLeft")
FriendsFrameTopRight:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopRight")
FriendsFrameBottomLeft:SetTexture("Interface\\FriendsFrame\\WhoFrame-BotLeft")
FriendsFrameBottomRight:SetTexture("Interface\\FriendsFrame\\WhoFrame-BotRight")
FriendsFrameTitleText:SetText(WHO_LIST)
WhoList_Update()
FriendsFrame_ShowSubFrame("WhoFrame")
end
end
-- ── The friends list (ref FriendsList_Update l.142-210) ────────────────────────────────
function FriendsList_Update()
local frame = FriendsFrame
local numFriends = GetNumFriends()
frame.selectedFriend = GetSelectedFriend()
-- A non-empty list always has a selection; the first row stands in if nothing else
-- does (spec: ref l.154-158).
local anyFriends = numFriends > 0
if anyFriends and frame.selectedFriend == 0 then
SetSelectedFriend(1)
frame.selectedFriend = GetSelectedFriend()
end
-- The three action buttons follow the SELECTED friend, not the list — and only two of
-- them need that friend to be online: you can drop someone from the list whether or
-- not they are logged in, but there is nobody there to whisper or invite (ref
-- l.159-172).
local online = anyFriends and select(5, GetFriendInfo(frame.selectedFriend))
set_enabled(FriendsFrameSendMessageButton, online)
set_enabled(FriendsFrameGroupInviteButton, online)
set_enabled(FriendsFrameRemoveFriendButton, anyFriends)
local offset = FauxScrollFrame_GetOffset(FriendsFrameFriendsScrollFrame)
for i = 1, FRIENDS_TO_DISPLAY do
local index = offset + i
local name, level, class, area, connected, status = GetFriendInfo(index)
local nameLocation = getglobal("FriendsFrameFriendButton" .. i .. "NameLocation")
local info = getglobal("FriendsFrameFriendButton" .. i .. "Info")
if not name or name == "" then
name = UNKNOWN
end
if connected then
nameLocation:SetText(format(FRIENDS_LIST_TEMPLATE, name, area, status or ""))
info:SetText(format(FRIENDS_LEVEL_TEMPLATE, level, class))
else
nameLocation:SetText(format(FRIENDS_LIST_OFFLINE_TEMPLATE, name))
info:SetText(UNKNOWN)
end
local button = getglobal("FriendsFrameFriendButton" .. i)
button:SetID(index)
if index == frame.selectedFriend then
button:LockHighlight()
else
button:UnlockHighlight()
end
if index > numFriends then
button:Hide()
else
button:Show()
end
end
FauxScrollFrame_Update(FriendsFrameFriendsScrollFrame, numFriends,
FRIENDS_TO_DISPLAY, FRIENDS_FRAME_FRIEND_HEIGHT)
end
-- ── The ignore list (ref IgnoreList_Update l.212-251) ──────────────────────────────────
function IgnoreList_Update()
local frame = FriendsFrame
local numIgnores = GetNumIgnores()
frame.selectedIgnore = GetSelectedIgnore()
local anyIgnores = numIgnores > 0
if anyIgnores and frame.selectedIgnore == 0 then
SetSelectedIgnore(1)
frame.selectedIgnore = GetSelectedIgnore()
end
set_enabled(FriendsFrameStopIgnoreButton, anyIgnores)
local offset = FauxScrollFrame_GetOffset(FriendsFrameIgnoreScrollFrame)
for i = 1, IGNORES_TO_DISPLAY do
local index = offset + i
getglobal("FriendsFrameIgnoreButton" .. i .. "Name")
:SetText(GetIgnoreName(index) or "")
local button = getglobal("FriendsFrameIgnoreButton" .. i)
button:SetID(index)
if index == frame.selectedIgnore then
button:LockHighlight()
else
button:UnlockHighlight()
end
if index > numIgnores then
button:Hide()
else
button:Show()
end
end
FauxScrollFrame_Update(FriendsFrameIgnoreScrollFrame, numIgnores,
IGNORES_TO_DISPLAY, FRIENDS_FRAME_IGNORE_HEIGHT)
end
-- ── The who list (ref WhoList_Update l.253-325) ────────────────────────────────────────
function WhoList_Update()
local numWhos, totalCount = GetNumWhoResults()
local frame = WhoFrame
-- "132 People Found (50 displayed)" — the suffix appears only when the server
-- matched more than it could send (ref l.264-268).
local displayedText = ""
if totalCount > MAX_WHOS_FROM_SERVER then
displayedText = format(WHO_FRAME_SHOWN_TEMPLATE, MAX_WHOS_FROM_SERVER)
end
local totalTemplate = WHO_FRAME_TOTAL_TEMPLATE_P1
if totalCount == 1 then
totalTemplate = WHO_FRAME_TOTAL_TEMPLATE
end
WhoFrameTotals:SetText(format(totalTemplate, totalCount) .. " " .. displayedText)
local showScrollBar = nil
if numWhos > WHOS_TO_DISPLAY then
showScrollBar = 1
end
local column = UIDropDownMenu_GetSelectedID(WhoFrameDropDown) or 1
local offset = FauxScrollFrame_GetOffset(WhoListScrollFrame)
for i = 1, WHOS_TO_DISPLAY do
local index = offset + i
local button = getglobal("WhoFrameButton" .. i)
button.whoIndex = index
local name, guild, level, race, class, zone = GetWhoInfo(index)
getglobal("WhoFrameButton" .. i .. "Name"):SetText(name or "")
getglobal("WhoFrameButton" .. i .. "Level"):SetText(level or "")
getglobal("WhoFrameButton" .. i .. "Class"):SetText(class or "")
-- The variable column follows the dropdown: zone / guild / race (ref l.274-279).
local columnTable = { zone, guild, race }
local variable = getglobal("WhoFrameButton" .. i .. "Variable")
variable:SetText(columnTable[column] or "")
if showScrollBar then
variable:SetWidth(95)
else
variable:SetWidth(110)
end
if frame.selectedWho == index then
button:LockHighlight()
else
button:UnlockHighlight()
end
if index > numWhos then
button:Hide()
else
button:Show()
end
end
-- The two who buttons need a selected row, and both act by NAME — so the selection is
-- resolved to one here and the buttons read it back (ref l.302-309).
set_enabled(WhoFrameGroupInviteButton, frame.selectedWho)
set_enabled(WhoFrameAddFriendButton, frame.selectedWho)
if frame.selectedWho then
frame.selectedName = GetWhoInfo(frame.selectedWho)
end
-- The middle column and the dropdown narrow to make room for the bar (ref l.311-318).
if showScrollBar then
WhoFrameColumn_SetWidth(105, WhoFrameColumnHeader2)
UIDropDownMenu_SetWidth(80, WhoFrameDropDown)
else
WhoFrameColumn_SetWidth(120, WhoFrameColumnHeader2)
UIDropDownMenu_SetWidth(95, WhoFrameDropDown)
end
FauxScrollFrame_Update(WhoListScrollFrame, numWhos, WHOS_TO_DISPLAY,
FRIENDS_FRAME_WHO_HEIGHT)
end
-- Ref WhoFrameColumn_SetWidth l.605-611: the header's middle slice carries the width less
-- the two 9px end caps.
function WhoFrameColumn_SetWidth(width, frame)
frame:SetWidth(width)
getglobal(frame:GetName() .. "Middle"):SetWidth(width - 9)
end
-- ── The who column dropdown (ref WhoFrameDropDown_* l.613-633) ─────────────────────────
function WhoFrameDropDown_Initialize()
for i = 1, table.getn(WHOFRAME_DROPDOWN_LIST) do
local info = {}
info.text = WHOFRAME_DROPDOWN_LIST[i].name
info.func = WhoFrameDropDownButton_OnClick
UIDropDownMenu_AddButton(info)
end
end
function WhoFrameDropDown_OnLoad()
UIDropDownMenu_Initialize(this, WhoFrameDropDown_Initialize)
UIDropDownMenu_SetWidth(80, this)
UIDropDownMenu_SetButtonWidth(24, this)
UIDropDownMenu_JustifyText("LEFT", this)
end
function WhoFrameDropDownButton_OnClick()
UIDropDownMenu_SetSelectedID(WhoFrameDropDown, this:GetID())
-- The ref sorts on the dropdown's OnMouseUp; doing it on the pick is the same intent
-- with one fewer hook, and keeps the column and its sort in step.
local entry = WHOFRAME_DROPDOWN_LIST[this:GetID()]
if entry and entry.sortType then
SortWho(entry.sortType)
end
WhoList_Update()
end
-- ── Events (ref FriendsFrame_OnEvent l.635-662) ────────────────────────────────────────
function FriendsFrame_OnEvent()
if event == "FRIENDLIST_SHOW" then
FriendsList_Update()
FriendsFrame_Update()
elseif event == "FRIENDLIST_UPDATE" then
FriendsList_Update()
elseif event == "IGNORELIST_UPDATE" then
IgnoreList_Update()
elseif event == "WHO_LIST_UPDATE" then
-- A fresh answer drops the old selection: row 3 of the last query is not row 3 of
-- this one, and the ref's own Refresh button clears it for exactly that reason.
WhoFrame.selectedWho = nil
WhoList_Update()
end
end
function FriendsFrame_OnLoad()
PanelTemplates_SetNumTabs(this, 3)
this.selectedTab = 1
this.showFriendsList = 1
this.selectedFriend = 0
this.selectedIgnore = 0
PanelTemplates_UpdateTabs(this)
-- No guild arc yet, so the GUILD tab is what a guildless character sees: present,
-- greyed, un-clickable (ref InGuildCheck l.920-931, the `not IsInGuild()` branch).
PanelTemplates_DisableTab(this, 3)
this:RegisterEvent("FRIENDLIST_SHOW")
this:RegisterEvent("FRIENDLIST_UPDATE")
this:RegisterEvent("IGNORELIST_UPDATE")
this:RegisterEvent("WHO_LIST_UPDATE")
end
function FriendsFrame_OnShow()
FriendsFrame_Update()
-- Guarded, the house idiom (CharacterFrame/QuestLogFrame do the same): MicroMenu.xml
-- loads before this file in the real manifest, but a window must stay loadable on its
-- own for its tests.
if UpdateMicroButtons then UpdateMicroButtons() end
PlaySound("igMainMenuOpen")
end
function FriendsFrame_OnHide()
if UpdateMicroButtons then UpdateMicroButtons() end
PlaySound("igMainMenuClose")
for i = 1, table.getn(BENILLA_FRIENDS_SUBFRAMES) do
getglobal(BENILLA_FRIENDS_SUBFRAMES[i]):Hide()
end
end
-- ── Row clicks (ref l.664-688) ─────────────────────────────────────────────────────────
function FriendsFrameFriendButton_OnClick(button)
if button == "RightButton" then
local name, _, _, _, connected = GetFriendInfo(this:GetID())
BenillaFriendsFrame_ShowDropdown(name, connected)
return
end
SetSelectedFriend(this:GetID())
FriendsList_Update()
end
function FriendsFrameIgnoreButton_OnClick()
SetSelectedIgnore(this:GetID())
IgnoreList_Update()
end
function FriendsFrameWhoButton_OnClick(button)
local name = getglobal(this:GetName() .. "Name"):GetText()
if button == "RightButton" then
-- A /who hit is online by construction, so the menu is never gated shut here.
BenillaFriendsFrame_ShowDropdown(name, 1)
return
end
WhoFrame.selectedWho = this.whoIndex
WhoFrame.selectedName = name
WhoList_Update()
end
-- ── The buttons (ref l.714-739) ────────────────────────────────────────────────────────
function FriendsFrame_UnIgnore()
local name = GetIgnoreName(FriendsFrame.selectedIgnore)
if name then
DelIgnore(name)
end
end
function FriendsFrame_RemoveFriend()
if FriendsFrame.selectedFriend and FriendsFrame.selectedFriend > 0 then
RemoveFriend(FriendsFrame.selectedFriend)
end
end
-- The ref opens the chat edit box prefilled "/w <name> " (l.726-734). benilla's chat edit
-- box is app-side, so the same intent goes through `ChatFrame_SendTell`, the whisper-target
-- queue the unit popup's WHISPER row already feeds.
function FriendsFrame_SendMessage()
local name = GetFriendInfo(FriendsFrame.selectedFriend)
if name and name ~= "" then
ChatFrame_SendTell(name)
end
end
function FriendsFrame_GroupInvite()
local name = GetFriendInfo(FriendsFrame.selectedFriend)
if name and name ~= "" then
InviteByName(name)
end
end
-- ── The window verbs (ref ToggleFriendsFrame l.741-765, ShowWhoPanel l.772-779) ────────
-- `tab` nil = plain toggle; 1 = friends, 2 = who. Clicking the tab you are already on
-- closes the window (the ref's own second branch).
function ToggleFriendsFrame(tab)
if not tab then
if FriendsFrame:IsVisible() then
HideUIPanel(FriendsFrame)
else
ShowUIPanel(FriendsFrame)
end
return
end
if tab == PanelTemplates_GetSelectedTab(FriendsFrame)
and FriendsFrame:IsVisible() then
HideUIPanel(FriendsFrame)
return
end
PanelTemplates_SetTab(FriendsFrame, tab)
if FriendsFrame:IsVisible() then
FriendsFrame_OnShow()
else
ShowUIPanel(FriendsFrame)
end
end
function ShowWhoPanel()
PanelTemplates_SetTab(FriendsFrame, 2)
if FriendsFrame:IsVisible() then
FriendsFrame_OnShow()
else
ShowUIPanel(FriendsFrame)
end
end
function ShowIgnorePanel()
FriendsFrame.showFriendsList = nil
PanelTemplates_SetTab(FriendsFrame, 1)
if FriendsFrame:IsVisible() then
FriendsFrame_OnShow()
else
ShowUIPanel(FriendsFrame)
end
end
-- The default `/who` (ref WhoFrame_GetDefaultWhoCommand l.790-798): this zone, my level
-- ±3.
function WhoFrame_GetDefaultWhoCommand()
local level = UnitLevel("player") or 1
local minLevel = level - 3
if minLevel <= 0 then
minLevel = 1
end
return WHO_TAG_ZONE .. "\"" .. (GetRealZoneText() or "") .. "\" "
.. minLevel .. "-" .. (level + 3)
end
function WhoFrameEditBox_OnEnterPressed()
SendWho(WhoFrameEditBox:GetText())
WhoFrameEditBox:ClearFocus()
end
-- ── The slash bodies (ref ChatFrame.lua SlashCmdList l.1013-1062, verbatim) ────────────
-- benilla parses slash lines in Rust, so the app calls these rather than a SlashCmdList
-- table — but the bodies are the ref's, so the window behaviour stays in the FrameXML.
function BenillaSlashWho(msg)
if msg == "" then
msg = WhoFrame_GetDefaultWhoCommand()
ShowWhoPanel()
end
WhoFrameEditBox:SetText(msg)
SendWho(msg)
end
function BenillaSlashFriends(msg)
if msg ~= "" then
AddFriend(msg)
else
ShowFriends()
end
end
function BenillaSlashRemoveFriend(msg)
if msg ~= "" then
RemoveFriend(msg)
end
end
function BenillaSlashIgnore(msg)
if msg ~= "" then
AddOrDelIgnore(msg)
else
ShowIgnorePanel()
end
end
function BenillaSlashUnignore(msg)
if msg ~= "" then
DelIgnore(msg)
else
ShowIgnorePanel()
end
end
-- ── The two name-entry dialogs (ref StaticPopup.lua l.775-820) ─────────────────────────
-- The first customers of the popup engine's hasEditBox capability (decision 0668).
StaticPopupDialogs["ADD_FRIEND"] = {
text = ADD_FRIEND_LABEL,
button1 = "Accept",
button2 = "Cancel",
hasEditBox = 1,
maxLetters = 12,
OnAccept = function()
AddFriend(getglobal("StaticPopup1EditBox"):GetText())
end,
OnShow = function()
getglobal("StaticPopup1EditBox"):SetFocus()
end,
EditBoxOnEnterPressed = function()
AddFriend(getglobal("StaticPopup1EditBox"):GetText())
StaticPopup_Hide("ADD_FRIEND")
end,
timeout = 0,
hideOnEscape = 1,
}
StaticPopupDialogs["ADD_IGNORE"] = {
text = ADD_IGNORE_LABEL,
button1 = "Accept",
button2 = "Cancel",
hasEditBox = 1,
maxLetters = 12,
OnAccept = function()
AddIgnore(getglobal("StaticPopup1EditBox"):GetText())
end,
OnShow = function()
getglobal("StaticPopup1EditBox"):SetFocus()
end,
EditBoxOnEnterPressed = function()
AddIgnore(getglobal("StaticPopup1EditBox"):GetText())
StaticPopup_Hide("ADD_IGNORE")
end,
timeout = 0,
hideOnEscape = 1,
}
]]></Script>
<!-- The panel action button face. No `UIPanelButtonTemplate` ships in this house (every NPC
window reconstructs it locally — Trainer/Bank/Craft say so in their own headers), so this
is that face: the ref's UI-Panel-Button three-state art, label via `text=`. -->
<Button name="BenillaFriendsPanelButtonTemplate" virtual="true">
<Size><AbsDimension x="131" y="21"/></Size>
<NormalFont inherits="GameFontNormal"/>
<HighlightFont inherits="GameFontHighlight"/>
<DisabledFont inherits="GameFontDisable"/>
<NormalTexture file="Interface\Buttons\UI-Panel-Button-Up"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></NormalTexture>
<PushedTexture file="Interface\Buttons\UI-Panel-Button-Down"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></PushedTexture>
<DisabledTexture file="Interface\Buttons\UI-Panel-Button-Disabled"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></DisabledTexture>
<HighlightTexture file="Interface\Buttons\UI-Panel-Button-Highlight" alphaMode="ADD"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></HighlightTexture>
</Button>
<!-- ── Row templates (ref FriendsFrame.xml l.4-165) ─────────────────────────────────────── -->
<Button name="BenillaFriendsFrameButtonTemplate" virtual="true">
<Size><AbsDimension x="298" y="31"/></Size>
<Layers>
<Layer level="BORDER">
<FontString name="$parentNameLocation" inherits="GameFontNormal" justifyH="LEFT">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-3"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentInfo" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentNameLocation" relativePoint="BOTTOMLEFT"/></Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<!-- Both buttons, ref-verbatim (`RegisterForClicks("LeftButtonUp","RightButtonUp")`):
left selects, right opens the FRIEND menu. arg1 is the button name. -->
<OnLoad>this:RegisterForClicks("LeftButtonUp", "RightButtonUp")</OnLoad>
<OnClick>FriendsFrameFriendButton_OnClick(arg1); PlaySound("igMainMenuOptionCheckBoxOn")</OnClick>
</Scripts>
<HighlightTexture file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD"/>
</Button>
<Button name="BenillaFriendsFrameIgnoreButtonTemplate" virtual="true">
<Size><AbsDimension x="298" y="16"/></Size>
<Layers>
<Layer level="BORDER">
<FontString name="$parentName" inherits="GameFontNormal" justifyH="LEFT">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-3"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnClick>FriendsFrameIgnoreButton_OnClick(); PlaySound("igMainMenuOptionCheckBoxOn")</OnClick>
</Scripts>
<HighlightTexture file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD"/>
</Button>
<!-- The who row's four columns, chained left to right off the name (ref l.74-165). -->
<Button name="BenillaFriendsFrameWhoButtonTemplate" virtual="true">
<Size><AbsDimension x="298" y="16"/></Size>
<Layers>
<Layer level="BORDER">
<FontString name="$parentName" inherits="GameFontNormalSmall" justifyH="LEFT">
<Size><AbsDimension x="88" y="14"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-3"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentVariable" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size><AbsDimension x="95" y="14"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="$parentName" relativePoint="RIGHT"/></Anchors>
</FontString>
<FontString name="$parentLevel" inherits="GameFontHighlightSmall" justifyH="CENTER">
<Size><AbsDimension x="20" y="14"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="$parentVariable" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor></Anchors>
</FontString>
<FontString name="$parentClass" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size><AbsDimension x="100" y="8"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="$parentLevel" relativePoint="RIGHT"><Offset><AbsDimension x="12" y="0"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>this:RegisterForClicks("LeftButtonUp", "RightButtonUp")</OnLoad>
<OnClick>FriendsFrameWhoButton_OnClick(arg1); PlaySound("igMainMenuOptionCheckBoxOn")</OnClick>
</Scripts>
<HighlightTexture file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD"/>
</Button>
<!-- The who column header: a three-slice tab strip, clickable to sort (ref l.166-233). -->
<Button name="BenillaWhoFrameColumnHeaderTemplate" virtual="true">
<Size><AbsDimension x="10" y="24"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentLeft" file="Interface\FriendsFrame\WhoFrame-ColumnTabs">
<Size><AbsDimension x="5" y="24"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<TexCoords left="0" right="0.078125" top="0" bottom="0.75"/>
</Texture>
<Texture name="$parentMiddle" file="Interface\FriendsFrame\WhoFrame-ColumnTabs">
<Size><AbsDimension x="53" y="24"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"/></Anchors>
<TexCoords left="0.078125" right="0.90625" top="0" bottom="0.75"/>
</Texture>
<Texture name="$parentRight" file="Interface\FriendsFrame\WhoFrame-ColumnTabs">
<Size><AbsDimension x="4" y="24"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="$parentMiddle" relativePoint="RIGHT"/></Anchors>
<TexCoords left="0.90625" right="0.96875" top="0" bottom="0.75"/>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnClick>
if this.sortType then
SortWho(this.sortType)
end
PlaySound("igMainMenuOptionCheckBoxOn")
</OnClick>
</Scripts>
<ButtonText>
<Anchors><Anchor point="LEFT"><Offset><AbsDimension x="8" y="0"/></Offset></Anchor></Anchors>
</ButtonText>
<NormalFont inherits="GameFontHighlightSmall"/>
<HighlightTexture name="$parentHighlightTexture" file="Interface\PaperDollInfoFrame\UI-Character-Tab-Highlight" alphaMode="ADD">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentLeft"><Offset><AbsDimension x="-2" y="5"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT" relativeTo="$parentRight"><Offset><AbsDimension x="2" y="-7"/></Offset></Anchor>
</Anchors>
</HighlightTexture>
</Button>
<!-- ── The window (ref l.506-607) ───────────────────────────────────────────────────────── -->
<Frame name="FriendsFrame" toplevel="true" movable="true" enableMouse="true" hidden="true">
<Size><AbsDimension x="384" y="512"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-104"/></Offset></Anchor></Anchors>
<HitRectInsets><AbsInset left="0" right="30" top="0" bottom="45"/></HitRectInsets>
<Layers>
<Layer level="BACKGROUND">
<Texture file="Interface\FriendsFrame\FriendsFrameScrollIcon">
<Size><AbsDimension x="60" y="60"/></Size>
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="7" y="-6"/></Offset></Anchor></Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<Texture name="FriendsFrameTopLeft" file="Interface\PaperDollInfoFrame\UI-Character-General-TopLeft">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
</Texture>
<Texture name="FriendsFrameTopRight" file="Interface\PaperDollInfoFrame\UI-Character-General-TopRight">
<Size><AbsDimension x="128" y="256"/></Size>
<Anchors><Anchor point="TOPRIGHT"/></Anchors>
</Texture>
<Texture name="FriendsFrameBottomLeft" file="Interface\FriendsFrame\UI-FriendsFrame-BotLeft">
<Size><AbsDimension x="256" y="256"/></Size>
<Anchors><Anchor point="BOTTOMLEFT"/></Anchors>
</Texture>
<Texture name="FriendsFrameBottomRight" file="Interface\FriendsFrame\UI-FriendsFrame-BotRight">
<Size><AbsDimension x="128" y="256"/></Size>
<Anchors><Anchor point="BOTTOMRIGHT"/></Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="FriendsFrameTitleText" inherits="GameFontNormal">
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-18"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The row right-click menu's host (ref `<Frame name="FriendsDropDown"
inherits="UIDropDownMenuTemplate"/>`): invisible until ToggleDropDownMenu opens
it at the cursor. -->
<Frame name="BenillaFriendsDropDown" inherits="UIDropDownMenuTemplate"/>
<!-- Close: the ref's own UIPanelCloseButton seat (TOPRIGHT -30,-8) on the
minimize-button art every close button in this house uses — no UIPanelCloseButton
template ships (CharacterFrame/Gossip/Bag say the same). -->
<Button name="FriendsFrameCloseButton">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-30" y="-8"/></Offset></Anchor></Anchors>
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
<Scripts>
<OnLoad>self:SetFrameLevel(self:GetFrameLevel() + 1)</OnLoad>
<OnClick>HideUIPanel(FriendsFrame)</OnClick>
</Scripts>
</Button>
<!-- ── Tab 1a: the friends list ─────────────────────────────────────────────────── -->
<Frame name="FriendsListFrame" hidden="true" setAllPoints="true">
<Frames>
<Button name="FriendsFrameToggleTab1" inherits="TabButtonTemplate" text="Friends" id="1">
<Anchors><Anchor point="TOPLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="70" y="-39"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>PanelTemplates_SelectTab(this)</OnLoad></Scripts>
</Button>
<Button name="FriendsFrameToggleTab2" inherits="TabButtonTemplate" text="Ignore" id="2">
<Anchors><Anchor point="LEFT" relativeTo="FriendsFrameToggleTab1" relativePoint="RIGHT"/></Anchors>
<Scripts>
<OnShow>PanelTemplates_DeselectTab(this)</OnShow>
<OnClick>
FriendsFrame.showFriendsList = nil
FriendsFrame_Update()
PlaySound("igCharacterInfoTab")
</OnClick>
</Scripts>
</Button>
<Button name="FriendsFrameAddFriendButton" inherits="BenillaFriendsPanelButtonTemplate" text="Add Friend">
<Size><AbsDimension x="131" y="21"/></Size>
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="17" y="107"/></Offset></Anchor></Anchors>
<Scripts>
<!-- Ref l.656-662: a friendly player target is befriended straight
away; otherwise the name-entry dialog opens. -->
<OnClick>
if UnitCanCooperate("player", "target") then
AddFriend(UnitName("target"))
else
StaticPopup_Show("ADD_FRIEND")
end
</OnClick>
<OnEnter>BenillaTooltip_AddNewbieTipFor(self, ADD_FRIEND, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_ADDFRIEND, 1)</OnEnter>
<OnLeave>GameTooltip:Hide()</OnLeave>
</Scripts>
</Button>
<Button name="FriendsFrameRemoveFriendButton" inherits="BenillaFriendsPanelButtonTemplate" text="Remove Friend">
<Size><AbsDimension x="131" y="21"/></Size>
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameAddFriendButton" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>FriendsFrame_RemoveFriend()</OnClick>
<OnEnter>BenillaTooltip_AddNewbieTipFor(self, REMOVE_FRIEND, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_REMOVEFRIEND, 1)</OnEnter>
<OnLeave>GameTooltip:Hide()</OnLeave>
</Scripts>
</Button>
<Button name="FriendsFrameSendMessageButton" inherits="BenillaFriendsPanelButtonTemplate" text="Send Message">
<Size><AbsDimension x="131" y="21"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="FriendsFrameAddFriendButton" relativePoint="RIGHT"><Offset><AbsDimension x="66" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>FriendsFrame_SendMessage()</OnClick>
<OnEnter>BenillaTooltip_AddNewbieTipFor(self, SEND_MESSAGE, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_SENDMESSAGE, 1)</OnEnter>
<OnLeave>GameTooltip:Hide()</OnLeave>
</Scripts>
</Button>
<Button name="FriendsFrameGroupInviteButton" inherits="BenillaFriendsPanelButtonTemplate" text="Group Invite">
<Size><AbsDimension x="131" y="21"/></Size>
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameSendMessageButton" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>FriendsFrame_GroupInvite()</OnClick>
<OnEnter>BenillaTooltip_AddNewbieTipFor(self, GROUP_INVITE, 1.0, 1.0, 1.0, NEWBIE_TOOLTIP_GROUPINVITE, 1)</OnEnter>
<OnLeave>GameTooltip:Hide()</OnLeave>
</Scripts>
</Button>
<!-- The ten rows: the first at (23,-76) off the window, the rest chained
TOP→BOTTOM with no gap (ref l.740-829). -->
<Button name="FriendsFrameFriendButton1" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="23" y="-76"/></Offset></Anchor></Anchors>
</Button>
<Button name="FriendsFrameFriendButton2" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton1" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton3" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton2" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton4" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton3" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton5" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton4" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton6" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton5" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton7" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton6" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton8" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton7" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton9" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton8" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameFriendButton10" inherits="BenillaFriendsFrameButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameFriendButton9" relativePoint="BOTTOM"/></Anchors>
</Button>
<Frame name="FriendsFrameFriendsScrollFrame" inherits="FauxScrollFrameTemplate">
<Size><AbsDimension x="296" y="304"/></Size>
<Anchors><Anchor point="TOPRIGHT" relativeTo="FriendsFrame"><Offset><AbsDimension x="-67" y="-75"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>self.updateFunc = FriendsList_Update</OnLoad></Scripts>
</Frame>
</Frames>
<Scripts>
<OnMouseWheel>BenillaFauxScrollFrame_OnMouseWheel(FriendsFrameFriendsScrollFrame, arg1)</OnMouseWheel>
</Scripts>
</Frame>
<!-- ── Tab 1b: the ignore list (ref l.879-1193) ─────────────────────────────────── -->
<Frame name="IgnoreListFrame" hidden="true" setAllPoints="true">
<Frames>
<Button name="IgnoreFrameToggleTab1" inherits="TabButtonTemplate" text="Friends" id="1">
<Anchors><Anchor point="TOPLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="70" y="-39"/></Offset></Anchor></Anchors>
<Scripts>
<OnShow>PanelTemplates_DeselectTab(this)</OnShow>
<OnClick>
FriendsFrame.showFriendsList = 1
FriendsFrame_Update()
PlaySound("igCharacterInfoTab")
</OnClick>
</Scripts>
</Button>
<Button name="IgnoreFrameToggleTab2" inherits="TabButtonTemplate" text="Ignore" id="2">
<Anchors><Anchor point="LEFT" relativeTo="IgnoreFrameToggleTab1" relativePoint="RIGHT"/></Anchors>
<Scripts><OnShow>PanelTemplates_SelectTab(this)</OnShow></Scripts>
</Button>
<Button name="FriendsFrameIgnorePlayerButton" inherits="BenillaFriendsPanelButtonTemplate" text="Ignore Player">
<Size><AbsDimension x="131" y="21"/></Size>
<!-- (17,81), NOT the friends list's (17,107): the ignore pane has two
buttons where that one has four, so its row sits lower (ref l.919-925). -->
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="17" y="81"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>StaticPopup_Show("ADD_IGNORE")</OnClick>
</Scripts>
</Button>
<Button name="FriendsFrameStopIgnoreButton" inherits="BenillaFriendsPanelButtonTemplate" text="Remove Player">
<Size><AbsDimension x="131" y="21"/></Size>
<Anchors><Anchor point="LEFT" relativeTo="FriendsFrameIgnorePlayerButton" relativePoint="RIGHT"><Offset><AbsDimension x="62" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>FriendsFrame_UnIgnore()</OnClick>
</Scripts>
</Button>
<Button name="FriendsFrameIgnoreButton1" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<!-- -80, not the friends list's -76 (ref l.965-971). -->
<Anchors><Anchor point="TOPLEFT" relativeTo="FriendsFrame"><Offset><AbsDimension x="23" y="-80"/></Offset></Anchor></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton2" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton1" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton3" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton2" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton4" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton3" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton5" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton4" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton6" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton5" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton7" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton6" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton8" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton7" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton9" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton8" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton10" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton9" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton11" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton10" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton12" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton11" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton13" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton12" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton14" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton13" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton15" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton14" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton16" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton15" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton17" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton16" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton18" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton17" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton19" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton18" relativePoint="BOTTOM"/></Anchors>
</Button>
<Button name="FriendsFrameIgnoreButton20" inherits="BenillaFriendsFrameIgnoreButtonTemplate">
<Anchors><Anchor point="TOP" relativeTo="FriendsFrameIgnoreButton19" relativePoint="BOTTOM"/></Anchors>
</Button>
<Frame name="FriendsFrameIgnoreScrollFrame" inherits="FauxScrollFrameTemplate">
<!-- 332 tall, not the friends list's 304: 20 short rows reach further
down than 10 tall ones (ref l.1146-1148). -->
<Size><AbsDimension x="296" y="332"/></Size>
<Anchors><Anchor point="TOPRIGHT" relativeTo="FriendsFrame"><Offset><AbsDimension x="-67" y="-75"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>self.updateFunc = IgnoreList_Update</OnLoad></Scripts>
</Frame>
</Frames>
<Scripts>
<OnMouseWheel>BenillaFauxScrollFrame_OnMouseWheel(FriendsFrameIgnoreScrollFrame, arg1)</OnMouseWheel>
</Scripts>
</Frame>
<!-- ── Tab 2: /who (ref l.1194-1718) ────────────────────────────────────────────── -->
<Frame name="WhoFrame" hidden="true" setAllPoints="true">
<Layers>
<Layer level="ARTWORK">
<FontString name="WhoFrameTotals" inherits="GameFontNormalSmall">
<Size><AbsDimension x="298" y="16"/></Size>
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="-10" y="127"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="WhoFrameColumnHeader1" inherits="BenillaWhoFrameColumnHeaderTemplate" text="Name">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="-70"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>WhoFrameColumn_SetWidth(83, this); this.sortType = "name"</OnLoad></Scripts>
</Button>
<Button name="WhoFrameColumnHeader2" inherits="BenillaWhoFrameColumnHeaderTemplate">
<Anchors><Anchor point="LEFT" relativeTo="WhoFrameColumnHeader1" relativePoint="RIGHT"><Offset><AbsDimension x="-2" y="0"/></Offset></Anchor></Anchors>
<Frames>
<!-- The variable column IS a dropdown sitting in its own header
(ref l.1326-1375). -->
<Frame name="WhoFrameDropDown" inherits="UIDropDownMenuTemplate" id="1">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="-15" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnLoad>WhoFrameDropDown_OnLoad()</OnLoad>
<OnShow>
UIDropDownMenu_Initialize(WhoFrameDropDown, WhoFrameDropDown_Initialize)
UIDropDownMenu_SetSelectedID(WhoFrameDropDown, 1)
</OnShow>
</Scripts>
</Frame>
</Frames>
<Scripts><OnLoad>WhoFrameColumn_SetWidth(105, this)</OnLoad></Scripts>
</Button>
<Button name="WhoFrameColumnHeader3" inherits="BenillaWhoFrameColumnHeaderTemplate" text="Lvl">
<Anchors><Anchor point="LEFT" relativeTo="WhoFrameColumnHeader2" relativePoint="RIGHT"><Offset><AbsDimension x="-2" y="0"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>WhoFrameColumn_SetWidth(32, this); this.sortType = "level"</OnLoad></Scripts>
</Button>
<Button name="WhoFrameColumnHeader4" inherits="BenillaWhoFrameColumnHeaderTemplate" text="Class">
<Anchors><Anchor point="LEFT" relativeTo="WhoFrameColumnHeader3" relativePoint="RIGHT"><Offset><AbsDimension x="-2" y="0"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>WhoFrameColumn_SetWidth(92, this); this.sortType = "class"</OnLoad></Scripts>
</Button>
<Button name="WhoFrameButton1" inherits="BenillaFriendsFrameWhoButtonTemplate" id="1">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrame"><Offset><AbsDimension x="15" y="-95"/></Offset></Anchor></Anchors>
</Button>
<Button name="WhoFrameButton2" inherits="BenillaFriendsFrameWhoButtonTemplate" id="2">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton1" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton3" inherits="BenillaFriendsFrameWhoButtonTemplate" id="3">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton2" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton4" inherits="BenillaFriendsFrameWhoButtonTemplate" id="4">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton3" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton5" inherits="BenillaFriendsFrameWhoButtonTemplate" id="5">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton4" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton6" inherits="BenillaFriendsFrameWhoButtonTemplate" id="6">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton5" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton7" inherits="BenillaFriendsFrameWhoButtonTemplate" id="7">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton6" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton8" inherits="BenillaFriendsFrameWhoButtonTemplate" id="8">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton7" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton9" inherits="BenillaFriendsFrameWhoButtonTemplate" id="9">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton8" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton10" inherits="BenillaFriendsFrameWhoButtonTemplate" id="10">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton9" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton11" inherits="BenillaFriendsFrameWhoButtonTemplate" id="11">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton10" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton12" inherits="BenillaFriendsFrameWhoButtonTemplate" id="12">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton11" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton13" inherits="BenillaFriendsFrameWhoButtonTemplate" id="13">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton12" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton14" inherits="BenillaFriendsFrameWhoButtonTemplate" id="14">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton13" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton15" inherits="BenillaFriendsFrameWhoButtonTemplate" id="15">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton14" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton16" inherits="BenillaFriendsFrameWhoButtonTemplate" id="16">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton15" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameButton17" inherits="BenillaFriendsFrameWhoButtonTemplate" id="17">
<Anchors><Anchor point="TOPLEFT" relativeTo="WhoFrameButton16" relativePoint="BOTTOMLEFT"/></Anchors>
</Button>
<Button name="WhoFrameGroupInviteButton" inherits="BenillaFriendsPanelButtonTemplate" text="Group Invite">
<Size><AbsDimension x="120" y="22"/></Size>
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-40" y="82"/></Offset></Anchor></Anchors>
<Scripts><OnClick>InviteByName(WhoFrame.selectedName)</OnClick></Scripts>
</Button>
<Button name="WhoFrameAddFriendButton" inherits="BenillaFriendsPanelButtonTemplate" text="Add Friend">
<Size><AbsDimension x="120" y="22"/></Size>
<Anchors><Anchor point="RIGHT" relativeTo="WhoFrameGroupInviteButton" relativePoint="LEFT"/></Anchors>
<Scripts><OnClick>AddFriend(WhoFrame.selectedName)</OnClick></Scripts>
</Button>
<Button name="WhoFrameWhoButton" inherits="BenillaFriendsPanelButtonTemplate" text="Refresh">
<Size><AbsDimension x="85" y="22"/></Size>
<Anchors><Anchor point="RIGHT" relativeTo="WhoFrameAddFriendButton" relativePoint="LEFT"/></Anchors>
<Scripts>
<OnClick>
WhoFrameEditBox_OnEnterPressed()
WhoFrame.selectedWho = nil
</OnClick>
</Scripts>
</Button>
<EditBox name="WhoFrameEditBox" autoFocus="false" historyLines="32">
<Size><AbsDimension x="296" y="32"/></Size>
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="-20" y="100"/></Offset></Anchor></Anchors>
<Scripts>
<OnShow>this:ClearFocus()</OnShow>
<OnEnterPressed>WhoFrameEditBox_OnEnterPressed()</OnEnterPressed>
<OnEscapePressed>this:ClearFocus()</OnEscapePressed>
</Scripts>
<FontString inherits="ChatFontNormal"/>
</EditBox>
<Frame name="WhoListScrollFrame" inherits="FauxScrollFrameTemplate">
<Size><AbsDimension x="296" y="287"/></Size>
<Anchors><Anchor point="TOPRIGHT" relativeTo="FriendsFrame" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-67" y="-96"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>self.updateFunc = WhoList_Update</OnLoad></Scripts>
</Frame>
</Frames>
<Scripts>
<!-- SetWhoToUI decides where the NEXT answer goes: this frame, or the chat
window (ref l.1707-1717). -->
<OnLoad>SetWhoToUI(0)</OnLoad>
<OnShow>SetWhoToUI(1)</OnShow>
<OnHide>SetWhoToUI(0)</OnHide>
<OnMouseWheel>BenillaFauxScrollFrame_OnMouseWheel(WhoListScrollFrame, arg1)</OnMouseWheel>
</Scripts>
</Frame>
<!-- ── The tab strip (ref l.3439-3540) ──────────────────────────────────────────── -->
<Button name="FriendsFrameTab1" inherits="CharacterFrameTabButtonTemplate" id="1" text="Friends">
<Anchors><Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="11" y="47"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>
PanelTemplates_SetTab(FriendsFrame, this:GetID())
FriendsFrame_OnShow()
PlaySound("igCharacterInfoTab")
</OnClick>
</Scripts>
</Button>
<Button name="FriendsFrameTab2" inherits="CharacterFrameTabButtonTemplate" id="2" text="Who">
<Anchors><Anchor point="LEFT" relativeTo="FriendsFrameTab1" relativePoint="RIGHT"><Offset><AbsDimension x="-14" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>
PanelTemplates_SetTab(FriendsFrame, this:GetID())
FriendsFrame_OnShow()
PlaySound("igCharacterInfoTab")
</OnClick>
</Scripts>
</Button>
<!-- Disabled for a guildless character, which we always are (header SCOPE note). -->
<Button name="FriendsFrameTab3" inherits="CharacterFrameTabButtonTemplate" id="3" text="Guild">
<Anchors><Anchor point="LEFT" relativeTo="FriendsFrameTab2" relativePoint="RIGHT"><Offset><AbsDimension x="-14" y="0"/></Offset></Anchor></Anchors>
</Button>
</Frames>
<Scripts>
<OnLoad>FriendsFrame_OnLoad()</OnLoad>
<OnShow>FriendsFrame_OnShow()</OnShow>
<OnHide>FriendsFrame_OnHide()</OnHide>
<OnEvent>FriendsFrame_OnEvent()</OnEvent>
</Scripts>
</Frame>
</Ui>