- The main menu bar's two empty recesses fill. The micro menu — the eight arched buttons: character, spellbook, talents, quest log, socials, world map, main menu, help — sits in the dark panel between the page arrows and the bags, transcribed from the reference's own layout: the character button wears your portrait, a button holds itself down while its panel is up, and the talent button appears at level 10. The latency meter fills the one slot the bar art leaves transparent for exactly it, tinted green/yellow/red on the reference's 300/600 ms thresholds and drawn UNDER the bar art, seen through its window, the way 1.12 actually does it. The socials and main-menu buttons find their panels one snapshot later; help still waits. - The UI explains itself on hover: 1.12 ships its detailed two-line tooltips ON — a FrameXML default, not the opt-in extra it is often remembered as — so the micro buttons, your own portrait, the XP bar, the five bag buttons and the ping meter all answer a hover with the reference's own explanations. - The PvP flag, end to end: crossed swords on the player, target and party frames, driven by the two descriptor bits the wire actually carries, and `/pvp` speaks — the yellow toast plus the system chat line, the OFF sentence being the one that warns the flag lingers for five minutes. It really does linger: turning it off waits out the server's timer, which looks like a bug and is the reference. - Quest markers stopped freezing. The grey `!` over a questgiver above your level goes gold the moment you ding, an NPC re-entering view is asked afresh instead of wearing a session-old answer, and the marker drops when the questgiver bit goes off — the re-ask triggers mirror the reference's own set, plus one named addition (your own level changing). - Water and heights: swimming downhill no longer bounces between swim and fall ten times a second — the surface line is a two-sided constraint, so the swimmer settles with the river instead of being left behind by it. And collision height is per-unit now, read from the unit's own model: a gnome used to swim with a third of a yard of water over her head because five depth lines were quoting a human's number. - A round of pixel honesty in text and chat: the newest chat line no longer wears a wider drop shadow than every line above it (shadows move in whole pixels now), keeps its descenders, and hover boxes stop painting over the chat body. The chat input's history browse survives programmatic edits, a failed script chunk warns instead of vanishing, and recall deepens to 64 lines. Idle animation got honest too: a model's idle is Stand resolved through its own lookup table — never file order, which had the duel flag bobbing on its spawn clip — and an armed idle is culled on the box its animation authors, not the bind pose, so the flag stops vanishing at most camera angles. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
874 lines
46 KiB
XML
874 lines
46 KiB
XML
<Ui>
|
||
<!--
|
||
The chat window, rebuilt on the reference's own structure (decision 0288 P3): the docked
|
||
General + Combat Log pair sharing ChatFrame1's rect, the hover-revealed tabs and
|
||
background (the classic transparent chat — chat-cache.txt ships window alpha 0, hover
|
||
fades to DEFAULT_CHATFRAME_ALPHA 0.25), the outside-left scroll column with the
|
||
blinking bottom button, and the reference edit box (three-piece border art + header)
|
||
below the frame. Geometry, art paths, timing constants, and behaviors are QUOTED from the
|
||
extracted patch-chain FloatingChatFrame.xml/.lua + ChatFrame.xml/.lua (the pin in 0288);
|
||
window management (drag/undock/resize/rename, the tab right-click options dropdown) is
|
||
chat SETTINGS — deliberately out (0288 §2).
|
||
|
||
The inbound feed (ui_chat::feed) AddMessages into ChatFrame1; the composer/router phase
|
||
(0288 P4) fans CHAT_MSG groups across both windows per the chat-cache defaults. The edit
|
||
box submits through SubmitChatInput → ui_chat::input's grammar; its live header machine
|
||
(ChatEdit_UpdateHeader) is 0288 P5 — until then the header shows the sticky default
|
||
"Say:" with static insets.
|
||
-->
|
||
<Script><![CDATA[
|
||
-- ── BenillaFCF: the FloatingChatFrame behaviors, transcribed (ref FloatingChatFrame.lua)
|
||
-- Quoted constants: CHAT_TAB_SHOW_DELAY=0.2, CHAT_FRAME_FADE_TIME=0.15,
|
||
-- DEFAULT_CHATFRAME_ALPHA=0.25, CHAT_BUTTON_FLASH_TIME=0.5,
|
||
-- MESSAGE_SCROLLBUTTON_INITIAL_DELAY=0, MESSAGE_SCROLLBUTTON_SCROLL_DELAY=0.05.
|
||
BenillaFCF = {
|
||
selected = 1, -- SELECTED_DOCK_FRAME (1 = General, 2 = Combat Log)
|
||
hover = false, -- cursor inside the dock's padded rect
|
||
hoverTime = 0, -- stationary-cursor accumulator (ref: moving resets it)
|
||
oldX = 0, oldY = 0,
|
||
reveal = 0, -- 0..1 master fade the tab/texture alphas scale by
|
||
revealTarget = 0,
|
||
flashTab = 0, -- tab id whose whisper flash runs (0 = none), 0288 P4 wires it
|
||
flashLeft = 0, -- remaining flash seconds (ref: 60s, blink 0.25/0.25)
|
||
}
|
||
|
||
-- The per-window texture sets the hover fade drives (ref CHAT_FRAME_TEXTURES: the
|
||
-- background + the 8 border pieces; benilla authors the borders as plain textures —
|
||
-- resizing is settings, the hover LOOK is not). Global: the load-time tint below needs it.
|
||
function BenillaFCF_Textures(id)
|
||
local n = "ChatFrame" .. id
|
||
local list = {}
|
||
for _, suffix in ipairs({
|
||
"Background",
|
||
"BorderTopLeft", "BorderTopRight", "BorderBottomLeft", "BorderBottomRight",
|
||
"BorderTop", "BorderBottom", "BorderLeft", "BorderRight",
|
||
}) do
|
||
local t = getglobal(n .. suffix)
|
||
if t then table.insert(list, t) end
|
||
end
|
||
return list
|
||
end
|
||
|
||
-- FCF_SelectDockFrame: show the selected frame, hide the other; selected tab full alpha,
|
||
-- unselected half (both still scaled by the reveal fade below). Stops the selected tab's
|
||
-- whisper flash (ref FCF_SelectDockFrame → UIFrameFlashRemoveFrame). Tab getglobals are
|
||
-- guarded: window 2's tab is deliberately unbuilt (see the note at the tab section).
|
||
function BenillaFCF_SelectDock(id)
|
||
BenillaFCF.selected = id
|
||
for i = 1, 2 do
|
||
local frame = getglobal("ChatFrame" .. i)
|
||
if i == id then frame:Show() else frame:Hide() end
|
||
end
|
||
if BenillaFCF.flashTab == id then
|
||
BenillaFCF.flashTab = 0
|
||
local flash = getglobal("ChatFrame" .. id .. "TabFlash")
|
||
if flash then flash:Hide() end
|
||
end
|
||
end
|
||
|
||
function BenillaFCF_TabClick(id)
|
||
-- ref FCF_Tab_OnClick (docked, left click): select; UChatScrollButton per click.
|
||
BenillaFCF_SelectDock(id)
|
||
PlaySound("UChatScrollButton")
|
||
end
|
||
|
||
-- The whisper tab flash (ref FCF_FlashTab: never the selected tab; 0.25s on/off for 60s,
|
||
-- and a flashing tab holds the dock tabs visible). Fired by the app on a received
|
||
-- whisper landing in an unselected window (0288 P4). No-tab windows can't flash.
|
||
function BenillaFCF_FlashTab(id)
|
||
if id == BenillaFCF.selected then return end
|
||
if not getglobal("ChatFrame" .. id .. "TabFlash") then return end
|
||
BenillaFCF.flashTab = id
|
||
BenillaFCF.flashLeft = 60
|
||
end
|
||
|
||
-- PanelTemplates_TabResize(5, tab), transcribed: the ref sizes every docked tab to its
|
||
-- label (FCF_DockUpdate) — middle slice = text width + 5, tab = middle + the two 16px
|
||
-- caps; the flash/highlight bands follow the Left/Right pieces by anchor. The label
|
||
-- width is host-measured (GetStringWidth), so early frames may see 0 — the OnUpdate
|
||
-- below re-applies until it settles, then the change-guard makes this a no-op.
|
||
function BenillaFCF_TabResize(tab)
|
||
local w = getglobal(tab:GetName() .. "Text"):GetStringWidth()
|
||
if w == 0 or tab.benillaTabTextW == w then return end
|
||
tab.benillaTabTextW = w
|
||
getglobal(tab:GetName() .. "Middle"):SetWidth(w + 5)
|
||
tab:SetWidth(w + 5 + 32)
|
||
end
|
||
|
||
-- The hover rect: the dock's rect expanded by the ref's MouseIsOver pads
|
||
-- (FCF_OnUpdate: MouseIsOver(chatFrame, 45, -10, -5, 5) — 45 up into the tab zone,
|
||
-- 10 down past the edit box seam, 5 out each side).
|
||
local function overDock(x, y)
|
||
local f = ChatFrame1
|
||
local left, right = f:GetLeft(), f:GetRight()
|
||
local top, bottom = f:GetTop(), f:GetBottom()
|
||
if not left then return false end
|
||
return x >= left - 5 and x <= right + 5 and y >= bottom - 10 and y <= top + 45
|
||
end
|
||
|
||
-- FCF_OnUpdate transcription (the parts that survive with window management out):
|
||
-- reveal after a 0.2s STATIONARY hover (a moving cursor keeps resetting the delay),
|
||
-- fade over 0.15s, conceal on leave; a flashing tab forces the tabs visible; the
|
||
-- selected window's textures ride the same fade toward alpha 0.25 (the chat-cache
|
||
-- default window alpha is 0 — the box only exists on hover).
|
||
function BenillaFCF_OnUpdate(elapsed)
|
||
local s = BenillaFCF
|
||
local x, y = GetCursorPosition()
|
||
if overDock(x, y) then
|
||
if not s.hover then
|
||
s.hover = true
|
||
s.hoverTime = 0
|
||
s.oldX, s.oldY = x, y
|
||
elseif s.oldX == x and s.oldY == y then
|
||
s.hoverTime = s.hoverTime + elapsed
|
||
else
|
||
s.hoverTime = 0
|
||
s.oldX, s.oldY = x, y
|
||
end
|
||
if s.hoverTime > 0.2 then s.revealTarget = 1 end
|
||
else
|
||
s.hover = false
|
||
s.hoverTime = 0
|
||
s.revealTarget = 0
|
||
end
|
||
if s.flashTab ~= 0 then s.revealTarget = 1 end
|
||
|
||
-- The 0.15s linear fade toward the target (ref UIFrameFadeIn/Out over
|
||
-- CHAT_FRAME_FADE_TIME).
|
||
if s.reveal < s.revealTarget then
|
||
s.reveal = math.min(s.revealTarget, s.reveal + elapsed / 0.15)
|
||
elseif s.reveal > s.revealTarget then
|
||
s.reveal = math.max(s.revealTarget, s.reveal - elapsed / 0.15)
|
||
end
|
||
|
||
-- Apply: tabs at 1.0 (selected) / 0.5 (unselected) × reveal; the selected window's
|
||
-- background+borders at 0.25 × reveal (ref: fade oldAlpha↔DEFAULT_CHATFRAME_ALPHA).
|
||
for i = 1, 2 do
|
||
local tab = getglobal("ChatFrame" .. i .. "Tab")
|
||
if tab then
|
||
local a = (i == BenillaFCF.selected) and 1.0 or 0.5
|
||
tab:SetAlpha(a * s.reveal)
|
||
BenillaFCF_TabResize(tab)
|
||
end
|
||
for _, t in ipairs(BenillaFCF_Textures(i)) do
|
||
t:SetAlpha(0.25 * s.reveal)
|
||
end
|
||
end
|
||
|
||
-- The whisper flash blink (0.25 on / 0.25 off, 60s — ref UIFrameFlash args).
|
||
if s.flashTab ~= 0 then
|
||
s.flashLeft = s.flashLeft - elapsed
|
||
local flash = getglobal("ChatFrame" .. s.flashTab .. "TabFlash")
|
||
if s.flashLeft <= 0 then
|
||
s.flashTab = 0
|
||
flash:Hide()
|
||
else
|
||
local phase = mod(s.flashLeft, 0.5)
|
||
if phase > 0.25 then flash:Show() else flash:Hide() end
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ChatFrame_OnUpdate transcription: the bottom button's blink while scrolled up
|
||
-- (CHAT_BUTTON_FLASH_TIME = 0.5s toggle; hidden the moment the view is AtBottom).
|
||
function BenillaChatFrame_OnUpdate(frame, elapsed)
|
||
local flash = getglobal(frame:GetName() .. "BottomButtonFlash")
|
||
if not flash then return end
|
||
if frame:AtBottom() then
|
||
flash:Hide()
|
||
frame.flashTimer = 0
|
||
return
|
||
end
|
||
frame.flashTimer = (frame.flashTimer or 0) + elapsed
|
||
while frame.flashTimer >= 0.5 do
|
||
frame.flashTimer = frame.flashTimer - 0.5
|
||
if flash:IsVisible() then flash:Hide() else flash:Show() end
|
||
end
|
||
end
|
||
|
||
-- MessageFrameScrollButton_OnLoad/_OnUpdate + the ref OnClick pair: a press arms the
|
||
-- hold-repeat (initial delay 0), each 0.05s while held scrolls WITHOUT the sound; the
|
||
-- release click scrolls once WITH the sound (ref FloatingChatFrame.xml's DownButton/
|
||
-- UpButton scripts — sound only on the non-pushed branch).
|
||
function BenillaChatScrollButton_OnClick(btn, down, dir, sound)
|
||
if down then
|
||
btn.clickDelay = 0
|
||
else
|
||
PlaySound(sound)
|
||
local frame = getglobal("ChatFrame" .. BenillaFCF.selected)
|
||
if dir == "up" then frame:ScrollUp() else frame:ScrollDown() end
|
||
end
|
||
end
|
||
|
||
function BenillaChatScrollButton_OnUpdate(btn, elapsed, dir)
|
||
if btn:GetButtonState() == "PUSHED" then
|
||
btn.clickDelay = (btn.clickDelay or 0) - elapsed
|
||
if btn.clickDelay < 0 then
|
||
local frame = getglobal("ChatFrame" .. BenillaFCF.selected)
|
||
if dir == "up" then frame:ScrollUp() else frame:ScrollDown() end
|
||
btn.clickDelay = 0.05
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ── BenillaUIMenu: the 1.12 UIMenu kit, transcribed (ref UIMenu.lua — the chat menu's
|
||
-- row engine: fixed 16px rows in a tooltip-backdrop box, a 2 s no-hover timeout that
|
||
-- walks up parentMenu chains, nested submenus opened on row hover). Constants quoted.
|
||
-- Scoped here because the chat menu is its only consumer; a second consumer graduates
|
||
-- it to its own file.
|
||
BENILLA_UIMENU_BUTTON_HEIGHT = 16
|
||
BENILLA_UIMENU_BUTTON_WIDTH = 104
|
||
BENILLA_UIMENU_BORDER_HEIGHT = 12
|
||
BENILLA_UIMENU_BORDER_WIDTH = 12
|
||
BENILLA_UIMENU_NUMBUTTONS = 32
|
||
BENILLA_UIMENU_TIMEOUT = 2.0
|
||
|
||
function BenillaUIMenu_Initialize(menu)
|
||
menu.numButtons = 0
|
||
menu.subMenu = ""
|
||
local name = menu:GetName()
|
||
for i = 1, BENILLA_UIMENU_NUMBUTTONS do
|
||
local button = getglobal(name .. "Button" .. i)
|
||
button:SetWidth(BENILLA_UIMENU_BUTTON_WIDTH)
|
||
button:SetHeight(BENILLA_UIMENU_BUTTON_HEIGHT)
|
||
button:Hide()
|
||
getglobal(button:GetName() .. "ShortcutText"):Hide()
|
||
end
|
||
menu:SetWidth(BENILLA_UIMENU_BUTTON_WIDTH + BENILLA_UIMENU_BORDER_WIDTH * 2)
|
||
menu:SetHeight(BENILLA_UIMENU_BORDER_HEIGHT * 2)
|
||
end
|
||
|
||
-- Rows past the button pool are dropped (the ref message()s; nothing we author overflows).
|
||
function BenillaUIMenu_AddButton(menu, text, shortcut, func, nested)
|
||
local id = menu.numButtons + 1
|
||
if id > BENILLA_UIMENU_NUMBUTTONS then return end
|
||
menu.numButtons = id
|
||
local button = getglobal(menu:GetName() .. "Button" .. id)
|
||
if text then button:SetText(text) end
|
||
button.func = func
|
||
button.nested = nested
|
||
button:Show()
|
||
if shortcut then
|
||
local s = getglobal(button:GetName() .. "ShortcutText")
|
||
s:SetText(shortcut)
|
||
s:Show()
|
||
end
|
||
menu:SetHeight(id * BENILLA_UIMENU_BUTTON_HEIGHT + BENILLA_UIMENU_BORDER_HEIGHT * 2)
|
||
end
|
||
|
||
function BenillaUIMenu_OnShow()
|
||
this.timeleft = BENILLA_UIMENU_TIMEOUT
|
||
this.counting = 1
|
||
end
|
||
|
||
function BenillaUIMenu_OnUpdate(elapsed)
|
||
if this.counting == 1 then
|
||
local timeleft = (this.timeleft or BENILLA_UIMENU_TIMEOUT) - elapsed
|
||
if timeleft <= 0 then
|
||
this:Hide()
|
||
return
|
||
end
|
||
this.timeleft = timeleft
|
||
end
|
||
end
|
||
|
||
function BenillaUIMenu_StartCounting(menu)
|
||
menu.counting = 1
|
||
if menu.parentMenu then BenillaUIMenu_StartCounting(getglobal(menu.parentMenu)) end
|
||
end
|
||
|
||
function BenillaUIMenu_StopCounting(menu)
|
||
menu.counting = 0
|
||
menu.timeleft = BENILLA_UIMENU_TIMEOUT
|
||
if menu.parentMenu then BenillaUIMenu_StopCounting(getglobal(menu.parentMenu)) end
|
||
end
|
||
|
||
function BenillaUIMenuButton_OnLoad()
|
||
this:SetPoint("TOP", this:GetParent():GetName(), "TOP", 0,
|
||
-((this:GetID() - 1) * BENILLA_UIMENU_BUTTON_HEIGHT) - BENILLA_UIMENU_BORDER_HEIGHT)
|
||
end
|
||
|
||
function BenillaUIMenuButton_OnClick()
|
||
if this.func then this.func() end
|
||
this:GetParent():Hide()
|
||
PlaySound("UChatScrollButton")
|
||
end
|
||
|
||
function BenillaUIMenuButton_OnEnter()
|
||
local nested = this.nested
|
||
if nested then
|
||
local menu = getglobal(nested)
|
||
if not menu:IsVisible() then
|
||
local oldMenu = getglobal(this:GetParent().subMenu or "")
|
||
if oldMenu then oldMenu:Hide() end
|
||
this:GetParent().subMenu = nested
|
||
menu:SetPoint("BOTTOMLEFT", this:GetName(), "BOTTOMRIGHT", 10, -12)
|
||
menu:Show()
|
||
end
|
||
BenillaUIMenu_StopCounting(menu)
|
||
else
|
||
BenillaUIMenu_StopCounting(this:GetParent())
|
||
end
|
||
end
|
||
|
||
function BenillaUIMenuButton_OnLeave()
|
||
BenillaUIMenu_StartCounting(this:GetParent())
|
||
if this.nested then BenillaUIMenu_StartCounting(getglobal(this.nested)) end
|
||
end
|
||
|
||
-- ── The chat menu rows (ref ChatMenu_* in ChatFrame.lua, adapted): every type row
|
||
-- prefixes the box with the type's slash and lets the LIVE PARSE convert — the ref's
|
||
-- own Whisper row does literally `SetText("/w "..GetText())`, and routing all rows the
|
||
-- same way means the menu can never drift from the slash grammar the edit machine
|
||
-- owns. Labels/shortcuts quoted from GlobalStrings. Language (benilla has no language
|
||
-- model yet) and Macro (no macro frame) are deliberately out; this OnLoad is their
|
||
-- return path.
|
||
function BenillaChatMenu_Type(prefix)
|
||
local eb = ChatFrameEditBox
|
||
eb:Show()
|
||
eb:SetFocus()
|
||
eb:SetText(prefix .. (eb:GetText() or ""))
|
||
end
|
||
|
||
function BenillaChatMenu_OnLoad()
|
||
BenillaUIMenu_Initialize(this)
|
||
BenillaUIMenu_AddButton(this, "Say", "/s", function() BenillaChatMenu_Type("/s ") end)
|
||
BenillaUIMenu_AddButton(this, "Party Chat", "/p", function() BenillaChatMenu_Type("/p ") end)
|
||
BenillaUIMenu_AddButton(this, "Guild Chat", "/g", function() BenillaChatMenu_Type("/g ") end)
|
||
BenillaUIMenu_AddButton(this, "Yell", "/y", function() BenillaChatMenu_Type("/y ") end)
|
||
BenillaUIMenu_AddButton(this, "Whisper", "/w", function() BenillaChatMenu_Type("/w ") end)
|
||
BenillaUIMenu_AddButton(this, "Emote", "/e", function() BenillaChatMenu_Type("/e ") end, "EmoteMenu")
|
||
BenillaUIMenu_AddButton(this, "Reply", "/r", function() BenillaChatMenu_Type("/r ") end)
|
||
BenillaUIMenu_AddButton(this, "Voice Emote", nil, nil, "VoiceMacroMenu")
|
||
end
|
||
|
||
-- An emote row submits its /command through the REAL chat pipeline (SubmitChatInput →
|
||
-- the router's EmotesText resolve + the send-side posture gate) — the ref's DoEmote by
|
||
-- token, reached through our one grammar. The lists are the ref's EmoteList /
|
||
-- TextEmoteSpeechList tokens as OUR canonical /commands (the EmotesText names the typed
|
||
-- grammar resolves), CMD1-sorted like the ref menu. Three ref labels differ
|
||
-- (/attacktarget /followme /silly are GlobalStrings CMD aliases the typed grammar
|
||
-- doesn't carry yet) — each row shows the command it actually runs.
|
||
BenillaEmoteMenuList = {
|
||
"/applaud", "/beg", "/bow", "/chicken", "/cry", "/dance", "/eat", "/flex",
|
||
"/kiss", "/kneel", "/laugh", "/point", "/roar", "/rude", "/salute", "/shy",
|
||
"/sit", "/sleep", "/stand", "/talk", "/wave",
|
||
}
|
||
BenillaVoiceMacroList = {
|
||
"/attackmytarget", "/bye", "/charge", "/cheer", "/congratulate", "/flee",
|
||
"/flirt", "/follow", "/healme", "/hello", "/helpme", "/incoming", "/joke",
|
||
"/no", "/nod", "/oom", "/openfire", "/rasp", "/thank", "/train", "/wait",
|
||
"/welcome",
|
||
}
|
||
|
||
function BenillaEmoteMenu_Click(cmd)
|
||
SubmitChatInput(cmd)
|
||
ChatMenu:Hide()
|
||
end
|
||
|
||
function BenillaOnEmoteMenuLoad(list)
|
||
BenillaUIMenu_Initialize(this)
|
||
this.parentMenu = "ChatMenu"
|
||
for _, cmd in ipairs(list) do
|
||
local c = cmd
|
||
BenillaUIMenu_AddButton(this, cmd, nil, function() BenillaEmoteMenu_Click(c) end)
|
||
end
|
||
end
|
||
]]></Script>
|
||
|
||
<!-- ── The dock: ChatFrame1 (General) + ChatFrame2 (Combat Log) sharing its rect ─────── -->
|
||
<!--
|
||
ChatFrame1: 430×120 at BOTTOMLEFT (32, 85) — the managed-position base
|
||
(UIPARENT_MANAGED_FRAME_POSITIONS["ChatFrame1"]: baseY 85 + the bottom-stack offsets,
|
||
applied by UIParent_ManageFramePositions per decision 0272); displayDuration 120 /
|
||
maxLines 128 (ref ChatFrameTemplate). The background stretches -2/+2 x and +3/-6 y past
|
||
the frame (ref $parentBackground anchors), the 8 border slices ring it (the ref draws
|
||
them through its resize buttons' textures; benilla authors them as plain textures — the
|
||
hover LOOK without the resize mechanics). Everything starts alpha 0; BenillaFCF fades.
|
||
-->
|
||
<ScrollingMessageFrame name="ChatFrame1" frameStrata="BACKGROUND" displayDuration="120.0" maxLines="128">
|
||
<Size><AbsDimension x="430" y="120"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT">
|
||
<Offset><AbsDimension x="32" y="85"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentBackground" file="Interface\ChatFrame\ChatFrameBackground" alpha="0">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-2" y="3"/></Offset></Anchor>
|
||
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="2" y="-6"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
<!-- The ChatFrameBorder ring (ref ChatFrameBorder slices; texcoords quoted from
|
||
the ref resize buttons). Corners 16×16, edges stretched between them. -->
|
||
<Texture name="$parentBorderTopLeft" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentBackground"><Offset><AbsDimension x="-2" y="2"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0" right="0.25" top="0" bottom="0.125"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderTopRight" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="TOPRIGHT" relativeTo="$parentBackground"><Offset><AbsDimension x="2" y="2"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0.75" right="1.0" top="0" bottom="0.125"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderBottomLeft" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativeTo="$parentBackground"><Offset><AbsDimension x="-2" y="-3"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0" right="0.25" top="0.7265625" bottom="0.8515625"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderBottomRight" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativeTo="$parentBackground"><Offset><AbsDimension x="2" y="-3"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0.75" right="1.0" top="0.7265625" bottom="0.8515625"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderTop" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentBorderTopLeft" relativePoint="RIGHT"/>
|
||
<Anchor point="RIGHT" relativeTo="$parentBorderTopRight" relativePoint="LEFT"/>
|
||
</Anchors>
|
||
<TexCoords left="0.25" right="0.75" top="0" bottom="0.125"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderBottom" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentBorderBottomLeft" relativePoint="RIGHT"/>
|
||
<Anchor point="RIGHT" relativeTo="$parentBorderBottomRight" relativePoint="LEFT"/>
|
||
</Anchors>
|
||
<TexCoords left="0.25" right="0.75" top="0.7265625" bottom="0.8515625"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderLeft" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOP" relativeTo="$parentBorderTopLeft" relativePoint="BOTTOM"/>
|
||
<Anchor point="BOTTOM" relativeTo="$parentBorderBottomLeft" relativePoint="TOP"/>
|
||
</Anchors>
|
||
<TexCoords left="0" right="0.25" top="0.125" bottom="0.7265625"/>
|
||
</Texture>
|
||
<Texture name="$parentBorderRight" file="Interface\ChatFrame\ChatFrameBorder" alpha="0">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOP" relativeTo="$parentBorderTopRight" relativePoint="BOTTOM"/>
|
||
<Anchor point="BOTTOM" relativeTo="$parentBorderBottomRight" relativePoint="TOP"/>
|
||
</Anchors>
|
||
<TexCoords left="0.75" right="1.0" top="0.125" bottom="0.7265625"/>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- The scroll column, outside bottom-left (ref: BottomButton at (-32,-4), Down and
|
||
Up stacked above it, 2px overlaps). Sounds + hold-repeat per the ref scripts. -->
|
||
<Button name="$parentBottomButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-32" y="-4"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentFlash" file="Interface\ChatFrame\UI-ChatIcon-BlinkHilight" hidden="true" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnClick>
|
||
PlaySound("igChatBottom")
|
||
getglobal("ChatFrame" .. BenillaFCF.selected):ScrollToBottom()
|
||
</OnClick>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Up"/>
|
||
<PushedTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Down"/>
|
||
<DisabledTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollEnd-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
<Button name="$parentDownButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOM" relativeTo="$parentBottomButton" relativePoint="TOP"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Scripts>
|
||
<OnLoad>
|
||
this:RegisterForClicks("LeftButtonDown", "LeftButtonUp")
|
||
</OnLoad>
|
||
<OnClick>
|
||
BenillaChatScrollButton_OnClick(this, arg2, "down", "igChatScrollDown")
|
||
</OnClick>
|
||
<OnUpdate>
|
||
BenillaChatScrollButton_OnUpdate(this, arg1, "down")
|
||
</OnUpdate>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Up"/>
|
||
<PushedTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Down"/>
|
||
<DisabledTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollDown-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
<Button name="$parentUpButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOM" relativeTo="$parentDownButton" relativePoint="TOP"/>
|
||
</Anchors>
|
||
<Scripts>
|
||
<OnLoad>
|
||
this:RegisterForClicks("LeftButtonDown", "LeftButtonUp")
|
||
</OnLoad>
|
||
<OnClick>
|
||
BenillaChatScrollButton_OnClick(this, arg2, "up", "igChatScrollUp")
|
||
</OnClick>
|
||
<OnUpdate>
|
||
BenillaChatScrollButton_OnUpdate(this, arg1, "up")
|
||
</OnUpdate>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollUp-Up"/>
|
||
<PushedTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollUp-Down"/>
|
||
<DisabledTexture file="Interface\ChatFrame\UI-ChatIcon-ScrollUp-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnUpdate>
|
||
BenillaFCF_OnUpdate(arg1)
|
||
BenillaChatFrame_OnUpdate(this, arg1)
|
||
</OnUpdate>
|
||
<OnMouseWheel>
|
||
-- WoW wheel convention: +1 per notch up, -1 down. Up = older messages.
|
||
if arg1 > 0 then this:ScrollUp() else this:ScrollDown() end
|
||
</OnMouseWheel>
|
||
<OnHyperlinkClick>
|
||
SetItemRef(arg1, arg2, arg3)
|
||
</OnHyperlinkClick>
|
||
</Scripts>
|
||
<FontString inherits="ChatFontNormal" justifyH="LEFT"/>
|
||
</ScrollingMessageFrame>
|
||
|
||
<!-- ChatFrame2 "Combat Log": docked — shares ChatFrame1's rect (ref FCF_DockUpdate anchors),
|
||
hidden until its tab selects it. Its message-group wiring (the chat-cache combat set)
|
||
lands with the router (0288 P4); until then it renders what it's given: nothing. -->
|
||
<ScrollingMessageFrame name="ChatFrame2" frameStrata="BACKGROUND" displayDuration="120.0" maxLines="128" hidden="true">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativeTo="ChatFrame1" relativePoint="TOPLEFT"/>
|
||
<Anchor point="BOTTOMRIGHT" relativeTo="ChatFrame1" relativePoint="BOTTOMRIGHT"/>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentBackground" file="Interface\ChatFrame\ChatFrameBackground" alpha="0">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-2" y="3"/></Offset></Anchor>
|
||
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="2" y="-6"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnMouseWheel>
|
||
if arg1 > 0 then this:ScrollUp() else this:ScrollDown() end
|
||
</OnMouseWheel>
|
||
<OnHyperlinkClick>
|
||
SetItemRef(arg1, arg2, arg3)
|
||
</OnHyperlinkClick>
|
||
</Scripts>
|
||
<FontString inherits="ChatFontNormal" justifyH="LEFT"/>
|
||
</ScrollingMessageFrame>
|
||
|
||
<!-- ── The tabs (ref ChatTabTemplate: 64×32, ChatFrameTab 3-slice quarters 16/44/16, label
|
||
at the left slice's right edge y −5, GameFontNormalSmall; the flash band at y −7; the
|
||
ref's ButtonText also carries a vestigial 50×8 Size that TabResize immediately
|
||
shrink-wraps — omitted). The middle slice hugs the label live (BenillaFCF_TabResize —
|
||
the ref's PanelTemplates_TabResize(5, tab) from FCF_DockUpdate). Hidden by alpha
|
||
(hover reveals).
|
||
|
||
ChatFrame2Tab ("Combat Log") is deliberately NOT built: the combat log renders nothing
|
||
real yet (window 2 gets its chat-cache groups from the router, but the combat-event →
|
||
line pipeline doesn't exist), so the tab just selected an empty window. ChatFrame2
|
||
itself stays above (the router keeps feeding it) so the tab can return whole with the
|
||
combat-log arc — director's call, 2026-07-11. The FCF loops guard the missing tab. ── -->
|
||
<Button name="ChatFrame1Tab" frameStrata="LOW" alpha="0">
|
||
<Size><AbsDimension x="70" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOMLEFT" relativeTo="ChatFrame1Background" relativePoint="TOPLEFT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentLeft" file="Interface\ChatFrame\ChatFrameTab">
|
||
<Size><AbsDimension x="16" y="32"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
<TexCoords left="0.0" right="0.25" top="0.0" bottom="1.0"/>
|
||
</Texture>
|
||
<Texture name="$parentMiddle" file="Interface\ChatFrame\ChatFrameTab">
|
||
<Size><AbsDimension x="38" y="32"/></Size>
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"/></Anchors>
|
||
<TexCoords left="0.25" right="0.75" top="0.0" bottom="1.0"/>
|
||
</Texture>
|
||
<Texture name="$parentRight" file="Interface\ChatFrame\ChatFrameTab">
|
||
<Size><AbsDimension x="16" y="32"/></Size>
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentMiddle" relativePoint="RIGHT"/></Anchors>
|
||
<TexCoords left="0.75" right="1.0" top="0.0" bottom="1.0"/>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<Frame name="$parentFlash" hidden="true">
|
||
<Size><AbsDimension x="5" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentLeft"><Offset><AbsDimension x="0" y="-7"/></Offset></Anchor>
|
||
<Anchor point="RIGHT" relativeTo="$parentRight"><Offset><AbsDimension x="0" y="-7"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture file="Interface\PaperDollInfoFrame\UI-Character-Tab-Highlight" alphaMode="ADD" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnClick>
|
||
BenillaFCF_TabClick(1)
|
||
</OnClick>
|
||
</Scripts>
|
||
<ButtonText name="$parentText" text="General">
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor>
|
||
</Anchors>
|
||
</ButtonText>
|
||
<NormalFont inherits="GameFontNormalSmall"/>
|
||
<!-- The ref leaves this texture unsized and leans on the BLP's NATURAL height (32) to
|
||
seat the glow at the anchors' y −7 — centered on the tab's visible body, which sits
|
||
in the BOTTOM 22 rows of the ChatFrameTab canvas. benilla's v1 region model has no
|
||
natural-size law (an unpinned axis inherits the owner's edges, decision 0068), which
|
||
parked the glow 7 units high; the explicit height states what the ref reads from the
|
||
file. -->
|
||
<HighlightTexture file="Interface\PaperDollInfoFrame\UI-Character-Tab-Highlight" alphaMode="ADD">
|
||
<Size><AbsDimension x="0" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentLeft"><Offset><AbsDimension x="0" y="-7"/></Offset></Anchor>
|
||
<Anchor point="RIGHT" relativeTo="$parentRight"><Offset><AbsDimension x="0" y="-7"/></Offset></Anchor>
|
||
</Anchors>
|
||
</HighlightTexture>
|
||
</Button>
|
||
|
||
<!-- ── The UIMenu kit (ref UIMenu.xml, names kept for the addon surface): a row button
|
||
with a right-aligned shortcut string, and the tooltip-backdrop menu holding the ref's
|
||
fixed pool of 32 rows (hidden until AddButton). The label is authored LEFT-anchored:
|
||
the ref leans on the 1.12 ButtonText default rect spanning the button, which our lazy
|
||
label slot doesn't reproduce. ─────────────────────────────────────────────────── -->
|
||
<Button name="UIMenuButtonTemplate" virtual="true">
|
||
<Size><AbsDimension x="128" y="16"/></Size>
|
||
<Scripts>
|
||
<OnLoad>
|
||
BenillaUIMenuButton_OnLoad()
|
||
</OnLoad>
|
||
<OnClick>
|
||
BenillaUIMenuButton_OnClick()
|
||
</OnClick>
|
||
<OnEnter>
|
||
BenillaUIMenuButton_OnEnter()
|
||
</OnEnter>
|
||
<OnLeave>
|
||
BenillaUIMenuButton_OnLeave()
|
||
</OnLeave>
|
||
</Scripts>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="$parentShortcutText" inherits="GameFontHighlight" hidden="true">
|
||
<Anchors><Anchor point="RIGHT"/></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<ButtonText name="$parentText">
|
||
<Anchors><Anchor point="LEFT"/></Anchors>
|
||
</ButtonText>
|
||
<NormalFont inherits="GameFontNormal" justifyH="LEFT"/>
|
||
<HighlightFont inherits="GameFontHighlight" justifyH="LEFT"/>
|
||
<DisabledFont inherits="GameFontDisable" justifyH="LEFT"/>
|
||
</Button>
|
||
<Frame name="UIMenuTemplate" frameStrata="DIALOG" virtual="true">
|
||
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
|
||
<BackgroundInsets><AbsInset left="4" right="4" top="4" bottom="4"/></BackgroundInsets>
|
||
<TileSize><AbsValue val="32"/></TileSize>
|
||
<EdgeSize><AbsValue val="13"/></EdgeSize>
|
||
</Backdrop>
|
||
<Frames>
|
||
<Button name="$parentButton1" inherits="UIMenuButtonTemplate" id="1"/>
|
||
<Button name="$parentButton2" inherits="UIMenuButtonTemplate" id="2"/>
|
||
<Button name="$parentButton3" inherits="UIMenuButtonTemplate" id="3"/>
|
||
<Button name="$parentButton4" inherits="UIMenuButtonTemplate" id="4"/>
|
||
<Button name="$parentButton5" inherits="UIMenuButtonTemplate" id="5"/>
|
||
<Button name="$parentButton6" inherits="UIMenuButtonTemplate" id="6"/>
|
||
<Button name="$parentButton7" inherits="UIMenuButtonTemplate" id="7"/>
|
||
<Button name="$parentButton8" inherits="UIMenuButtonTemplate" id="8"/>
|
||
<Button name="$parentButton9" inherits="UIMenuButtonTemplate" id="9"/>
|
||
<Button name="$parentButton10" inherits="UIMenuButtonTemplate" id="10"/>
|
||
<Button name="$parentButton11" inherits="UIMenuButtonTemplate" id="11"/>
|
||
<Button name="$parentButton12" inherits="UIMenuButtonTemplate" id="12"/>
|
||
<Button name="$parentButton13" inherits="UIMenuButtonTemplate" id="13"/>
|
||
<Button name="$parentButton14" inherits="UIMenuButtonTemplate" id="14"/>
|
||
<Button name="$parentButton15" inherits="UIMenuButtonTemplate" id="15"/>
|
||
<Button name="$parentButton16" inherits="UIMenuButtonTemplate" id="16"/>
|
||
<Button name="$parentButton17" inherits="UIMenuButtonTemplate" id="17"/>
|
||
<Button name="$parentButton18" inherits="UIMenuButtonTemplate" id="18"/>
|
||
<Button name="$parentButton19" inherits="UIMenuButtonTemplate" id="19"/>
|
||
<Button name="$parentButton20" inherits="UIMenuButtonTemplate" id="20"/>
|
||
<Button name="$parentButton21" inherits="UIMenuButtonTemplate" id="21"/>
|
||
<Button name="$parentButton22" inherits="UIMenuButtonTemplate" id="22"/>
|
||
<Button name="$parentButton23" inherits="UIMenuButtonTemplate" id="23"/>
|
||
<Button name="$parentButton24" inherits="UIMenuButtonTemplate" id="24"/>
|
||
<Button name="$parentButton25" inherits="UIMenuButtonTemplate" id="25"/>
|
||
<Button name="$parentButton26" inherits="UIMenuButtonTemplate" id="26"/>
|
||
<Button name="$parentButton27" inherits="UIMenuButtonTemplate" id="27"/>
|
||
<Button name="$parentButton28" inherits="UIMenuButtonTemplate" id="28"/>
|
||
<Button name="$parentButton29" inherits="UIMenuButtonTemplate" id="29"/>
|
||
<Button name="$parentButton30" inherits="UIMenuButtonTemplate" id="30"/>
|
||
<Button name="$parentButton31" inherits="UIMenuButtonTemplate" id="31"/>
|
||
<Button name="$parentButton32" inherits="UIMenuButtonTemplate" id="32"/>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnShow>
|
||
BenillaUIMenu_OnShow()
|
||
PlaySound("UChatScrollButton")
|
||
this:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
|
||
this:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
|
||
</OnShow>
|
||
<OnUpdate>
|
||
BenillaUIMenu_OnUpdate(arg1)
|
||
</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- ── The chat menu button (ref ChatFrameMenuButton): the bubble icon atop the scroll
|
||
column; click opens ChatMenu (ref ChatFrame_OpenMenu). ──────────────────────────── -->
|
||
<Button name="ChatFrameMenuButton" frameStrata="LOW">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="BOTTOM" relativeTo="ChatFrame1UpButton" relativePoint="TOP"/>
|
||
</Anchors>
|
||
<Scripts>
|
||
<OnClick>
|
||
PlaySound("igChatEmoteButton")
|
||
ChatMenu:Show()
|
||
</OnClick>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Up"/>
|
||
<PushedTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Down"/>
|
||
<DisabledTexture file="Interface\ChatFrame\UI-ChatIcon-Chat-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
|
||
<!-- ChatMenu + its two nested menus (ref FloatingChatFrame.xml; the ref's own OnShow
|
||
hides only EmoteMenu — hiding both submenus is the same intent without the ref's
|
||
Voice-menu-left-open corner). The submenus are authored as children (the ref's
|
||
parent="ChatMenu" attr — this engine attaches by nesting, CharacterFrame.xml's note),
|
||
so hiding ChatMenu hides them with it. -->
|
||
<Frame name="ChatMenu" inherits="UIMenuTemplate" hidden="true">
|
||
<Anchors>
|
||
<Anchor point="BOTTOMLEFT" relativeTo="ChatFrameMenuButton" relativePoint="TOPRIGHT"/>
|
||
</Anchors>
|
||
<Frames>
|
||
<Frame name="EmoteMenu" inherits="UIMenuTemplate" hidden="true">
|
||
<Scripts>
|
||
<OnLoad>
|
||
BenillaOnEmoteMenuLoad(BenillaEmoteMenuList)
|
||
</OnLoad>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="VoiceMacroMenu" inherits="UIMenuTemplate" hidden="true">
|
||
<Scripts>
|
||
<OnLoad>
|
||
BenillaOnEmoteMenuLoad(BenillaVoiceMacroList)
|
||
</OnLoad>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>
|
||
BenillaChatMenu_OnLoad()
|
||
</OnLoad>
|
||
<OnShow>
|
||
BenillaUIMenu_OnShow()
|
||
EmoteMenu:Hide()
|
||
VoiceMacroMenu:Hide()
|
||
this:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
|
||
this:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
|
||
</OnShow>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- ── The edit box (ref ChatFrameEditBox): below ChatFrame1, -5/+5 wide, 32 tall, DIALOG
|
||
strata, hidden until ENTER opens it (ui_chat::input). The three-piece
|
||
UI-ChatInputBorder art; the header ("Say:" until the P5 edit machine drives it) at
|
||
LEFT+13; typed text starts past it (static insets, P5 makes them live). ─────────── -->
|
||
<!-- The ref template ships ignoreArrows="true": plain arrows fall through to CHARACTER
|
||
MOVEMENT while typing (Ctrl bypasses), because 1.12 lets you keep arrow-steering with
|
||
the box open. benilla has no typing-while-moving arrow scheme, so the attr would leave
|
||
the keys dead; the director's call is the modern law — plain arrows move the caret,
|
||
Up/Down recall history (decision 0301). The engine still honors the attr faithfully
|
||
for any box that sets it. -->
|
||
<!-- historyLines: the ref template ships 32; 64 at the director's call ("at least 50",
|
||
2026-07-26) — the recall walk is the modern law already (decision 0301). -->
|
||
<EditBox name="ChatFrameEditBox" frameStrata="DIALOG" hidden="true" historyLines="64" letters="255">
|
||
<Size><AbsDimension x="0" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativeTo="ChatFrame1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-5" y="-2"/></Offset></Anchor>
|
||
<Anchor point="TOPRIGHT" relativeTo="ChatFrame1" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="5" y="-2"/></Offset></Anchor>
|
||
</Anchors>
|
||
<TextInsets><AbsInset left="47" right="13" top="0" bottom="0"/></TextInsets>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentLeft" file="Interface\ChatFrame\UI-ChatInputBorder-Left">
|
||
<Size><AbsDimension x="256" y="32"/></Size>
|
||
<Anchors><Anchor point="LEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="$parentRight" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
|
||
<Size><AbsDimension x="16" y="32"/></Size>
|
||
<Anchors><Anchor point="RIGHT"/></Anchors>
|
||
<TexCoords left="0.9375" right="1.0" top="0" bottom="1.0"/>
|
||
</Texture>
|
||
<Texture name="$parentMid" file="Interface\ChatFrame\UI-ChatInputBorder-Right">
|
||
<Size><AbsDimension x="1" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="$parentLeft" relativePoint="RIGHT"/>
|
||
<Anchor point="RIGHT" relativeTo="$parentRight" relativePoint="LEFT"/>
|
||
</Anchors>
|
||
<TexCoords left="0" right="0.9375" top="0" bottom="1.0"/>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="$parentHeader" inherits="ChatFontNormal" text="Say:">
|
||
<Anchors>
|
||
<Anchor point="LEFT"><Offset><AbsDimension x="13" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnterPressed>
|
||
SubmitChatInput(this:GetText())
|
||
this:SetText("")
|
||
this:ClearFocus()
|
||
this:Hide()
|
||
</OnEnterPressed>
|
||
<OnEscapePressed>
|
||
this:SetText("")
|
||
this:ClearFocus()
|
||
this:Hide()
|
||
</OnEscapePressed>
|
||
<OnTabPressed>
|
||
BenillaChatTabPressed()
|
||
</OnTabPressed>
|
||
</Scripts>
|
||
<FontString inherits="ChatFontNormal" justifyH="LEFT"/>
|
||
</EditBox>
|
||
|
||
<!-- The load-order hack, like the ref's own trailing FCF_DockFrame(ChatFrame1, 1): select
|
||
the General tab once everything above exists — and tint the window chrome BLACK
|
||
(FCF_SetWindowColor: the ref vertex-colors every CHAT_FRAME_TEXTURES piece with the
|
||
chat-cache window COLOR, which ships 0 0 0; the ChatFrameBackground art itself is
|
||
white, so untinted it reads as a white wash over the world). -->
|
||
<Script><![CDATA[
|
||
BenillaFCF_SelectDock(1)
|
||
for i = 1, 2 do
|
||
for _, t in ipairs(BenillaFCF_Textures(i)) do
|
||
t:SetVertexColor(0, 0, 0)
|
||
end
|
||
end
|
||
]]></Script>
|
||
</Ui>
|