Files
benilla-octo/crates/benilla/assets/ui/ChatFrame.xml
T
SamandClaude Fable 5 2ad0043523 benilla: initial public release
A from-scratch World of Warcraft 1.12.1 client in Rust + Bevy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:27:01 +07:00

555 lines
30 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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
]]></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"/>
<HighlightTexture file="Interface\PaperDollInfoFrame\UI-Character-Tab-Highlight" alphaMode="ADD">
<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 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. -->
<EditBox name="ChatFrameEditBox" frameStrata="DIALOG" hidden="true" historyLines="32" 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>