Files
benilla-octo/crates/benilla-app/assets/ui/OptionsFrame.xml
T
pkuzicandClaude Opus 5.5 6bf7c409a2 MONKEY (integration): merge graphics-programme-presets
Graphics Preset ladder + Render Distance (farclip ceiling 1497). Conflict in
options_tests: the Advanced page now has 33 rows (preset + render distance lead,
then the 31 programme rows). The three round-3 rows join the ladder:
ambientOcclusion 0/0/1/2/2, zoneSkyboxes 0/0/1/1/1, lampFog 0/0/1/2/2
(Classic/Low/Medium/High/Ultra); the preset tooltip names them (EN+RU).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:52:52 +01:00

4431 lines
328 KiB
XML

<Ui>
<!--
The Options window, opened from the game menu. Deviation: the 1.15 era client's single
settings window replaces the 1.12 four-panel family, which is much worse to use; the 1.12
frames still load, hidden, for addons.
Structure follows the era UI source (1.15.9), surfaces the 1.14 System window
(OptionsFrameTemplates.xml); every art byte is 1.12-native or a colour fill, so era atlas
names below cite geometry only. Cut from the era window: the corner close X, live tabs,
the Accessibility, Languages and Network pages, and the close-with-pending confirm and
revert timer, so hiding discards pending edits and Apply commits outright. A slider shows
the 1.12 range; an out-of-range config value displays clamped and is not written back.
-->
<!-- The era GameFontHighlightMedium/Huge (FRIZQT 14 and 20, white) under Options* names, so
Fonts.xml stays the 1.12 set; the shadow is MasterFont's (Fonts.xml l.62). -->
<Font name="OptionsFontHighlightMedium" font="Fonts\FRIZQT__.TTF" virtual="true">
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0" g="0" b="0"/>
</Shadow>
<FontHeight><AbsValue val="14"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="OptionsFontHighlightHuge" font="Fonts\FRIZQT__.TTF" virtual="true">
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0" g="0" b="0"/>
</Shadow>
<FontHeight><AbsValue val="20"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Script><![CDATA[
-- The stock UIOptionsFrame.xml loads hidden before this file and owns the options uvars
-- (UIOptionsFrame_Init, UIOptionsFrame.lua l.93-185) and UIOptionsFrameCheckButtons;
-- each uvar row captures its default at OnLoad, after that file ran.
-- Deviation: AUTO_QUEST_WATCH is the string "1". 1.12 assigns the number 1 (l.122) but
-- every consumer compares against "1" (QuestLogFrame.lua:64/68), and 1 ~= "1" in Lua 5.0.
-- The RegisterForSave repeats the stock one, which is idempotent.
AUTO_QUEST_WATCH = "1"
RegisterForSave("AUTO_QUEST_WATCH")
-- Every combat-text row's applyFunc, UIOptionsFrame_Save l.371-376: Blizzard_CombatText
-- is LoadOnDemand, so the master loads it, and the update runs only once it exists.
function CombatText_UpdateOrLoad()
if ( SHOW_COMBAT_TEXT == "1" ) then
UIParentLoadAddOn("Blizzard_CombatText")
end
if ( CombatText_UpdateDisplayedMessages ) then
CombatText_UpdateDisplayedMessages()
end
end
-- The Remove Chat Hover Delay row's applyFunc (UIOptionsFrame.lua l.216).
function ChatFrame_ApplyMouseOverDelay()
if SetChatMouseOverDelay then -- nil in a VM loaded without the chat files
SetChatMouseOverDelay(REMOVE_CHAT_DELAY)
end
end
-- Show Tutorials' setter (UIOptionsFrame.lua l.318-327). There is no tutorial CVar: the
-- store is the _Load/_Save/_SetDefaults special arms, and disabling marks the whole bank.
-- The `~=` guard is the reference's: TutorialsEnabled() is 1 or nil, and re-ticking an
-- on row must not ResetTutorials() and re-arm dismissed tutorials.
function BenillaOptionsFrame_SetTutorialsEnabled(value)
if ( tonumber(value) ~= TutorialsEnabled() ) then
if ( value == "1" ) then
ResetTutorials()
TutorialFrameCheckButton:SetChecked(1)
else
ClearTutorials()
end
TutorialFrame_HideAllAlerts()
end
end
-- UpdateNameplates, over the stock UIOptionsFrame.lua l.768-780. Deviation: stock l.776
-- is dropped. Stock l.774-776 shows then hides the friendly plates; on 1.12 that clears
-- volatile bits (`[0xc4da34]`), but here the verbs write the CVar pair that is the store,
-- so it would erase the saved setting at every world entry. The body stays for addons
-- that set NAMEPLATES_ON and call this.
function UpdateNameplates()
if ( NAMEPLATES_ON ) then
ShowNameplates()
else
HideNameplates()
end
if ( FRIENDNAMEPLATES_ON ) then
ShowFriendNameplates()
else
HideFriendNameplates()
end
end
-- The static category tree (era Game tab, Classic tocs), in list order. Keys are the row
-- name suffixes; the visible label doubles as the page title (the era does the same —
-- Settings.RegisterCategory names both from one string).
-- MONKEY (advanced graphics): "AdvancedGraphics" joins the System group under Graphics —
-- the seat the era's own tree gives a page that refines the one above it, and the seat
-- that keeps the three shadow rows it inherits one row away from where they used to be.
OPTIONS_CATEGORY_KEYS = {
"Controls", "Interface", "ActionBars", "Combat", "Chat", "Keybindings", "Nameplates",
"Graphics", "AdvancedGraphics", "Audio",
}
-- The era-window scale: the era UIParent draws smaller than our 768-unit canvas on modern
-- screens, and every era-shaped window wears this (GameMenuFrame too). Set by eye.
ERA_WINDOW_SCALE = 0.78
function BenillaOptionsFrame_UpdateScale()
-- The era panel's checkFit = 1: UIPanelUpdateScaleForFit also shrinks it to fit.
local k = ERA_WINDOW_SCALE
local wFit = GetScreenWidth() / 940
local hFit = GetScreenHeight() / 744
if wFit < k then k = wFit end
if hFit < k then k = hFit end
BenillaOptionsFrame:SetScale(k)
end
-- The era tab width (MinimalTab.lua l.7): label width + 40, measured in the tabs' OnShow
-- as 1.12's PanelTemplates_TabResize is, since it depends on the scale the window's
-- OnShow sets first. Deviation: the era measures the medium font it swaps away (about 6
-- wider); this measures the small font the label wears.
function OptionsTab_FitWidth(tab)
tab:SetWidth(getglobal(tab:GetName() .. "Text"):GetStringWidth() + 40)
end
-- A category row: the wash at the era atlas size (187x21), in the 1.14 hover steel-blue
-- (OptionsFrameTemplates.lua l.130-131). A new category is one XML row plus one key.
function OptionsCategoryRow_OnLoad(row, key, label)
row.categoryKey = key
row.pageTitle = label
row:SetText(label)
local bg = getglobal(row:GetName() .. "Bg")
bg:SetWidth(187)
bg:SetHeight(21)
bg:SetVertexColor(0.196, 0.388, 0.8)
end
-- Select a category: 1.14's OptionsList_SelectButton (OptionsFrameTemplates.lua
-- l.107-121), the selected wash gold and locked, the rest blue. Picking a category ends a
-- search (Blizzard_SettingsPanel.lua l.793); SetText("") re-enters here through the
-- restore, so the outer call returns early.
function BenillaOptionsFrame_SelectCategory(key)
BenillaOptionsFrame.selectedCategory = key
if BenillaOptionsFrameSearchBox:GetText() ~= "" then
BenillaOptionsFrameSearchBox:SetText("")
return -- the restore re-entered with this key and finished
end
for _, k in ipairs(OPTIONS_CATEGORY_KEYS) do
local row = getglobal("BenillaOptionsFrameCategoryListRow" .. k)
local bg = getglobal("BenillaOptionsFrameCategoryListRow" .. k .. "Bg")
if k == key then
bg:SetVertexColor(1, 1, 0)
bg:Show()
row:SetTextFontObject("GameFontHighlight")
BenillaOptionsFrameContainerTitle:SetText(row.pageTitle)
else
bg:SetVertexColor(0.196, 0.388, 0.8)
bg:Hide()
row:SetTextFontObject("GameFontNormal")
end
end
for k in pairs(OPTIONS_PAGE_ROWS) do
local body = getglobal("BenillaOptionsFrameContainerBody" .. k)
if k == key then body:Show() else body:Hide() end
end
-- A category switch starts at the top, as the era ScrollBox does per category.
BenillaOptionsFrameContainerScroll:SetVerticalScroll(0)
-- Keybindings: entering rebuilds the section tree; leaving disarms a pending capture,
-- which must never outlive the page.
local kb = getglobal("BenillaOptionsFrameContainerBodyKeybindings")
if key == "Keybindings" then
kb:Show()
KeyBindingsPage_Refresh()
BenillaOptionsFrameContainerUnbind:Show()
BenillaOptionsFrameContainerDefaults:Enable()
else
kb:Hide()
KeyBindings_SetSelected(nil)
KeyBindings_Output("")
BenillaOptionsFrameContainerUnbind:Hide()
if OPTIONS_PAGE_ROWS[key] then
OptionsPage_Refresh(key)
BenillaOptionsFrameContainerDefaults:Enable()
else
BenillaOptionsFrameContainerDefaults:Disable()
end
end
end
-- ── Search: the era SettingsPanel search (Blizzard_SettingsPanel.lua l.566-692) ──
-- A row's tag is its label uppercased; a query matches by plain substring, scored by
-- matched length, grouped under clickable category heads in best-score order. Results
-- are the live row frames re-anchored, so values and writes work mid-search.
-- The era word list (l.569-572): the whole query, then each comma- or space-separated word.
function OptionsSearch_Words(text)
local up = string.upper(text)
local words = { up }
for w in string.gfind(up, "([^, ]+)") do
table.insert(words, w)
end
return words
end
-- The era score (MatchesSearchTags, Blizzard_Settings.lua l.65-77), with a plain find.
function OptionsSearch_Score(tag, words)
for _, w in ipairs(words) do
local first, last = string.find(tag, w, 1, true)
if first then return last - first end
end
return nil
end
-- The era gather (l.575-636): scores walked high to low give the groups' order.
function OptionsSearch_FindMatches(text)
local words = OptionsSearch_Words(text)
local buckets, scores = {}, {}
for _, key in ipairs(OPTIONS_CATEGORY_KEYS) do
if OPTIONS_PAGE_ROWS[key] then
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
local row = getglobal("BenillaOptionsFrameContainerBody" .. key .. rkey)
local s = OptionsSearch_Score(row.searchTag, words)
if s then
if not buckets[s] then
buckets[s] = {}
table.insert(scores, s)
end
table.insert(buckets[s], { key = key, rkey = rkey })
end
end
end
end
-- Keybinding matches join the buckets, as in the era; their rkey is the binding index.
for _, m in ipairs(KeyBindings_SearchMatches(words)) do
if not buckets[m.score] then
buckets[m.score] = {}
table.insert(scores, m.score)
end
table.insert(buckets[m.score], { key = "Keybindings", rkey = m.index })
end
table.sort(scores, function(a, b) return a > b end)
local groups, order = {}, {}
for _, s in ipairs(scores) do
for _, m in ipairs(buckets[s]) do
if not groups[m.key] then
groups[m.key] = {}
table.insert(order, m.key)
end
table.insert(groups[m.key], m.rkey)
end
end
return order, groups
end
-- ── The page scroll ──
-- The body is as tall as the larger of the page rect and the content. Only frames hung
-- off the body's top are measured, so the size converges: one anchored to its bottom
-- would move as it grows. IsVisible, since a hidden page's rows keep their shown flag.
function OptionsScroll_ContentBottom()
local bottom = nil
local function take(name)
local f = getglobal(name)
if f and f:IsVisible() then
local b = f:GetBottom()
if b and (not bottom or b < bottom) then bottom = b end
end
end
for _, key in ipairs(OPTIONS_CATEGORY_KEYS) do
if OPTIONS_PAGE_ROWS[key] then
take("BenillaOptionsFrameContainerBodySearchHead" .. key)
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
take("BenillaOptionsFrameContainerBody" .. key .. rkey)
end
end
end
take("BenillaOptionsFrameContainerBodySearchHeadKeybindings")
for i = 1, KEYBINDINGS_SEARCH_ROWS do
take("BenillaOptionsFrameContainerBodyKeybindSearch" .. i)
end
return bottom
end
-- Size the body from OnUpdate, off the previous frame's rects; writes are gated because
-- SetWidth and SetHeight invalidate layout.
function OptionsScroll_Fit()
local sf = BenillaOptionsFrameContainerScroll
local body = BenillaOptionsFrameContainerBody
local fw, fh = sf:GetWidth(), sf:GetHeight()
if not fw or fw <= 0 or not fh or fh <= 0 then return end
if math.abs(body:GetWidth() - fw) >= 0.5 then body:SetWidth(fw) end
local h = fh
local top, bottom = body:GetTop(), OptionsScroll_ContentBottom()
if top and bottom then
local content = (top - bottom) + BENILLA_SCROLL_PAD
if content > h then h = content end
end
if math.abs(body:GetHeight() - h) >= 0.5 then
body:SetHeight(h)
sf:UpdateScrollChildRect()
end
end
-- The page layout (era SettingsList: verticalPad 10, padLeft 25, spacing 9): the head at
-- (10,-12), each next at (0,-9), as the rows' XML anchors state; `prev` nil is the head.
function OptionsSearch_Place(name, prev)
local f = getglobal(name)
f:ClearAllPoints()
if prev then
f:SetPoint("TOPLEFT", prev, "BOTTOMLEFT", 0, -9)
f:SetPoint("TOPRIGHT", prev, "BOTTOMRIGHT", 0, -9)
else
f:SetPoint("TOPLEFT", "BenillaOptionsFrameContainerBody", "TOPLEFT", 10, -12)
f:SetPoint("TOPRIGHT", "BenillaOptionsFrameContainerBody", "TOPRIGHT", -20, -12)
end
end
-- Lay a page's rows back on their XML chain after a search; a test holds the two equal.
function OptionsPage_Layout(key)
local prev = nil
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
local name = "BenillaOptionsFrameContainerBody" .. key .. rkey
OptionsSearch_Place(name, prev)
getglobal(name):Show()
prev = name
end
end
-- The results view (era OnSearchTextChanged, l.659-691): page bodies shown, rows hidden,
-- then each group chained, head then matches, a child pulling its parent in (l.665-670).
-- The title and no-match strings are ours: the era's are not in its UI source.
function OptionsSearch_Display(text)
BenillaOptionsFrameContainerScroll:SetVerticalScroll(0)
for k in pairs(OPTIONS_PAGE_ROWS) do
getglobal("BenillaOptionsFrameContainerBody" .. k):Show()
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[k]) do
getglobal("BenillaOptionsFrameContainerBody" .. k .. rkey):Hide()
end
getglobal("BenillaOptionsFrameContainerBodySearchHead" .. k):Hide()
end
-- The Keybindings body hides too; matched bindings paint onto the search pool.
getglobal("BenillaOptionsFrameContainerBodyKeybindings"):Hide()
getglobal("BenillaOptionsFrameContainerBodySearchHeadKeybindings"):Hide()
for i = 1, KEYBINDINGS_SEARCH_ROWS do
getglobal("BenillaOptionsFrameContainerBodyKeybindSearch" .. i):Hide()
end
KeyBindingsPage.searchPainted = nil
KeyBindings_SetSelected(nil)
BenillaOptionsFrameContainerUnbind:Hide()
BenillaOptionsFrameContainerTitle:SetText("Search Results")
BenillaOptionsFrameContainerDefaults:Hide()
local order, groups = OptionsSearch_FindMatches(text)
if table.getn(order) == 0 then
BenillaOptionsFrameContainerBodyNoResults:Show()
return
end
BenillaOptionsFrameContainerBodyNoResults:Hide()
local prev = nil
for _, key in ipairs(order) do
local head = "BenillaOptionsFrameContainerBodySearchHead" .. key
OptionsSearch_Place(head, prev)
getglobal(head):Show()
prev = head
if key == "Keybindings" then
-- Matched bindings paint onto the pool, capped at its size.
KeyBindingsPage.searchPainted = {}
local shown = 0
for _, index in ipairs(groups[key]) do
if shown < KEYBINDINGS_SEARCH_ROWS then
shown = shown + 1
local name = "BenillaOptionsFrameContainerBodyKeybindSearch" .. shown
KeyBindings_PaintBindRow(name, index)
OptionsSearch_Place(name, prev)
getglobal(name):Show()
KeyBindingsPage.searchPainted[name] = index
prev = name
end
end
else
local placed = {}
for _, rkey in ipairs(groups[key]) do
local row = getglobal("BenillaOptionsFrameContainerBody" .. key .. rkey)
if row.parentRow and not placed[row.parentRow] then
placed[row.parentRow] = 1
local pname = "BenillaOptionsFrameContainerBody" .. key .. row.parentRow
OptionsSearch_Place(pname, prev)
getglobal(pname):Show()
prev = pname
end
if not placed[rkey] then
placed[rkey] = 1
local name = "BenillaOptionsFrameContainerBody" .. key .. rkey
OptionsSearch_Place(name, prev)
row:Show()
prev = name
end
end
OptionsPage_Refresh(key)
end
end
end
-- Ending a search (the era's empty-text arm, l.655-658).
function OptionsSearch_Restore()
BenillaOptionsFrameContainerScroll:SetVerticalScroll(0)
for k in pairs(OPTIONS_PAGE_ROWS) do
OptionsPage_Layout(k)
getglobal("BenillaOptionsFrameContainerBodySearchHead" .. k):Hide()
end
for i = 1, KEYBINDINGS_SEARCH_ROWS do
getglobal("BenillaOptionsFrameContainerBodyKeybindSearch" .. i):Hide()
end
getglobal("BenillaOptionsFrameContainerBodySearchHeadKeybindings"):Hide()
KeyBindingsPage.searchPainted = nil
BenillaOptionsFrameContainerBodyNoResults:Hide()
BenillaOptionsFrameContainerDefaults:Show()
BenillaOptionsFrame_SelectCategory(BenillaOptionsFrame.selectedCategory or "Controls")
end
-- The era text gate (OnSearchTextChanged l.640-652).
function OptionsSearch_OnTextChanged(text)
if text == BenillaOptionsFrame.searchText then return end
local had = BenillaOptionsFrame.searchText and BenillaOptionsFrame.searchText ~= ""
BenillaOptionsFrame.searchText = text
if text == "" then
if had then OptionsSearch_Restore() end
else
OptionsSearch_Display(text)
end
end
-- ── The setting pages: 1.12 rows in the era Settings grammar ──
-- Rows, CVars, labels and dependencies are the 1.12 panels'; geometry is the era
-- settings list (Blizzard_SettingControls, Blizzard_SettingsList): 26-tall rows on a 9
-- spacing, label LEFT+37 to CENTER-85, control at CENTER-80.
-- Descriptions 1.12 lacks take a BENILLA_ prefix, so OPTION_TOOLTIP_* stays 1.12's own.
BENILLA_TOOLTIP_RENDER_SCALE =
"Draws the 3D world at a fraction of the window's resolution, or larger than it. "
.. "The interface is unaffected at any setting.\n\n"
.. "Below 100% trades sharpness for frame rate; above 100% is supersampling, which "
.. "smooths edges at the cost of frame rate. Applies when you click Apply."
-- Enable Sound in Background: 1.12 has no checkbox; silenced sounds keep running.
BENILLA_TOOLTIP_BACKGROUND_SOUND =
"Keeps the game's sound playing while you are working in another window.\n\n"
.. "With this off, switching away silences the game and switching back restores it. "
.. "Sounds keep running while they are silenced, so a long one may have finished by "
.. "the time you return."
-- Display Mode: 1.12's WINDOWED_MODE text describes a checkbox and exclusive-mode gamma.
BENILLA_TOOLTIP_DISPLAY_MODE =
"Windowed (Fullscreen) fills the screen with a borderless window; Windowed runs in "
.. "an ordinary one.\n\n"
.. "There is no exclusive fullscreen mode. WoW itself removed one in 8.0.1, and "
.. "modern Classic offers these same two."
-- Brightness: 1.12's GAMMA text points at gray-bar art this page does not have.
BENILLA_TOOLTIP_BRIGHTNESS =
"Lightens or darkens the whole picture — nights, caves and interiors are what it is "
.. "for.\n\n"
.. "This is the same correction 1.12 applied through the display's own gamma ramp, "
.. "which it could only do in exclusive fullscreen. benilla applies it to the "
.. "finished image instead, so it works in both display modes."
-- ══ MONKEY (advanced graphics): the Advanced Graphics page's own strings, EN + RU ═════
--
-- The page that gives a PLAYER the dynamic light and shadow system. Until it existed the
-- lanes were reachable only from `/console` and the native debug panel — and the panel
-- does not ship in a player build, so a player had no way in at all. Three rows move here
-- off the Graphics page (Real Character Shadows, World Shadows, Shadow Distance) with
-- their settings and their descriptions unchanged; the other twelve are new seats on
-- CVars this client has read for some time.
--
-- **Every string on it is authored in both languages** (the project's own standing rule),
-- picked by `GetLocale()`, and there is no other localisation pattern in this window to
-- follow: every page above is 1.12 GlobalStrings, whose own file IS the localisation. So
-- the table is here, next to the page, rather than in a scheme of its own.
--
-- TWO CAVEATS, both true of the client and not of this table: benilla's `GetLocale()`
-- answers `enUS` unconditionally today (it ships and reads enUS data only), so the ruRU
-- column is dormant until that changes; and 1.12's own `FRIZQT__.TTF` carries no Cyrillic
-- glyphs, so a Russian build needs a font that does before these read as words. Neither is
-- a reason to ship the page half-authored — both are one line away from being true, and a
-- string written later is a string written to a different standard.
--
-- The VALUES the rows write are never localised: a dropdown entry carries the engine's own
-- string in `value` and the player's language in `text`, so `config.toml` and `/console`
-- read the same words on every install.
BENILLA_ADVGFX_STRINGS = {
enUS = {
page = "Advanced Graphics",
lightingQuality = "Lighting Quality",
-- MONKEY (presets): the Graphics Preset and Render Distance rows.
graphicsQuality = "Graphics Preset",
renderDistance = "Render Distance",
pClassic = "Classic",
qUltra = "Ultra",
-- MONKEY (volumetric fog): localised atmospheric quality row.
volumetricFog = "Volumetric Fog",
-- MONKEY (post): HDR excess + halo quality.
bloom = "Bloom",
sunShafts = "Sun Shafts",
colorGrading = "Colour Grading",
-- MONKEY (sky): the sky tier row.
skyQuality = "Sky Quality",
fogOff = "Off",
-- MONKEY (skybox): the zone skybox row.
zoneSkyboxes = "Zone Skyboxes",
waterQuality = "Water Quality",
waterClassic = "Classic",
waterEnhanced = "Enhanced",
waterHigh = "High",
lavaGlow = "Lava Glow",
qOff = "Off",
qLow = "Low",
qMedium = "Medium",
qHigh = "High",
qCustom = "Custom",
characterShadows = "Real Character Shadows",
worldShadows = "World Shadows",
shadowDistance = "Shadow Distance",
shadowResolution = "Shadow Resolution",
moonShadows = "Moon Shadows",
interiorLight = "Dynamic Interior Lighting",
interiorShadows = "Indoor Torch Shadows",
exteriorShadows = "Outdoor Torch Shadows",
torchTerrainShadows = "Terrain Blocks Torchlight",
torchSoft = "Torch Shadow Softness",
fireLight = "Fire Light Brightness",
fireFlicker = "Fire Flicker",
spellLights = "Spell Lights",
nightDarkness = "Night Darkness",
interiorDarkness = "Interior Darkness",
-- MONKEY (p0 skyDither)
skyDither = "Sky Dithering",
-- MONKEY (fog)
fogModel = "Modern Fog",
-- MONKEY (wet)
rainSurfaces = "Wet Surfaces in Rain",
-- MONKEY (wind)
foliageWind = "Foliage Wind",
windGrass = "Grass",
windTrees = "Grass + Trees",
-- MONKEY (ao): localised contact-shadow row.
ambientOcclusion = "Ambient Occlusion",
-- MONKEY (lampfog)
lampFog = "Lamp Fog",
-- MONKEY (integration): the daylight lane's district window split.
daylightWindowSplit = "City Window Daylight",
yards = "%d yd",
tips = {
-- MONKEY (presets)
GRAPHICS_QUALITY =
"Sets every graphics setting at once: Lighting Quality and everything it sets, "
.. "Render Distance, Sky Quality, Sky Dithering, Modern Fog, Wet Surfaces in Rain, "
.. "Terrain Blocks Torchlight, the daylight through city windows, Ambient Occlusion, Lamp Fog "
.. "and Zone Skyboxes.\n\n"
.. "Classic is the original client: every enhancement off and the original 350 yd "
.. "view distance. Low and Medium add the enhancements that cost almost nothing; High "
.. "is the recommended look; Ultra raises every quality to its maximum and the view "
.. "distance to 1497 yd, and costs the most.\n\n"
.. "Shadow Distance and Torch Shadow Softness stay as you set them. Changing any "
.. "setting the preset sets shows Custom.",
RENDER_DISTANCE =
"How far the detailed world is drawn, in yards: the same setting as Terrain "
.. "Distance on the Graphics page, with a longer reach. Past 777 yd, the original "
.. "client's limit, the extra distance shows through Modern Fog; with the original "
.. "fog the zone's own fog hides it.\n\n"
.. "Farther costs more memory, loading and GPU time.",
LIGHTING_QUALITY =
"Sets character, world, indoor torch and outdoor torch shadows; dynamic "
.. "interior lighting; moon shadows; volumetric fog; water quality; lava glow; fire and spell brightness; fire flicker; "
.. "foliage wind; and night and interior darkness. Low, Medium and High also set shadow "
.. "resolution; Medium and High also set resident and moving torch shadow counts.\n\n"
.. "Off restores the original client's look: Classic water, no volumetric fog, lava glow or synthesised fire lights, "
.. "night gain 1.0 and interior gain 1.0. All other settings, including "
.. "Shadow Distance and Torch Shadow Softness, stay as you set them. "
.. "Low, Medium and High use Enhanced water; mirror reflections stay opt-in. "
.. "Ultra also raises shadow resolution to 4096 and the torch shadow counts to 16 and 8, "
.. "and uses High water and High volumetric fog. "
.. "Changing a preset member shows Custom when no preset matches.",
-- MONKEY (volumetric fog): explain cost and the shadow-map dependency.
-- MONKEY (post): Off guarantees the pre-HDR image.
BLOOM =
"Makes fire, lava, spells and lit windows carry a soft halo. Low uses a smaller blur chain; High is smoother. Off leaves the original image unchanged.",
SUN_SHAFTS =
"Draws sunlight through gaps in trees and buildings. Scene depth blocks the rays; they fade at night, off-screen and indoors.",
COLOR_GRADING =
"Applies a subtle zone-specific colour palette to the 3D world and blends between its day and night looks. The interface is never graded.",
VOLUMETRIC_FOG =
"Off disables volumetric fog. Low adds nearby haze and sun or moon shafts with fewer steps; High uses more steps for smoother shafts. Mist is heavier at dawn and in bad weather, and subtle indoors. Shafts require shadows; with shadows off only haze remains.",
-- MONKEY (sky): what each sky tier adds.
SKY_QUALITY =
"Classic is the original client's sky. Enhanced smooths the sky's colour "
.. "gradient, adds a soft glow around the sun and a starry night sky with the "
.. "Milky Way. High also gives the clouds finer detail and sunlit edges. "
.. "Costs very little.",
-- MONKEY (skybox): what the zone skybox row changes.
ZONE_SKYBOXES =
"Draws the painted sky a zone's lighting names, as later expansions do: "
.. "the volcanic sky of the Burning Steppes, the alien sky of the Blasted Lands "
.. "and the starry night over Mount Hyjal, fading in at the zone's edge. "
.. "Off keeps the original client's sky everywhere but ghost and dungeon skies. Nearly free.",
WATER_QUALITY =
"Classic is the original client's water. Enhanced adds soft shorelines, "
.. "animated foam around shores and objects, moving wave highlights, sky reflection "
.. "and light glints. High also adds mirror reflections and costs the most.",
LAVA_GLOW =
"How strongly lava lights its surroundings. 0 turns the glow off.",
CHARACTER_SHADOWS =
"Renders real dynamic silhouettes for players, NPCs, creatures, and mounts, replacing "
.. "the legacy oval blob. Matches Wrath's character-only shadow tier. This uses "
.. "additional GPU time and memory.",
WORLD_SHADOWS =
"Casts real dynamic shadows from the static world (trees, buildings, and foliage) "
.. "following the sun, and switches off the baked terrain shadows they replace. "
.. "Independent of Real Character Shadows. This uses additional GPU time and memory.",
SHADOW_DISTANCE =
"How far realtime shadows are drawn, in yards. Higher covers more ground but spreads "
.. "the shadow map thinner (softer edges) and costs more. Applies on Apply.",
SHADOW_RESOLUTION =
"The edge of the sun's shadow map, in texels. Larger is sharper "
.. "everywhere the shadow distance reaches.\n\n"
.. "The cost is quadratic: 4096 draws four times the shadow pass of 2048 "
.. "and holds four times the depth texture.",
MOON_SHADOWS =
"How dark a shadow thrown by moonlight is allowed to get. A little keeps "
.. "the night from reading flat; a lot is stylised moonlight the original "
.. "client never had.\n\n"
.. "At 0 the moon casts nothing at all and the night renders exactly as "
.. "it did before this existed. It costs nothing by day.",
INTERIOR_LIGHT =
"Lights the inside of buildings from the lamps, candles and hearths that "
.. "actually stand in the room, instead of the lighting baked into the "
.. "walls.\n\n"
.. "Off restores the original client's baked interiors. On, it costs a "
.. "little GPU time per lit surface. Indoor Torch Shadows require it; "
.. "Outdoor Torch Shadows work independently.",
INTERIOR_SHADOWS =
"Lets the nearest indoor fires cast real shadows — a candle throws the "
.. "table's shadow across the floor.\n\n"
.. "Each promoted fire costs a shadow map of its own, which makes this "
.. "the most expensive row on the page. Needs Dynamic Interior Lighting.",
EXTERIOR_SHADOWS =
"The same for fires out in the open: campfires, braziers and lampposts "
.. "cast real shadows after dark.\n\n"
.. "It does nothing by day and does not require Dynamic Interior Lighting.",
TORCH_TERRAIN_SHADOWS =
"Lets the ground itself take part in outdoor torch shadows: a hill or a "
.. "bank between a fire and the slope behind it blocks the fire's light.\n\n"
.. "Adds the nearby terrain to each outdoor fire's shadow map when it is "
.. "rebuilt; the per-frame cost is small. Needs Outdoor Torch Shadows.",
TORCH_SOFT =
"How soft the edge of a torch shadow is where the object meets the "
.. "ground. Low is hard and crisp; high spreads the edge the way a real "
.. "flame does.\n\n"
.. "It costs no extra shadow maps — only a wider filter over the ones "
.. "already drawn.",
FIRE_LIGHT =
"How brightly campfires, torches, braziers and forges light the world "
.. "around them. These are lights benilla invents from the flame itself; "
.. "the original client's art carries none.\n\n"
.. "At 0 the invented fire lights are off and only the lights the artists "
.. "placed remain. Moving it costs nothing.",
FIRE_FLICKER =
"How strongly every flame's light breathes — candles quick and shallow, "
.. "bonfires slow and steady.\n\n"
.. "At 0 fires burn at a constant brightness, which is what they did "
.. "before this existed. It is computed on the processor and costs the "
.. "graphics card nothing.",
SPELL_LIGHTS =
"How brightly spells, missiles and impacts light the room around them — a "
.. "fireball's flash, an aura's glow.\n\n"
.. "Separate from Fire Light Brightness on purpose: calming a busy fight "
.. "should not dim the world's hearths. At 0 no spell throws light.",
NIGHT_DARKNESS =
"How dark the world gets outdoors after sunset. "
.. "1.0 = the original client night; lower = darker.\n\n"
.. "It never touches the fires — the point is a darker night around the "
.. "flame, not a dimmer flame. Inert while the sun is up, and free at any "
.. "setting.",
INTERIOR_DARKNESS =
"Scales interior fixture light and room ambient, including the light from "
.. "lamps and candles. Lower values make both dimmer.\n\n"
.. "1.0 leaves these inputs unchanged. Free at any setting.",
-- MONKEY (p0 skyDither)
SKY_DITHER =
"Adds a faint noise to the final image so smooth sky and fog gradients do not "
.. "break into visible bands. Off is the original client's look. Practically free.",
-- MONKEY (fog)
FOG_MODEL =
"Softer distance fog in the style of the modern client: it thickens gradually "
.. "instead of in a straight ramp, glows toward the sun by day and shifts to the "
.. "sky's colour in the distance, so the land melts into the horizon. Each zone "
.. "keeps its own fog distance; above the original view-distance limit the fog "
.. "recedes with it.\n\nOff is the original client's fog. Practically free.",
-- MONKEY (wet)
RAIN_SURFACES =
"Rain slowly soaks the ground, stone and wood under the open sky: they darken, "
.. "puddles gather on flat ground and wet tops catch the light; rain drops ring "
.. "the water. It dries over a few minutes after the rain stops. Off is the "
.. "original client's look. Nearly free, and only active while things are wet.",
-- MONKEY (wind)
FOLIAGE_WIND =
"Grass bends in two travelling wind waves and parts around nearby characters. "
.. "Grass + Trees also gives classified tree and bush foliage a gentle sway.\n\n"
.. "Off makes no vertex displacement and restores the unchanged image. Tree shadows stay static.",
-- MONKEY (ao): what the contact shadows touch and what they spare.
AMBIENT_OCCLUSION =
"Soft contact shadows where surfaces meet: under props and furniture, in the corners "
.. "between walls and floors, and around characters' feet. Low uses fewer samples; "
.. "High is smoother and reaches a little further.\n\n"
.. "Fades out with distance and spares the sky, water, lit windows and flames. "
.. "Off leaves the image unchanged.",
-- MONKEY (integration): daylight window split.
DAYLIGHT_WINDOW_SPLIT =
"Large city buildings take daylight through each window on its own instead of "
.. "treating a whole wall of windows as one opening, so halls like the cathedral "
.. "catch the sun pane by pane.\n\nApplies to buildings loaded after the change. "
.. "Off is the earlier look.",
-- MONKEY (lampfog)
LAMP_FOG =
"Makes nearby lamps and fires glow through the air after dark. Low uses the "
.. "nearest 16 lights; High uses 32. Rain and fog strengthen the halos. "
.. "The effect is unshadowed, but stops at visible scene depth.\n\n"
.. "Off is unchanged, and daylight is unchanged at every setting.",
},
},
ruRU = {
page = "Расширенная графика",
lightingQuality = "Качество освещения",
-- MONKEY (presets): the Graphics Preset and Render Distance rows.
graphicsQuality = "Набор графики",
renderDistance = "Дальность прорисовки",
pClassic = "Классика",
qUltra = "Ультра",
-- MONKEY (post): Russian HDR excess + halo quality row.
bloom = "Свечение",
sunShafts = "Солнечные лучи",
colorGrading = "Цветокоррекция",
-- MONKEY (volumetric fog): Russian atmospheric quality row.
volumetricFog = "Объёмный туман",
-- MONKEY (sky): the sky tier row.
skyQuality = "Качество неба",
fogOff = "Выкл",
-- MONKEY (skybox): the zone skybox row.
zoneSkyboxes = "Небосводы зон",
waterQuality = "Качество воды",
waterClassic = "Классическое",
waterEnhanced = "Улучшенное",
waterHigh = "Высокое",
lavaGlow = "Свечение лавы",
qOff = "Выкл.",
qLow = "Низкое",
qMedium = "Среднее",
qHigh = "Высокое",
qCustom = "Своё",
characterShadows = "Настоящие тени персонажей",
worldShadows = "Тени мира",
shadowDistance = "Дальность теней",
shadowResolution = "Разрешение теней",
moonShadows = "Лунные тени",
interiorLight = "Динамическое освещение помещений",
interiorShadows = "Тени факелов в помещениях",
exteriorShadows = "Тени огней под открытым небом",
torchTerrainShadows = "Рельеф заслоняет огни",
torchSoft = "Мягкость теней от огня",
fireLight = "Яркость огня",
fireFlicker = "Мерцание огня",
spellLights = "Свет от заклинаний",
nightDarkness = "Темнота ночи",
interiorDarkness = "Темнота помещений",
-- MONKEY (p0 skyDither)
skyDither = "Дизеринг неба",
-- MONKEY (fog)
fogModel = "Современный туман",
-- MONKEY (wet)
rainSurfaces = "Мокрые поверхности в дождь",
-- MONKEY (wind)
foliageWind = "Ветер листвы",
windGrass = "Трава",
windTrees = "Трава + деревья",
-- MONKEY (ao): Russian contact-shadow row.
ambientOcclusion = "Затенение окружения",
-- MONKEY (lampfog)
lampFog = "Свечение фонарей в тумане",
-- MONKEY (integration): the daylight lane's district window split.
daylightWindowSplit = "Дневной свет через окна города",
yards = "%d ярд.",
tips = {
-- MONKEY (presets)
GRAPHICS_QUALITY =
"Задаёт все настройки графики сразу: качество освещения и всё, что оно задаёт, "
.. "дальность прорисовки, качество неба, дизеринг неба, современный туман, мокрые "
.. "поверхности в дождь, заслонение огней рельефом, дневной свет в окнах городов, "
.. "затенение окружения, свечение фонарей в тумане и небосводы зон.\n\n"
.. "«Классика» — оригинальный клиент: все улучшения выключены, дальность обзора "
.. "прежние 350 ярдов. «Низкое» и «Среднее» добавляют почти бесплатные улучшения; "
.. "«Высокое» — рекомендуемый вид; «Ультра» поднимает всё качество до максимума, а "
.. "дальность — до 1497 ярдов, и стоит дороже всего.\n\n"
.. "Дальность теней и мягкость теней от огня сохраняют ваши значения. Изменение "
.. "любой настройки набора показывает «Своё».",
RENDER_DISTANCE =
"Как далеко рисуется подробный мир, в ярдах: та же настройка, что «Дальность "
.. "обзора» на странице «Графика», но с большим пределом. Дальше 777 ярдов, предела "
.. "оригинального клиента, дополнительное расстояние видно с современным туманом; "
.. "с оригинальным туманом его скрывает туман зоны.\n\n"
.. "Чем дальше, тем больше памяти, загрузки и работы видеокарты.",
LIGHTING_QUALITY =
"Задаёт тени персонажей, мира и огней внутри и снаружи помещений; "
.. "динамическое освещение помещений; лунные тени; объёмный туман; качество воды; свечение лавы; яркость огня и заклинаний; "
.. "мерцание огня; темноту ночи и помещений. «Низкое», «Среднее» и «Высокое» "
.. "также задают разрешение теней; «Среднее» и «Высокое» — число карт теней "
.. "от огней и число огней с тенями движущихся объектов.\n\n"
.. "«Выкл.» возвращает вид оригинального клиента: классическая вода, без объёмного тумана, свечения лавы и созданных из пламени "
.. "источников света, с коэффициентами яркости ночи и помещений 1.0. "
.. "Все остальные настройки, включая дальность теней и мягкость теней от огня, "
.. "сохраняют ваши значения. «Низкое», «Среднее» и «Высокое» используют улучшенную воду; "
.. "зеркальные отражения включаются отдельно. «Ультра» также поднимает разрешение теней "
.. "до 4096 и число теней от огней до 16 и 8, а вода и объёмный туман — «Высокое». "
.. "Изменение настройки набора показывает «Своё», "
.. "если ни один набор больше не совпадает.",
-- MONKEY (post): localised bloom effect and Off contract.
BLOOM =
"Добавляет мягкое сияние огню, лаве, заклинаниям и освещённым окнам. Низкое качество использует короткое размытие, высокое — более плавное. Выключение сохраняет исходное изображение.",
SUN_SHAFTS =
"Показывает солнечные лучи сквозь деревья и здания. Рельеф и здания перекрывают свет; ночью и в помещениях эффект исчезает.",
COLOR_GRADING =
"Применяет мягкую цветовую палитру зоны и плавно меняет дневной вариант на ночной. Интерфейс не изменяется.",
-- MONKEY (volumetric fog): localised effect and cost explanation.
VOLUMETRIC_FOG =
"Выкл отключает объёмный туман. Низкое добавляет дымку вблизи и лучи солнца или луны с меньшим числом шагов; Высокое использует больше шагов для более плавных лучей. Туман гуще на рассвете и в непогоду, а в помещениях слабее. Для лучей нужны тени; без теней остаётся только дымка.",
-- MONKEY (sky): what each sky tier adds.
SKY_QUALITY =
"«Классическое» — небо оригинального клиента. «Улучшенное» сглаживает "
.. "цветовой переход неба, добавляет мягкое сияние вокруг солнца и звёздное "
.. "ночное небо с Млечным Путём. «Высокое» также добавляет облакам мелкие "
.. "детали и освещённые солнцем края. Почти не влияет на производительность.",
-- MONKEY (skybox): what the zone skybox row changes.
ZONE_SKYBOXES =
"Рисует нарисованное небо, заданное освещением зоны, как в поздних дополнениях: "
.. "вулканическое небо Пылающих степей, чужое небо Выжженных земель "
.. "и звёздную ночь над горой Хиджал, с плавным появлением на границе зоны. "
.. "«Выкл.» оставляет небо оригинального клиента везде, кроме неба призрака и подземелий. Почти бесплатно.",
WATER_QUALITY =
"«Классическое» — вода оригинального клиента. «Улучшенное» добавляет плавные переходы у берегов, "
.. "анимированную пену у берегов и вокруг объектов, подвижные блики на волнах, отражение неба "
.. "и блики от источников света. «Высокое» также добавляет зеркальные отражения и требует больше всего ресурсов.",
LAVA_GLOW =
"Насколько сильно лава освещает всё вокруг. При 0 свечение отключено.",
CHARACTER_SHADOWS =
"Рисует настоящие динамические силуэты игроков, НИП, существ и ездовых "
.. "животных вместо старого овального пятна. Соответствует уровню теней "
.. "персонажей из Wrath. Требует дополнительного времени и памяти "
.. "видеокарты.",
WORLD_SHADOWS =
"Заставляет статичный мир — деревья, здания и растительность — "
.. "отбрасывать настоящие динамические тени вслед за солнцем и отключает "
.. "запечённые тени ландшафта, которые они заменяют. Не зависит от "
.. "настоящих теней персонажей. Требует дополнительного времени и памяти "
.. "видеокарты.",
SHADOW_DISTANCE =
"Как далеко рисуются тени в реальном времени, в ярдах. Большее значение "
.. "покрывает больше земли, но растягивает карту теней тоньше (края "
.. "становятся мягче) и стоит дороже. Применяется по кнопке «Применить».",
SHADOW_RESOLUTION =
"Размер карты теней солнца в текселях. Чем больше, тем чётче тени на "
.. "всей дальности их прорисовки.\n\n"
.. "Стоимость растёт квадратично: 4096 — это вчетверо больше работы в "
.. "проходе теней и вчетверо больше видеопамяти под карту глубины, чем "
.. "2048.",
MOON_SHADOWS =
"Насколько тёмной может стать тень, отбрасываемая лунным светом. "
.. "Немного — и ночь перестаёт выглядеть плоской; много — это "
.. "стилизованная луна, какой в оригинальном клиенте не было.\n\n"
.. "При 0 луна не отбрасывает теней вовсе, и ночь выглядит так же, как "
.. "до появления этой возможности. Днём не стоит ничего.",
INTERIOR_LIGHT =
"Освещает помещения от ламп, свечей и очагов, которые действительно "
.. "стоят в комнате, а не от освещения, запечённого в стенах.\n\n"
.. "«Выкл.» возвращает запечённые интерьеры оригинального клиента. "
.. "Включённый режим стоит немного времени видеокарты на каждую "
.. "освещённую поверхность. Тени от огней внутри требуют этого режима; "
.. "тени от огней снаружи работают независимо.",
INTERIOR_SHADOWS =
"Позволяет ближайшим огням в помещении отбрасывать настоящие тени: "
.. "свеча кладёт тень стола на пол.\n\n"
.. "Каждый такой огонь стоит собственной карты теней, поэтому это самая "
.. "дорогая строка на странице. Требует динамического освещения "
.. "помещений.",
EXTERIOR_SHADOWS =
"То же для огней под открытым небом: костры, жаровни и фонари "
.. "отбрасывают настоящие тени после наступления темноты.\n\n"
.. "Днём не действует и не требует динамического освещения помещений.",
TORCH_TERRAIN_SHADOWS =
"Земля сама участвует в тенях от огней снаружи: холм или склон между "
.. "костром и местностью за ним заслоняет свет огня.\n\n"
.. "Добавляет ближний рельеф в карту теней каждого уличного огня при её "
.. "перестройке; затраты на кадр невелики. Требует теней огней под "
.. "открытым небом.",
TORCH_SOFT =
"Насколько мягок край тени от огня там, где предмет касается пола. "
.. "Низкое значение — резкий край, высокое — размытый, как от "
.. "настоящего пламени.\n\n"
.. "Дополнительных карт теней не требует: это лишь более широкий фильтр "
.. "по уже нарисованным.",
FIRE_LIGHT =
"Насколько ярко костры, факелы, жаровни и горны освещают всё вокруг. "
.. "Эти источники benilla создаёт из самого пламени — в оригинальной "
.. "графике их нет.\n\n"
.. "При 0 придуманные огни выключены и остаются лишь источники, "
.. "расставленные художниками. Изменение значения ничего не стоит.",
FIRE_FLICKER =
"Насколько сильно «дышит» свет каждого пламени: свечи — часто и слабо, "
.. "костры — медленно и ровно.\n\n"
.. "При 0 огни горят с постоянной яркостью, как было до появления этой "
.. "возможности. Считается на процессоре и ничего не стоит видеокарте.",
SPELL_LIGHTS =
"Насколько ярко заклинания, снаряды и попадания освещают всё вокруг: "
.. "вспышка огненного шара, свечение ауры.\n\n"
.. "Отделено от яркости огня намеренно: успокоить шумный бой не должно "
.. "значить пригасить очаги во всём мире. При 0 заклинания не дают "
.. "света.",
NIGHT_DARKNESS =
"Насколько темно становится под открытым небом после заката. "
.. "1.0 — ночь оригинального клиента; ниже — темнее.\n\n"
.. "Огней не касается: смысл в том, чтобы ночь вокруг пламени была "
.. "темнее, а не само пламя тусклее. Пока солнце в небе, не действует, и "
.. "ничего не стоит при любом значении.",
INTERIOR_DARKNESS =
"Масштабирует свет светильников и фоновое освещение помещений, включая "
.. "свет ламп и свечей. Меньшие значения ослабляют и то и другое.\n\n"
.. "1.0 оставляет эти составляющие без изменений. Ничего не стоит при любом значении.",
-- MONKEY (p0 skyDither)
SKY_DITHER =
"Добавляет едва заметный шум в итоговое изображение, чтобы плавные переходы цвета "
.. "неба и тумана не распадались на полосы. Выключено — вид оригинального клиента. "
.. "Почти ничего не стоит.",
-- MONKEY (fog)
FOG_MODEL =
"Более мягкий туман в духе современного клиента: он сгущается постепенно, а не "
.. "по прямой, днём светлеет в сторону солнца, а вдали принимает цвет неба, "
.. "так что земля растворяется в горизонте. Дальность тумана в каждой зоне "
.. "прежняя; за пределом дальности обзора оригинала туман отступает вместе с ней."
.. "\n\nВыключено — туман оригинального клиента. Почти ничего не стоит.",
-- MONKEY (wet)
RAIN_SURFACES =
"Дождь постепенно намачивает землю, камень и дерево под открытым небом: они темнеют, "
.. "на ровной земле собираются лужи, мокрые поверхности блестят, а капли расходятся "
.. "кругами по воде. После дождя всё высыхает за несколько минут. Выключено — вид "
.. "оригинального клиента. Почти ничего не стоит и работает, только пока всё мокрое.",
-- MONKEY (wind)
FOLIAGE_WIND =
"Трава гнётся двумя бегущими волнами ветра и расступается вокруг персонажей. "
.. "Трава + деревья также добавляет мягкое качание листвы деревьев и кустов.\n\n"
.. "Выключено не смещает вершины и восстанавливает исходный вид. Тени деревьев остаются неподвижными.",
-- MONKEY (ao): Russian contact-shadow explanation.
AMBIENT_OCCLUSION =
"Мягкие контактные тени там, где поверхности соприкасаются: под предметами и мебелью, "
.. "в углах между стенами и полом, у ног персонажей. «Низкое» использует меньше выборок; "
.. "«Высокое» — более плавное и захватывает чуть больше.\n\n"
.. "Ослабевает с расстоянием и не затрагивает небо, воду, освещённые окна и пламя. "
.. "«Выкл» оставляет изображение без изменений.",
-- MONKEY (integration): daylight window split.
DAYLIGHT_WINDOW_SPLIT =
"Большие городские здания пропускают дневной свет через каждое окно отдельно, "
.. "а не через всю стену окон как один проём, поэтому залы вроде собора "
.. "освещаются солнцем окно за окном.\n\nДействует для зданий, загруженных после "
.. "изменения. Выключено — прежний вид.",
-- MONKEY (lampfog)
LAMP_FOG =
"После заката ближайшие фонари и огни светятся сквозь воздух. Низкое "
.. "качество использует 16 ближайших источников, высокое — 32. Дождь и туман усиливают ореолы. "
.. "Эффект не рассчитывает тени, но обрывается на видимой глубине.\n\n"
.. "Выключено — без изменений; днём изображение не меняется при любом значении.",
},
},
}
-- The selected column. `or` the English one so an unbuilt locale is a fallback rather
-- than fifteen rows of `nil` labels — 1.12's own GlobalStrings do the same thing by
-- shipping one file per locale with every key present.
BENILLA_ADVGFX = BENILLA_ADVGFX_STRINGS[GetLocale()] or BENILLA_ADVGFX_STRINGS.enUS
-- A row's description resolves by GLOBAL NAME at hover time (`OptionsRow_ShowTooltip`), so
-- the selected column's copy is published under the key the row carries. Same `BENILLA_`
-- prefix the four rows above use, and for the same reason: the reference's
-- `OPTION_TOOLTIP_` namespace stays the reference's.
for key, text in pairs(BENILLA_ADVGFX.tips) do
setglobal("BENILLA_TOOLTIP_" .. key, text)
end
OPTIONS_PAGE_ROWS = {
-- The era Controls order for Sticky Targeting, Auto Loot, Invert Mouse and Mouse
-- Sensitivity; the rest follow their 1.12 box's columns left to right, General
-- 45 -> 3 -> 16 and 14 -> 61, then Camera: the style dropdown -> 24 -> 26,
-- Slider2 -> 27 -> 15, Slider3 -> Slider4.
Controls = {
"RowStickyTarget", "RowAssistAttack", "RowClearAFK",
"RowBlockTrades", "RowAutoSelfCast",
"RowAutoLoot", "RowInvertMouse", "RowMouseSpeed",
"RowCameraFollowStyle", "RowFollowTerrain", "RowHeadBob",
"RowAutoFollowSpeed", "RowWaterCollision", "RowSmartPivot",
"RowMouseLookSpeed", "RowMaxCameraDistance",
},
Audio = {
"RowEnableAll", "RowMaster", "RowSound", "RowMusic", "RowAmbience",
"RowEnableMusic", "RowEnableAmbience", "RowEnableErrorSpeech",
"RowBackgroundSound",
},
Graphics = {
"RowUiScale", "RowFarclip", "RowWorldDetail", "RowBrightness",
"RowWeatherDensity",
"RowDisplayMode", "RowVerticalSync",
"RowRenderScale",
},
-- MONKEY (advanced graphics): the dynamic light + shadow system's own page. Order is
-- the preset first (it writes the rest), then the SUN lanes, then the ROOM lane and
-- its torches, then the invented lights, then the two darkness dials — coarse to
-- fine, and each group's own master above the rows it gates.
--
-- Real Character Shadows, World Shadows and Shadow Distance MOVED here from Graphics,
-- carrying their CVars and their descriptions unchanged: they belong with the rest of
-- the rig they share, and the Graphics page had become the place where a player found
-- three of eighteen shadow settings and no hint that the other fifteen existed.
AdvancedGraphics = {
-- MONKEY (presets): the ladder over every row below, then the view distance.
"RowGraphicsQuality", "RowRenderDistance",
-- MONKEY (volumetric fog): include in refresh, defaults and search.
"RowLightingQuality", "RowWaterQuality", "RowVolumetricFog",
-- MONKEY (sky): the sky tier row.
"RowSkyQuality",
-- MONKEY (post): the world-only screen effects.
"RowBloom", "RowSunShafts", "RowColorGrading",
"RowCharacterShadows", "RowWorldShadows", "RowShadowDistance",
"RowShadowResolution", "RowMoonShadows",
"RowInteriorLight", "RowInteriorShadows", "RowExteriorShadows",
-- MONKEY (daylight: terrain torch casters)
"RowTorchTerrainShadows", "RowTorchSoft",
"RowFireLight", "RowFireFlicker", "RowSpellLights", "RowLavaGlow",
"RowNightDarkness", "RowInteriorDarkness",
-- MONKEY (p0 skyDither)
"RowSkyDither",
-- MONKEY (fog)
"RowFogModel",
-- MONKEY (wet)
"RowRainSurfaces",
-- MONKEY (wind): appended for conflict-free lane merges.
"RowFoliageWind",
-- MONKEY (ao): appended so the other rows keep their indices.
"RowAmbientOcclusion",
-- MONKEY (lampfog)
"RowLampFog",
-- MONKEY (integration): daylight window split.
"RowDaylightWindowSplit",
-- MONKEY (integration): the skybox lane's row (the lane left it out of this list).
"RowZoneSkyboxes",
},
-- Player Guild Names is a child of Player Names, as in 1.12 (l.702-708).
Nameplates = {
"RowEnemyPlates", "RowFriendlyPlates",
"RowPlayerNames", "RowGuildNames", "RowNpcNames", "RowOwnName",
},
-- 1.12's Display box by column (12 -> 2, 31 -> 20, 42 -> 39 -> 66 -> 5), then Help
-- (28 -> 44 -> 29). The target-of-target pair, from Advanced Options' Raid and Party
-- box, sits under Status Text, the other unit-frame readout.
Interface = {
"RowEnhancedTooltips", "RowStatusText", "RowTargetOfTarget", "RowTargetOfTargetMode",
"RowShowCloak", "RowShowHelm",
"RowInstantQuestText", "RowBuffDurations", "RowAutoQuestWatch",
"RowProfanityFilter",
"RowShowTutorials", "RowTipOfTheDay", "RowNewbieTips",
},
-- 1.12's chat box in anchor order (UIOptionsFrame.xml l.751-840). Not shipped: 7
-- Simple Chat, which needs FCF_Set_SimpleChat's re-layout, and 8 Lock Chat Settings
-- and 51 Guild Recruitment Channel, whose verbs exist.
Chat = {
"RowGuildMemberAlert", "RowRemoveChatDelay", "RowChatBubbles", "RowLootSpam",
"RowPartyChatBubbles", "RowSpamFilter",
},
-- Deviation: the bar toggles and grid switch precede the lock, which 1.12's two-column
-- box leads with (CheckButton32), so what is on screen reads first.
ActionBars = {
"RowMultiBar1", "RowMultiBar2", "RowMultiBar3", "RowMultiBar4",
"RowAlwaysShowMultibars", "RowLockActionBar",
},
-- The combat-text box in its anchor-chain order, not its CheckButton index order.
Combat = {
"RowCombatText", "RowFloatMode", "RowLowHealthMana", "RowAuras", "RowAuraFade",
"RowCombatState", "RowDodgeParryMiss", "RowResistances", "RowReputation",
"RowReactives", "RowFriendlyNames", "RowComboPoints", "RowEnergyGains",
"RowHonorGained",
-- 19 -> 11 -> 9 close the chain under their own master (l.709-714).
"RowShowDamage", "RowPeriodicDamage", "RowPetDamage",
},
}
-- `tip` is a GlobalStrings key, resolved at hover as UIOptionsFrame.lua l.265 does.
function OptionsRow_OnLoad(row, cvar, label, tip, child)
row.cvar = cvar
row.tip = tip
-- The era search tag: the display name (SettingControls.lua l.773), uppercased.
row.searchTag = string.upper(label)
-- Kept for OptionsRow_SetEnabled, whose disabled font must keep the child size.
row.child = child
local l = getglobal(row:GetName() .. "Label")
l:SetText(label)
if child then
-- Era child rows (SettingControls.lua l.319-322): the label indents, in small font.
l:SetFontObject("GameFontNormalSmall")
l:ClearAllPoints()
l:SetPoint("LEFT", row:GetName(), "LEFT", 52, 0)
l:SetPoint("RIGHT", row:GetName(), "CENTER", -85, 0)
end
end
-- ── The row's store: a CVar, a saved global, or an API pair ──
-- 1.12's three stores (UIOptionsFrame.lua l.230-377): `cvar`, `uvar` or a
-- `func`/`setFunc` pair, all as strings, "1"/"0" for a toggle.
-- Whether the row has a store, in OptionsRow_Set's order; keep the two in step.
function OptionsRow_HasStore(row)
return row.uvar or row.setFunc or row.cvar
end
function OptionsRow_Get(row)
if row.uvar then return getglobal(row.uvar) end
if row.getFunc then
-- A numeric API row, 1.12's video-panel `func` fork (OptionsFrame.lua l.110/135),
-- formatted like the slider's write so it compares equal as a string.
if row.numeric then
return (string.gsub(string.format("%.2f", row.getFunc()), "%.?0+$", ""))
end
if row.getFunc() then return "1" else return "0" end
end
return GetCVar(row.cvar)
end
-- The write. A global's consumers are Lua and do not poll, so a uvar row also runs its
-- `applyFunc` — the reference's own per-uvar side effects (SIMPLE_CHAT → FCF_Set_*,
-- HIDE_PARTY_INTERFACE → RaidOptionsFrame_UpdatePartyFrames, the combat-text family →
-- CombatText_UpdateDisplayedMessages), moved from its batched confirmation to our live write
-- because this window commits on the click (0961's grammar), not on a Save button.
-- `cvarEvent` is a CVar row's counterpart to a global row's `applyFunc`, and it is the
-- reference's own third SetCVar argument (decision 1140): the token the engine hands back
-- as `CVAR_UPDATE`'s arg1. 1.12 passes its CheckButtons table KEY there
-- (`SetCVar(value.cvar, value.value, index)`), so a consumer that wants to react the
-- INSTANT the switch moves — rather than on its next repaint — has something to listen
-- for. nil on a row nobody listens to, which is most of them: the host polls its knob.
function OptionsRow_Set(row, value)
if row.uvar then
setglobal(row.uvar, value)
-- `applyFunc` is a global's name, looked up when applied: most definers load
-- after this file. A name with no global behind it applies nothing.
local apply = row.applyFunc
if type(apply) == "string" then apply = getglobal(apply) end
if apply then apply() end
return
end
-- An API row passes the "1"/"0" string, as UIOptionsFrame_Save l.290-297 does.
if row.setFunc then
-- A numeric one passes a number, as OptionsFrame_Save does (l.206-226).
if row.numeric then
row.setFunc(tonumber(value))
else
row.setFunc(value)
end
return
end
SetCVar(row.cvar, value, row.cvarEvent)
OptionsRow_WritePartner(row, value)
end
-- The partner write, from UIOptionsFrame_Save's special arms: Pet Melee Damage also
-- writes PetSpellDamage (l.334-336); the camera speeds write their pitch twin at yaw/4
-- and yaw/2 (l.351-356). A scaled value is formatted like the slider's write, so a
-- partner at its default compares equal and stays out of the config file.
function OptionsRow_WritePartner(row, value)
if not row.partner then return end
local v = value
if row.partner.scale then
v = string.gsub(
string.format("%.2f", tonumber(value) * row.partner.scale), "%.?0+$", "")
end
SetCVar(row.partner.cvar, v)
end
-- The registered default. A uvar's is the value its defining file assigned, captured at
-- the row's OnLoad: all UI XML loads before the saved-variables chunk runs over it.
function OptionsRow_Default(row)
if row.uvar then return row.udefault end
if row.getFunc then return row.fdefault end
return GetCVarDefault(row.cvar)
end
-- A uvar row: OptionsRow_OnLoad's signature with the global's name in the cvar seat.
function OptionsGlobalRow_OnLoad(row, uvar, label, tip, child)
OptionsRow_OnLoad(row, nil, label, tip, child)
row.uvar = uvar
row.udefault = getglobal(uvar)
end
-- An API row, 1.12's `func`/`setFunc` shape. `default` is stated because nothing is
-- registered; the reference hand-writes it too (UIOptionsFrame_SetDefaults l.631-634).
function OptionsFuncRow_OnLoad(row, getFunc, setFunc, default, label, tip, child)
OptionsRow_OnLoad(row, nil, label, tip, child)
row.getFunc = getFunc
row.setFunc = setFunc
row.fdefault = default
end
-- A numeric API row; `default` is still a string, since rows compare strings.
function OptionsNumFuncRow_OnLoad(row, getFunc, setFunc, default, label, tip, child)
OptionsFuncRow_OnLoad(row, getFunc, setFunc, default, label, tip, child)
row.numeric = 1
end
-- Saved uvars land after their file-scope consumers ran; the stock VARIABLES_LOADED arm
-- (UIOptionsFrame.lua l.193-227) re-applies them, so this window has no load ladder.
-- OptionsFrameSliders is the stock video window's table (OptionsFrame.lua l.24-34),
-- which addons write; a declaration here would replace it. This maps its slider index to
-- our Graphics row; 4, 5, 7 and 8 have none, and the holes are why the OnShow loop uses
-- Lua 5.0's `for i, name in` pairs form: ipairs would stop at 3.
BENILLA_GRAPHICS_SLIDER_ROWS = {
"RowUiScale", "RowFarclip", "RowWorldDetail",
[6] = "RowBrightness", [9] = "RowWeatherDensity",
}
-- A slider's range and readout where the template's is not it. The refreshing guard:
-- SetMinMaxValues re-clamps and fires OnValueChanged, which must not write back.
function OptionsSliderRow_Setup(row, min, max, step, fmt, stops)
local slider = getglobal(row:GetName() .. "ControlSlider")
row.fmt = fmt
-- Kept for the "travel" readout, a share of the row's own range.
row.minv, row.maxv = min, max
-- A named ladder reads out its stop (Low/Medium/High). Deviation: 1.12's slider
-- labels only its ends; a bare index would mean nothing to a player.
row.stops = stops
row.refreshing = 1
slider:SetMinMaxValues(min, max)
slider:SetValueStep(step)
row.refreshing = nil
end
-- ── The dropdown rows: the 1.12 UIDropDownMenu kit in the era row grammar ──
-- Entry values are the store's strings; AddButton checks the one equal to selectedValue.
function OptionsDropdownRow_Setup(row, entries)
row.entries = entries
local dd = getglobal(row:GetName() .. "Dropdown")
UIDropDownMenu_SetWidth(180, dd)
UIDropDownMenu_Initialize(dd, OptionsDropdownRow_InitMenu)
-- The capsule's button steals hover from the row, so it carries the row wash too.
local btn = getglobal(dd:GetName() .. "Button")
btn:SetScript("OnEnter", function() OptionsRow_Hover(this:GetParent():GetParent(), 1) end)
btn:SetScript("OnLeave", function() OptionsRow_Hover(this:GetParent():GetParent(), nil) end)
end
function OptionsDropdownRow_InitMenu()
local dd = getglobal(UIDROPDOWNMENU_INIT_MENU)
local row = dd:GetParent()
for _, e in ipairs(row.entries) do
local info = {}
info.text = e.text
info.value = e.value
info.func = OptionsDropdownEntry_OnClick
UIDropDownMenu_AddButton(info)
end
end
-- An entry click (`this` is the list button); the kit closes the list and plays the click.
function OptionsDropdownEntry_OnClick()
local dd = UIDropDownMenu_GetCurrentDropDown()
local row = dd:GetParent()
OptionsRow_Set(row, this.value)
OptionsDropdown_ShowValue(row)
end
-- Paint the capsule from the store. selectedValue is set as a field: SetSelectedValue's
-- Refresh walks the shared DropDownList1 and could match another dropdown's buttons. An
-- off-grid value shows the nearest entry and is not written back.
function OptionsDropdown_ShowValue(row)
local dd = getglobal(row:GetName() .. "Dropdown")
local v = OptionsRow_Get(row)
local match
for _, e in ipairs(row.entries) do
-- `alt`: 1.12's camera dropdown writes "3" for Never, which the nearest-value
-- fallback would show as Always. `e.alt ~= nil` keeps a nil value matching none.
if e.value == v or (e.alt ~= nil and e.alt == v) then match = e end
end
if not match and tonumber(v) then
local best
for _, e in ipairs(row.entries) do
local d = tonumber(e.value) and math.abs(tonumber(e.value) - tonumber(v))
if d and (not best or d < best) then
best = d
match = e
end
end
end
if match then
dd.selectedValue = match.value
UIDropDownMenu_SetText(match.text, dd)
-- An entry with its own `tip` retargets the row's description, as
-- UIOptionsFrameCameraDropDown_OnClick does with OPTION_TOOLTIP_CAMERA<id>.
if match.tip then row.tip = match.tip end
else
dd.selectedValue = v
UIDropDownMenu_SetText(v, dd)
end
end
-- The readout (era MinimalSlider): rounded percent (FormatPercentage, Audio.lua l.406-411).
function OptionsRow_FormatValue(row, value)
if row.fmt == "raw" then
return string.format("%d", math.floor(value + 0.5))
end
-- A named ladder reads its stop's name; the clamp guards a short stops table.
if row.stops then
local i = math.floor(value + 0.5) + 1
if i < 1 then i = 1 end
if i > table.getn(row.stops) then i = table.getn(row.stops) end
return row.stops[i]
end
-- "travel": the thumb's share of the groove. Brightness stores the reference's
-- `1 - gamma` (-0.5 to +0.5, default 0) and reads 0 to 100% with the default at 50.
if row.fmt == "travel" and row.minv and row.maxv and row.maxv > row.minv then
return string.format("%d%%",
math.floor((value - row.minv) / (row.maxv - row.minv) * 100 + 0.5))
end
-- MONKEY (advanced graphics): travel, READ BACKWARDS — the same share of the groove,
-- counted from the right-hand end. The two darkness dials are the case: their stored
-- unit is a GAIN (`nightGain`, `interiorGain`), so the darkest setting is the SMALLEST
-- number and sits at the left of the groove, while the row is named for the darkness
-- rather than the gain. Without this the readout would count UP as the world got
-- LIGHTER under a label that says "Darkness", which is exactly backwards; with it the
-- label, the thumb and the number all agree that further left is darker. The store
-- keeps the gain, unchanged — this is a readout, not a unit.
if row.fmt == "darkness" and row.minv and row.maxv and row.maxv > row.minv then
return string.format("%d%%",
math.floor((row.maxv - value) / (row.maxv - row.minv) * 100 + 0.5))
end
-- A row whose stored value is a FACTOR but whose meaning is a distance: show the
-- distance (decision 1140 — cameraDistanceMaxFactor over the 15 yd base). The number
-- the player is choosing is "how far out the wheel stops", not "times 1.4".
if row.fmt == "yards" then
return string.format(BENILLA_ADVGFX.yards, math.floor(value * 15 + 0.5))
end
-- MONKEY (advanced graphics): a row whose stored value ALREADY IS a distance in yards
-- — the realtime-shadow range. Its own format, because the one above it is a
-- CONVERSION and not a unit: `shadowDistance` rode `"yards"` from the day it was
-- seated, so an 80-yard cascade printed "1200 yd" and nothing caught it (no test read
-- that readout, and 1200 is not an absurd-looking number for a view distance). The
-- two formats differ by exactly the factor's 15 yd base, which is why they cannot be
-- one.
if row.fmt == "yd" then
return string.format(BENILLA_ADVGFX.yards, math.floor(value + 0.5))
end
return string.format("%d%%", math.floor(value * 100 + 0.5))
end
-- The era row-wide hover wash (HoverBackgroundTemplate) and the tooltip, from one seam;
-- crossing controls does not blink, as OnLeave fires before OnEnter within a move.
function OptionsRow_Hover(row, on)
local hover = getglobal(row:GetName() .. "Hover")
if on then
hover:Show()
OptionsRow_ShowTooltip(row)
else
hover:Hide()
GameTooltip:Hide()
end
end
-- The description: 1.12's per-option string alone in the default gold
-- (OptionsFrameTemplates.xml l.52-64), seated the era way (ANCHOR_RIGHT, x -10).
-- Deviation: the era's white name line is cut, as it repeats the label.
function OptionsRow_ShowTooltip(row)
local text = row.tip and getglobal(row.tip)
if text then
GameTooltip:SetOwner(getglobal(row:GetName() .. "Tip"), "ANCHOR_RIGHT", -10, 0)
GameTooltip:SetText(text, nil, nil, nil, nil, 1)
else
-- Deviation: 1.12 returns early here. A mute row hides the last plate, so a hover
-- entered without the old row's OnLeave cannot leave a neighbour's text standing.
GameTooltip:Hide()
end
end
function OptionsCheckbox_OnClick(box)
local row = box:GetParent()
local checked = box:GetChecked()
-- The 1.12 panels disagree: the interface panel plays CheckBoxOn when checked
-- (OptionsFrame.lua l.509), the sound panel CheckBoxOff; Audio rows carry soundQuirk.
local kitOn = checked
if row.soundQuirk then kitOn = not kitOn end
if kitOn then
PlaySound("igMainMenuOptionCheckBoxOn")
else
PlaySound("igMainMenuOptionCheckBoxOff")
end
-- An inverted row (Sticky Targeting, Disable Spam Filter) writes the opposite.
local on = checked
if row.invert then on = not on end
if on then
OptionsRow_Set(row, "1")
else
OptionsRow_Set(row, "0")
end
OptionsPage_UpdateDependencies(BenillaOptionsFrame.selectedCategory)
end
function OptionsSlider_OnValueChanged(slider, value)
local control = slider:GetParent()
local row = control:GetParent()
if not row.refreshing then
-- Era obeyStepOnDrag (MinimalSlider.xml l.5-7): a move snaps to the grid from the
-- minimum (farclip's 1.12 grid is 177+n*60); a refresh sets the stored value raw.
local step = slider:GetValueStep()
if step and step > 0 then
local minv = slider:GetMinMaxValues()
local snapped = minv + math.floor((value - minv) / step + 0.5) * step
if math.abs(snapped - value) > 0.00001 then
slider:SetValue(snapped) -- re-enters once with the snapped value
return
end
value = snapped -- the clean grid number, not the f32-rounded echo
end
end
getglobal(control:GetName() .. "Value"):SetText(OptionsRow_FormatValue(row, value))
if OptionsRow_HasStore(row) and not row.refreshing then
-- Two decimals, trailing zeros stripped, so a value at its default compares
-- equal as a string and stays out of the config file.
local str = string.gsub(string.format("%.2f", value), "%.?0+$", "")
if row.deferred then
-- Era CommitFlag.Apply: shown at once, stored on Apply. A pending equal to
-- the committed value is dropped, as the era's IsModified does.
if str == OptionsRow_Get(row) then
row.pending = nil
else
row.pending = str
end
OptionsApply_Update()
else
OptionsRow_Set(row, str)
end
end
end
function OptionsPage_Refresh(key)
local base = "BenillaOptionsFrameContainerBody" .. key
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
local row = getglobal(base .. rkey)
local box = getglobal(base .. rkey .. "Check")
if box then
-- SetChecked takes the store's string as the 1.12 panel does: "0" unchecks.
-- An inverted row checks on "0" (UIOptionsFrame.lua's GAMEFIELD_DESELECT arm).
if row.invert then
local checked
if OptionsRow_Get(row) == "0" then checked = 1 end
box:SetChecked(checked)
else
box:SetChecked(OptionsRow_Get(row))
end
elseif row.entries then
OptionsDropdown_ShowValue(row)
else
local slider = getglobal(base .. rkey .. "ControlSlider")
row.refreshing = 1
-- A staged value shows first, as the era's GetValue returns it.
slider:SetValue(tonumber(row.pending or OptionsRow_Get(row) or "0") or 0)
row.refreshing = nil
-- SetValue fires only on a change, so the readout is written here, from the
-- slider's own (clamped) value.
getglobal(base .. rkey .. "ControlValue"):SetText(
OptionsRow_FormatValue(row, slider:GetValue()))
end
end
OptionsPage_UpdateDependencies(key)
OptionsApply_Update()
end
-- ── MONKEY (advanced graphics): the page that has to WATCH its settings ─────────────
-- Every other page in this window owns its rows outright: nothing but a click on the page
-- moves the CVars behind it while it is open, so reading them once on select is the whole
-- contract. The lighting rows are not like that, and deliberately so — they are the live
-- A/B knobs the whole system was tuned with, and there are three other ways to move one
-- with this page on screen: `/console set nightGain 1` in chat, the native lighting panel
-- in a dev build, and — the one that matters to a player — the Lighting Quality row above,
-- which does not write its members here at all. It writes ONE CVar; the host's preset
-- table answers by writing the other ten, and those land a frame or two later.
--
-- So the page polls. A cheap signature of its own rows' values, four times a second, and a
-- refresh only when that string actually moves — which is never, on a page nobody is
-- touching. The alternative (an event) does not exist: a host-side CVar write reaches the
-- interface as a mirror update, not as `CVAR_UPDATE`, which the reference only ever fires
-- for a script's own `SetCVar` with a token.
--
-- Safe under a drag, and not by luck: the value the refresh would write back is the value
-- the drag just wrote, `SetValue` fires nothing when it does not change the value, and the
-- `refreshing` guard stops a write even if it did. A staged (deferred) edit is safe too —
-- `OptionsPage_Refresh` shows `row.pending` ahead of the stored value.
BENILLA_ADVGFX_POLL = 0.25
function AdvGfx_Signature()
local out = ""
for _, rkey in ipairs(OPTIONS_PAGE_ROWS.AdvancedGraphics) do
local row = getglobal("BenillaOptionsFrameContainerBodyAdvancedGraphics" .. rkey)
out = out .. "|" .. (OptionsRow_Get(row) or "")
end
return out
end
function AdvGfx_OnUpdate(page, elapsed)
page.since = (page.since or 0) + (elapsed or 0)
if page.since < BENILLA_ADVGFX_POLL then return end
page.since = 0
local sig = AdvGfx_Signature()
if sig == page.sig then return end
page.sig = sig
OptionsPage_Refresh("AdvancedGraphics")
end
-- Per-page dependency rules. Audio's is the 1.12 rule, verbatim: Enable All Sound off
-- greys Enable Ambience — and only it, of our rows
-- (SoundOptionsFrame_UpdateDependencies disables buttons 2 and 4, Ambience and Error
-- Speech; Enable Music stays live, the panel's own quirk).
function OptionsPage_UpdateDependencies(key)
if key == "Combat" then
-- The combat-text block: the master off greys the floating-text rows, and Combo
-- Points is greyed for anyone but a rogue or druid.
local on = SHOW_COMBAT_TEXT ~= "0"
local _, class = UnitClass("player")
class = class and string.upper(class)
local combo = class == "ROGUE" or class == "DRUID"
-- The damage-number trio is not under this master: that block names 53..69 only.
local damage = {
RowShowDamage = 1, RowPeriodicDamage = 1, RowPetDamage = 1,
}
for _, rkey in ipairs(OPTIONS_PAGE_ROWS.Combat) do
if rkey ~= "RowCombatText" and not damage[rkey] then
local live = on
if rkey == "RowComboPoints" and not combo then live = nil end
OptionsRow_SetEnabled(
getglobal("BenillaOptionsFrameContainerBodyCombat" .. rkey), live)
end
end
-- l.709-714: Show Target Damage off greys Periodic and Pet Damage.
local dmg = GetCVar("CombatDamage") ~= "0"
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyCombatRowPeriodicDamage, dmg)
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyCombatRowPetDamage, dmg)
return
end
if key == "AdvancedGraphics" then
-- MONKEY (advanced graphics): the page's own dependencies — the same shape the
-- reference's own rules have (a master's own switch greys what it gates), read
-- off the CVar docs rather than invented: `interiorShadows` "needs
-- interiorLight", the two shadow-rig rows size a cascade that is not rendered
-- with both sun lanes off, and the torch softness is the PCF radius on maps
-- neither torch lane is drawing. The CVars keep their values throughout — this
-- is a dependency, not a write, so turning a master back on finds its children
-- exactly where they were left.
local base = "BenillaOptionsFrameContainerBodyAdvancedGraphics"
local sun = GetCVar("characterShadows") ~= "0"
or GetCVar("worldShadows") ~= "0"
OptionsRow_SetEnabled(getglobal(base .. "RowShadowDistance"), sun)
OptionsRow_SetEnabled(getglobal(base .. "RowShadowResolution"), sun)
local interior = GetCVar("interiorLight") ~= "0"
OptionsRow_SetEnabled(getglobal(base .. "RowInteriorShadows"), interior)
local torch = (interior and GetCVar("interiorShadows") ~= "0")
or GetCVar("exteriorShadows") ~= "0"
OptionsRow_SetEnabled(getglobal(base .. "RowTorchSoft"), torch)
-- MONKEY (daylight: terrain torch casters): the ground only casts for outdoor fires.
OptionsRow_SetEnabled(getglobal(base .. "RowTorchTerrainShadows"),
GetCVar("exteriorShadows") ~= "0")
return
end
if key == "Controls" then
-- l.715-719: Auto-Follow Speed is dead while the style is Never, "0" in the
-- engine's values and "3" as the reference's dropdown writes it.
local style = GetCVar("cameraSmoothStyle")
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyControlsRowAutoFollowSpeed,
style ~= "0" and style ~= "3")
return
end
if key == "Nameplates" then
-- l.702-708: Player Names off greys Player Guild Names.
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyNameplatesRowGuildNames,
GetCVar("UnitNamePlayer") ~= "0")
return
end
if key == "Interface" then
-- l.694-700: the target-of-target mode is dead while its switch is off.
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetMode,
SHOW_TARGET_OF_TARGET ~= "0")
return
end
if key == "ActionBars" then
-- l.722-726: Right ActionBar 2 is dead while Right ActionBar is off.
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyActionBarsRowMultiBar4,
SHOW_MULTI_ACTIONBAR_3)
return
end
if key ~= "Audio" then return end
-- SoundOptionsFrame_UpdateDependencies; Enable Music stays live, as in 1.12.
local on = GetCVar("MasterSoundEffects") ~= "0"
for _, row in {"RowEnableAmbience", "RowEnableErrorSpeech"} do
local box = getglobal("BenillaOptionsFrameContainerBodyAudio"..row.."Check")
local label = getglobal("BenillaOptionsFrameContainerBodyAudio"..row.."Label")
if on then
box:Enable()
label:SetFontObject("GameFontNormal")
else
box:Disable()
label:SetFontObject("GameFontDisable")
end
end
end
-- Grey or wake one row. A dropdown greys as OptionsFrame_DisableDropDown does, button
-- disabled and text gray; 1.12 has no UIDropDownMenu_DisableDropDown.
function OptionsRow_SetEnabled(row, on)
local name = row:GetName()
local box = getglobal(name .. "Check")
local dd = getglobal(name .. "Dropdown")
-- A slider greys as OptionsFrame_DisableSlider does (l.481-486), thumb hidden; it
-- also drops the mouse, since a press anywhere on this track seats the value.
local sl = getglobal(name .. "ControlSlider")
if box then
if on then box:Enable() else box:Disable() end
elseif sl then
local thumb = getglobal(name .. "ControlSliderThumb")
local value = getglobal(name .. "ControlValue")
if on then
sl:EnableMouse(true)
thumb:Show()
value:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g,
NORMAL_FONT_COLOR.b)
else
sl:EnableMouse(false)
thumb:Hide()
value:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b)
end
elseif dd then
local text = getglobal(dd:GetName() .. "Text")
if on then
getglobal(dd:GetName() .. "Button"):Enable()
text:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g,
HIGHLIGHT_FONT_COLOR.b)
else
getglobal(dd:GetName() .. "Button"):Disable()
text:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b)
end
end
local label = getglobal(name .. "Label")
if on then
label:SetFontObject(row.child and "GameFontNormalSmall" or "GameFontNormal")
else
label:SetFontObject(row.child and "GameFontDisableSmall" or "GameFontDisable")
end
end
-- Defaults: the visible page back to its registered defaults, pending edits dropped.
function OptionsPage_Defaults(key)
local base = "BenillaOptionsFrameContainerBody" .. key
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
local row = getglobal(base .. rkey)
row.pending = nil
if not row.preset then
OptionsRow_Set(row, OptionsRow_Default(row))
end
end
-- MONKEY (presets): a preset row goes last, so its default rung (the Graphics
-- Preset's High) is what the page lands on rather than its members' own defaults.
-- `SetCVar` queues only a moved value, so "Custom" (which the host applies as
-- nothing) goes first: the rung is then always a queued write, after the members.
for _, rkey in ipairs(OPTIONS_PAGE_ROWS[key]) do
local row = getglobal(base .. rkey)
if row.preset then
OptionsRow_Set(row, "Custom")
OptionsRow_Set(row, OptionsRow_Default(row))
end
end
OptionsPage_Refresh(key)
end
-- ── The Apply flow: era CommitFlag.Apply ──
-- Pending edits are panel-wide: they survive a category switch; hiding discards them.
-- The era Apply gate (HasUnappliedSettings): shown only while an edit is pending.
function OptionsApply_Update()
local pending
for key, rows in pairs(OPTIONS_PAGE_ROWS) do
local base = "BenillaOptionsFrameContainerBody" .. key
for _, rkey in ipairs(rows) do
if getglobal(base .. rkey).pending then pending = 1 end
end
end
if pending then
BenillaOptionsFrameApplyButton:Enable()
BenillaOptionsFrameApplyButton:Show()
else
BenillaOptionsFrameApplyButton:Disable()
BenillaOptionsFrameApplyButton:Hide()
end
end
-- Commit every pending edit (era SettingsPanelMixin:CommitSettings).
function OptionsPage_Apply()
for key, rows in pairs(OPTIONS_PAGE_ROWS) do
local base = "BenillaOptionsFrameContainerBody" .. key
for _, rkey in ipairs(rows) do
local row = getglobal(base .. rkey)
if row.pending then
OptionsRow_Set(row, row.pending)
row.pending = nil
end
end
end
OptionsApply_Update()
end
-- Hiding discards pending edits (the era's WipeModifiedTable on hide).
function OptionsPage_DiscardPending()
for key, rows in pairs(OPTIONS_PAGE_ROWS) do
local base = "BenillaOptionsFrameContainerBody" .. key
for _, rkey in ipairs(rows) do
getglobal(base .. rkey).pending = nil
end
end
OptionsApply_Update()
end
]]></Script>
<!-- The red panel button (era UIPanelButtonTemplate, 96x22), a copy of
GameMenuButtonTemplate (GameMenuFrame.xml l.145), which loads after this file. -->
<Button name="OptionsRedButtonTemplate" virtual="true">
<Size><AbsDimension x="96" y="22"/></Size>
<ButtonText name="$parentText"/>
<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>
<NormalFont inherits="GameFontHighlight"/>
<HighlightFont inherits="GameFontHighlight"/>
<DisabledFont inherits="GameFontDisable"/>
</Button>
<!-- A category row (era Blizzard_CategoryList.xml), 199 wide as the era ScrollBox stretches
it. The wash is 1.14's OptionsListButtonTemplate (OptionsFrameTemplates.xml l.216-229):
one UI-QuestLogTitleHighlight quad in ADD blend, blue on hover, gold when selected. -->
<Button name="OptionsCategoryRowTemplate" virtual="true">
<Size><AbsDimension x="199" y="20"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentBg" file="Interface\QuestFrame\UI-QuestLogTitleHighlight" alphaMode="ADD" hidden="true">
<Anchors><Anchor point="CENTER"/></Anchors>
</Texture>
</Layer>
</Layers>
<!-- The era label box spans the row (CategoryList.xml l.72-77), so the default middle
justify centres the text vertically; justifyH LEFT keeps it from centring across. -->
<ButtonText name="$parentText" justifyH="LEFT">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="36" y="1"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="1"/></Offset></Anchor>
</Anchors>
</ButtonText>
<NormalFont inherits="GameFontNormal"/>
<HighlightFont inherits="GameFontHighlight"/>
<DisabledFont inherits="GameFontDisable"/>
<Scripts>
<OnClick>BenillaOptionsFrame_SelectCategory(this.categoryKey)</OnClick>
<!-- The hover wash; the selected row keeps its locked gold. -->
<OnEnter>
if BenillaOptionsFrame.selectedCategory ~= this.categoryKey then
getglobal(this:GetName() .. "Bg"):Show()
end
</OnEnter>
<OnLeave>
if BenillaOptionsFrame.selectedCategory ~= this.categoryKey then
getglobal(this:GetName() .. "Bg"):Hide()
end
</OnLeave>
</Scripts>
</Button>
<!-- A category header (era SettingsCategoryListHeaderTemplate); the era's
Options_CategoryHeader_<n> wash has no 1.12 art and is dropped. -->
<Frame name="OptionsCategoryHeaderTemplate" virtual="true">
<Size><AbsDimension x="199" y="30"/></Size>
<Layers>
<Layer level="OVERLAY">
<FontString name="$parentLabel" inherits="OptionsFontHighlightMedium">
<Anchors><Anchor point="LEFT"><Offset><AbsDimension x="20" y="-1"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
<!-- A search group head (era SettingsListSearchCategoryTemplate, Blizzard_SettingsList.xml
l.65-87); a click selects the category, ending the search. Deviation: the hover is the
rows' white 0.1 wash, not the era's gray ADD overlay. -->
<Button name="OptionsSearchHeadTemplate" virtual="true" hidden="true">
<Size><AbsDimension y="45"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentHover" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Color r="1" g="1" b="1" a="0.1"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<FontString name="$parentLabel" inherits="GameFontNormalLarge" justifyH="LEFT">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="16" y="-16"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnClick>BenillaOptionsFrame_SelectCategory(this.categoryKey)</OnClick>
<OnEnter>getglobal(this:GetName() .. "Hover"):Show()</OnEnter>
<OnLeave>getglobal(this:GetName() .. "Hover"):Hide()</OnLeave>
</Scripts>
</Button>
<!-- A checkbox setting row (era SettingsCheckboxControlTemplate, SettingControls.lua
l.322-323, l.473) with the 1.12 UI-CheckBox set. No HighlightTexture: the era row-wide
wash (HoverBackgroundTemplate) is the hover. -->
<Frame name="OptionsCheckboxRowTemplate" virtual="true" enableMouse="true">
<Size><AbsDimension y="26"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentHover" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-10" y="0"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-5" y="0"/></Offset></Anchor>
</Anchors>
<Color r="1" g="1" b="1" a="0.1"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="$parentLabel" inherits="GameFontNormal" justifyH="LEFT">
<Anchors>
<Anchor point="LEFT"><Offset><AbsDimension x="37" y="0"/></Offset></Anchor>
<Anchor point="RIGHT" relativePoint="CENTER"><Offset><AbsDimension x="-85" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The tooltip seat, the era's label-half region (Blizzard_SettingControls.xml
l.57-61); mouse-less so it never steals the row's hover. -->
<Frame name="$parentTip">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM"><Offset><AbsDimension x="-80" y="0"/></Offset></Anchor>
</Anchors>
</Frame>
<CheckButton name="$parentCheck">
<Size><AbsDimension x="30" y="29"/></Size>
<Anchors><Anchor point="LEFT" relativePoint="CENTER"><Offset><AbsDimension x="-80" y="0"/></Offset></Anchor></Anchors>
<NormalTexture file="Interface\Buttons\UI-CheckBox-Up"/>
<PushedTexture file="Interface\Buttons\UI-CheckBox-Down"/>
<CheckedTexture file="Interface\Buttons\UI-CheckBox-Check"/>
<DisabledCheckedTexture file="Interface\Buttons\UI-CheckBox-Check-Disabled"/>
<Scripts>
<OnClick>OptionsCheckbox_OnClick(this)</OnClick>
<OnEnter>OptionsRow_Hover(this:GetParent(), 1)</OnEnter>
<OnLeave>OptionsRow_Hover(this:GetParent(), nil)</OnLeave>
</Scripts>
</CheckButton>
</Frames>
<Scripts>
<OnEnter>OptionsRow_Hover(this, 1)</OnEnter>
<OnLeave>OptionsRow_Hover(this, nil)</OnLeave>
</Scripts>
</Frame>
<!-- A slider setting row (era SettingsSliderControlTemplate, SettingControls.lua l.550-552):
the 1.12 OptionsSliderTemplate groove (OptionsFrameTemplates.xml l.74) and 32x32 thumb,
and the era readout 6 right (MinimalSlider.xml l.73-77). No era steppers, as in 1.12; a
press anywhere on the track seats the thumb. The +3 seats the art, not the control, so
the readout stays level with the label. -->
<Frame name="OptionsSliderRowTemplate" virtual="true" enableMouse="true">
<Size><AbsDimension y="26"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentHover" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-10" y="0"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-5" y="0"/></Offset></Anchor>
</Anchors>
<Color r="1" g="1" b="1" a="0.1"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="$parentLabel" inherits="GameFontNormal" justifyH="LEFT">
<Anchors>
<Anchor point="LEFT"><Offset><AbsDimension x="37" y="0"/></Offset></Anchor>
<Anchor point="RIGHT" relativePoint="CENTER"><Offset><AbsDimension x="-85" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The tooltip seat. Deviation: the era hangs a slider's plate off the slider
(SettingControls.lua l.556); one column keeps it still down a page. -->
<Frame name="$parentTip">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM"><Offset><AbsDimension x="-80" y="0"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="$parentControl">
<Size><AbsDimension x="250" y="40"/></Size>
<Anchors><Anchor point="LEFT" relativePoint="CENTER"><Offset><AbsDimension x="-80" y="0"/></Offset></Anchor></Anchors>
<Layers>
<Layer level="OVERLAY">
<FontString name="$parentValue" inherits="GameFontNormal">
<Anchors><Anchor point="LEFT" relativePoint="RIGHT"><Offset><AbsDimension x="6" y="0"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The groove, declared before the Slider so the thumb draws above it. -->
<Frame name="$parentGroove">
<Size><AbsDimension y="17"/></Size>
<Anchors>
<Anchor point="LEFT"><Offset><AbsDimension x="19" y="3"/></Offset></Anchor>
<Anchor point="RIGHT"><Offset><AbsDimension x="-19" y="3"/></Offset></Anchor>
</Anchors>
<Backdrop bgFile="Interface\Buttons\UI-SliderBar-Background" edgeFile="Interface\Buttons\UI-SliderBar-Border" tile="true">
<EdgeSize><AbsValue val="8"/></EdgeSize>
<TileSize><AbsValue val="8"/></TileSize>
<BackgroundInsets><AbsInset left="3" right="3" top="6" bottom="6"/></BackgroundInsets>
</Backdrop>
</Frame>
<Slider name="$parentSlider" orientation="HORIZONTAL" minValue="0" maxValue="1" valueStep="0.05">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="19" y="3"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-19" y="3"/></Offset></Anchor>
</Anchors>
<ThumbTexture name="$parentThumb" file="Interface\Buttons\UI-SliderBar-Button-Horizontal">
<Size><AbsDimension x="32" y="32"/></Size>
</ThumbTexture>
<Scripts>
<OnValueChanged>OptionsSlider_OnValueChanged(this, arg1)</OnValueChanged>
<OnEnter>OptionsRow_Hover(this:GetParent():GetParent(), 1)</OnEnter>
<OnLeave>OptionsRow_Hover(this:GetParent():GetParent(), nil)</OnLeave>
</Scripts>
</Slider>
</Frames>
</Frame>
</Frames>
<Scripts>
<OnEnter>OptionsRow_Hover(this, 1)</OnEnter>
<OnLeave>OptionsRow_Hover(this, nil)</OnLeave>
</Scripts>
</Frame>
<!-- A dropdown setting row (era SettingsDropdownControlTemplate): the 1.12
UIDropDownMenuTemplate capsule at CENTER-71, so its ink (after about 10 units of cap)
opens at the groove's column, 180 wide to match the track. -->
<Frame name="OptionsDropdownRowTemplate" virtual="true" enableMouse="true">
<Size><AbsDimension y="26"/></Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentHover" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-10" y="0"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-5" y="0"/></Offset></Anchor>
</Anchors>
<Color r="1" g="1" b="1" a="0.1"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<FontString name="$parentLabel" inherits="GameFontNormal" justifyH="LEFT">
<Anchors>
<Anchor point="LEFT"><Offset><AbsDimension x="37" y="0"/></Offset></Anchor>
<Anchor point="RIGHT" relativePoint="CENTER"><Offset><AbsDimension x="-85" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The tooltip seat, as on the checkbox row. -->
<Frame name="$parentTip">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT" relativePoint="BOTTOM"><Offset><AbsDimension x="-80" y="0"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="$parentDropdown" inherits="UIDropDownMenuTemplate">
<Anchors><Anchor point="LEFT" relativePoint="CENTER"><Offset><AbsDimension x="-71" y="-2"/></Offset></Anchor></Anchors>
</Frame>
</Frames>
<Scripts>
<OnEnter>OptionsRow_Hover(this, 1)</OnEnter>
<OnLeave>OptionsRow_Hover(this, nil)</OnLeave>
</Scripts>
</Frame>
<!-- The window (era SettingsPanel: 920x724, CENTER), toplevel as 1.12's OptionsFrame.xml
l.3. Deviation: strata HIGH, the era SettingsPanel's, where 1.12's is DIALOG. -->
<Frame name="BenillaOptionsFrame" parent="UIParent" frameStrata="HIGH" toplevel="true" enableMouse="true" hidden="true">
<Size><AbsDimension x="920" y="724"/></Size>
<Anchors><Anchor point="CENTER"/></Anchors>
<!-- The 1.14 System window backdrop, BACKDROP_DIALOG_32_32 (Backdrop.lua l.17-25): the
UI-DialogBox-Background tile, uniform black at 0.6 alpha, inside the rope border. -->
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<TileSize><AbsValue val="32"/></TileSize>
<EdgeSize><AbsValue val="32"/></EdgeSize>
<BackgroundInsets><AbsInset left="11" right="12" top="12" bottom="11"/></BackgroundInsets>
</Backdrop>
<Layers>
<Layer level="BACKGROUND">
<!-- A black 0.7 fill over the 0.6 tile (0.88 combined) so labels read over bright
terrain. Inset 15, not the bg insets: regions draw over the border, whose ink
ends by texel 14. -->
<Texture name="$parentGroundDim">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="15" y="-15"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-15" y="15"/></Offset></Anchor>
</Anchors>
<Color r="0" g="0" b="0" a="0.7"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- The title plate at the 1.14 seat (OptionsFrameTemplates.xml l.244-255). -->
<Texture name="$parentHeader" file="Interface\DialogFrame\UI-DialogBox-Header">
<Size><AbsDimension x="300" y="68"/></Size>
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="12"/></Offset></Anchor></Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- The title on the plate, as a 1.12 dialog carries it. Not GameFontNormalMed1:
GameMenuFrame.xml declares that after this file. -->
<FontString name="$parentTitleText" inherits="GameFontNormal" text="Options">
<Anchors>
<Anchor point="TOP" relativeTo="$parentHeader"><Offset><AbsDimension x="0" y="-14"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The two boxes, 1.14's OptionsFrameListTemplate (OptionsFrameTemplates.xml
l.113-116): outlines, fill alpha 0, border LIGHTGRAY_FONT_COLOR. Declared first
so siblings draw above. Deviation: tops at -52, not 1.14's -40, to clear the
search box. -->
<Frame name="$parentCategoryBox">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-52"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-695" y="38"/></Offset></Anchor>
</Anchors>
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize><AbsValue val="16"/></EdgeSize>
<TileSize><AbsValue val="16"/></TileSize>
<BackgroundInsets><AbsInset left="5" right="5" top="5" bottom="5"/></BackgroundInsets>
</Backdrop>
<Scripts>
<OnLoad>
this:SetBackdropColor(0, 0, 0, 0)
this:SetBackdropBorderColor(0.6, 0.6, 0.6)
</OnLoad>
</Scripts>
</Frame>
<Frame name="$parentPageBox">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="225" y="-52"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-14" y="39"/></Offset></Anchor>
</Anchors>
<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize><AbsValue val="16"/></EdgeSize>
<TileSize><AbsValue val="16"/></TileSize>
<BackgroundInsets><AbsInset left="5" right="5" top="5" bottom="5"/></BackgroundInsets>
</Backdrop>
<Scripts>
<OnLoad>
this:SetBackdropColor(0, 0, 0, 0)
this:SetBackdropBorderColor(0.6, 0.6, 0.6)
</OnLoad>
</Scripts>
</Frame>
<!-- The tabs, seated the 1.14 way on the category box (InterfaceOptionsFrame.xml
l.152-158), with the era MinimalTab's width and text. Static: only Game has pages.
Each plate is one UI-Character tab piece at the era heights, flipped vertically,
since 1.12 ships only bottom-tab plates. -->
<Button name="$parentGameTab">
<Size><AbsDimension x="72" y="37"/></Size>
<Anchors>
<Anchor point="BOTTOMLEFT" relativeTo="$parentCategoryBox" relativePoint="TOPLEFT"><Offset><AbsDimension x="6" y="-3"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="$parentPlate" file="Interface\PaperDollInfoFrame\UI-Character-ActiveTab">
<Size><AbsDimension y="26"/></Size>
<Anchors>
<Anchor point="BOTTOMLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<TexCoords left="0" right="1" top="1" bottom="0"/>
</Texture>
</Layer>
</Layers>
<ButtonText name="$parentText" text="Game">
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="6"/></Offset></Anchor></Anchors>
</ButtonText>
<NormalFont inherits="GameFontHighlightSmall"/>
<HighlightFont inherits="GameFontHighlightSmall"/>
<DisabledFont inherits="GameFontHighlightSmall"/>
<Scripts>
<OnShow>OptionsTab_FitWidth(self)</OnShow>
</Scripts>
</Button>
<Button name="$parentAddOnsTab">
<Size><AbsDimension x="87" y="37"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentGameTab" relativePoint="TOPRIGHT"><Offset><AbsDimension x="5" y="0"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="$parentPlate" file="Interface\PaperDollInfoFrame\UI-Character-InActiveTab">
<Size><AbsDimension y="23"/></Size>
<Anchors>
<Anchor point="BOTTOMLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<TexCoords left="0" right="1" top="1" bottom="0"/>
</Texture>
</Layer>
</Layers>
<ButtonText name="$parentText" text="AddOns">
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="4"/></Offset></Anchor></Anchors>
</ButtonText>
<NormalFont inherits="GameFontNormalSmall"/>
<HighlightFont inherits="GameFontNormalSmall"/>
<DisabledFont inherits="GameFontNormalSmall"/>
<!-- No addon list behind it: disabled, but in the era's unselected gold. -->
<Scripts>
<OnLoad>self:Disable()</OnLoad>
<OnShow>OptionsTab_FitWidth(self)</OnShow>
</Scripts>
</Button>
<!-- ── The category list (era CategoryList; static, it fits) ── -->
<Frame name="$parentCategoryList">
<Size><AbsDimension x="199"/></Size>
<!-- The top: the box top (-52) plus the era's 12-unit list-to-box pad. -->
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="18" y="-64"/></Offset></Anchor>
<Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="18" y="46"/></Offset></Anchor>
</Anchors>
<!-- The era list rhythm: spacing 2, and an 18-tall spacer between groups. -->
<Frames>
<Frame name="$parentHeaderGameplay" inherits="OptionsCategoryHeaderTemplate">
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<Scripts>
<OnLoad>getglobal(self:GetName() .. "Label"):SetText("Gameplay")</OnLoad>
</Scripts>
</Frame>
<Button name="$parentRowControls" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentHeaderGameplay" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Controls", "Controls")</OnLoad></Scripts>
</Button>
<Button name="$parentRowInterface" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowControls" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Interface", "Interface")</OnLoad></Scripts>
</Button>
<Button name="$parentRowActionBars" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowInterface" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "ActionBars", "Action Bars")</OnLoad></Scripts>
</Button>
<Button name="$parentRowCombat" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowActionBars" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Combat", "Combat")</OnLoad></Scripts>
</Button>
<Button name="$parentRowChat" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowCombat" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Chat", "Chat")</OnLoad></Scripts>
</Button>
<Button name="$parentRowKeybindings" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowChat" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Keybindings", "Keybindings")</OnLoad></Scripts>
</Button>
<!-- The era Gameplay group's last row (NAMEPLATE_OPTIONS_LABEL). -->
<Button name="$parentRowNameplates" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowKeybindings" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Nameplates", "Nameplates")</OnLoad></Scripts>
</Button>
<Frame name="$parentHeaderSystem" inherits="OptionsCategoryHeaderTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowNameplates" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-22"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnLoad>getglobal(self:GetName() .. "Label"):SetText("System")</OnLoad>
</Scripts>
</Frame>
<Button name="$parentRowGraphics" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentHeaderSystem" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Graphics", "Graphics")</OnLoad></Scripts>
</Button>
<!-- MONKEY (advanced graphics): under Graphics, which is what it refines. Its
label is the one category label in this tree that is not a literal — the
page is bilingual, so the row (and the page title it doubles as) reads
the selected column like every other string on it. -->
<Button name="$parentRowAdvancedGraphics" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowGraphics" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "AdvancedGraphics", BENILLA_ADVGFX.page)</OnLoad></Scripts>
</Button>
<Button name="$parentRowAudio" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowAdvancedGraphics" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "Audio", "Audio")</OnLoad></Scripts>
</Button>
</Frames>
</Frame>
<!-- ── The page area (era SettingsList) ── -->
<Frame name="$parentContainer">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentCategoryList" relativePoint="TOPRIGHT"><Offset><AbsDimension x="16" y="0"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-22" y="47"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<!-- The era options_horizontaldivider at (TOP, -50), as the colour fill
it is: a 630x1 white row at about 0.3 alpha (atlas fdid 1318750). -->
<Texture name="$parentDivider">
<Size><AbsDimension y="1"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="-50"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-50"/></Offset></Anchor>
</Anchors>
<Color r="1" g="1" b="1" a="0.3"/>
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- The page title, written by BenillaOptionsFrame_SelectCategory. -->
<FontString name="$parentTitle" inherits="OptionsFontHighlightHuge">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="7" y="-22"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- On the Keybindings page, 1.12's Reset To Default behind a confirm. -->
<Button name="$parentDefaults" inherits="OptionsRedButtonTemplate" text="Defaults">
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-36" y="-16"/></Offset></Anchor></Anchors>
<Scripts>
<OnLoad>self:Disable()</OnLoad>
<OnClick>
if BenillaOptionsFrame.selectedCategory == "Keybindings" then
StaticPopup_Show("CONFIRM_RESET_KEYBINDINGS")
else
OptionsPage_Defaults(BenillaOptionsFrame.selectedCategory)
end
</OnClick>
</Scripts>
</Button>
<!-- 1.12's Unbind Key: Keybindings only, live while a capsule is selected. -->
<Button name="$parentUnbind" inherits="OptionsRedButtonTemplate" hidden="true">
<Anchors><Anchor point="RIGHT" relativeTo="$parentDefaults" relativePoint="LEFT"><Offset><AbsDimension x="-2" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnLoad>
self:SetText(KeyBindings_String("UNBIND", "Unbind Key"))
self:Disable()
</OnLoad>
<OnClick>
PlaySound("igMainMenuOptionCheckBoxOn")
KeyBindings_Unbind()
</OnClick>
</Scripts>
</Button>
<!-- The page area scrolls, as the era SettingsList's ScrollBox does
(Blizzard_SettingsList.xml l.48-58); a bar shows only when content
outgrows the rect. enableMouse catches the wheel over blank area. -->
<ScrollFrame name="$parentScroll" enableMouse="true">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-50"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Scripts>
<!-- The loader fires OnLoad bottom-up, so the body already exists. -->
<OnLoad>self:SetScrollChild(BenillaOptionsFrameContainerBody)</OnLoad>
<OnUpdate>OptionsScroll_Fit()</OnUpdate>
<OnMouseWheel>BenillaScroll_OnMouseWheel(this, arg1)</OnMouseWheel>
<OnVerticalScroll>BenillaScroll_SyncBar(this)</OnVerticalScroll>
<OnScrollRangeChanged>BenillaScroll_SyncBar(this)</OnScrollRangeChanged>
</Scripts>
<Frames>
<!-- The bar's trough seats itself on the bar its name minus "Trough"
names (BenillaScrollTrough_Seat). Declared before the body and the
bar so it draws beneath both. -->
<Frame name="$parentBarTrough" inherits="BenillaScrollTroughTemplate"/>
<!-- The page body. Named in full so every page and row name derives
from it. Sized, not anchored: SetScrollChild pins its TOPLEFT and
OptionsScroll_Fit keeps the size. -->
<Frame name="BenillaOptionsFrameContainerBody">
<Size><AbsDimension x="665" y="563"/></Size>
<Layers>
<Layer level="OVERLAY">
<!-- The no-match line (era SETTINGS_SEARCH_NOTHING_FOUND, at
the section header's seat). -->
<FontString name="$parentNoResults" inherits="GameFontHighlightLarge" justifyH="LEFT" hidden="true" text="No results found.">
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="17" y="-28"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The Controls page. Labels are 1.12's GlobalStrings, the
era's for Auto Loot. Sticky Targeting is inverted in both
clients (1.12 checks it on deselectOnClick "0"). -->
<Frame name="$parentControls" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowStickyTarget" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "deselectOnClick", "Sticky Targeting",
"OPTION_TOOLTIP_GAMEFIELD_DESELECT")
self.invert = 1
</OnLoad></Scripts>
</Frame>
<!-- Labels verbatim, ASSIST_ATTACK's sentence case too. -->
<Frame name="$parentRowAssistAttack" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowStickyTarget" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowStickyTarget" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "assistAttack", "Attack on assist",
"OPTION_TOOLTIP_ASSIST_ATTACK")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowClearAFK" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAssistAttack" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAssistAttack" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "autoClearAFK", "Auto Clear AFK",
"OPTION_TOOLTIP_CLEAR_AFK")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowBlockTrades" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowClearAFK" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowClearAFK" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "BlockTrades", "Block Trades",
"OPTION_TOOLTIP_BLOCK_TRADES")</OnLoad></Scripts>
</Frame>
<!-- Deviation: ships "1" where 1.12 registers "0"
(`cvars::REGISTERED`): off, a friendly cast falls
into the targeting cursor, which is not modelled. -->
<Frame name="$parentRowAutoSelfCast" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowBlockTrades" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowBlockTrades" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "autoSelfCast", "Auto Self Cast",
"OPTION_TOOLTIP_AUTO_SELF_CAST")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAutoLoot" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAutoSelfCast" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAutoSelfCast" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<!-- No tip: 1.12 has no AUTO_LOOT string. -->
<Scripts><OnLoad>OptionsRow_OnLoad(self, "autoLootDefault", "Auto Loot")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowInvertMouse" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAutoLoot" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAutoLoot" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "mouseInvertPitch", "Invert Mouse",
"OPTION_TOOLTIP_INVERT_MOUSE")</OnLoad></Scripts>
</Frame>
<!-- The reference's range and step. -->
<Frame name="$parentRowMouseSpeed" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowInvertMouse" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowInvertMouse" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "mousespeed", "Mouse Sensitivity",
"OPTION_TOOLTIP_MOUSE_SENSITIVITY")
OptionsSliderRow_Setup(self, 0.5, 1.5, 0.05)
</OnLoad></Scripts>
</Frame>
<!-- 1.12's UIOptionsFrameCameraDropDown, with its
tooltips. Deviation: values are the engine's 0/1/2;
1.12 writes 3 for Never, which its terrain-tilt
consumer reads past its table's end. -->
<Frame name="$parentRowCameraFollowStyle" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMouseSpeed" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMouseSpeed" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraSmoothStyle",
"Camera Following Style", "OPTION_TOOLTIP_CAMERA1")
OptionsDropdownRow_Setup(self, {
{ text = "Smart", value = "1", tip = "OPTION_TOOLTIP_CAMERA1" },
{ text = "Always", value = "2", tip = "OPTION_TOOLTIP_CAMERA2" },
{ text = "Never", value = "0", alt = "3", tip = "OPTION_TOOLTIP_CAMERA3" },
})
</OnLoad></Scripts>
</Frame>
<!-- The 1.12 camera toggles and speed sliders. -->
<Frame name="$parentRowFollowTerrain" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowCameraFollowStyle" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowCameraFollowStyle" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraTerrainTilt", "Follow Terrain",
"OPTION_TOOLTIP_FOLLOW_TERRAIN")
</OnLoad></Scripts>
</Frame>
<!-- First person only, as in 1.12: the gate requires
`[cam+0xec] <= 1/6` on the zoom distance. -->
<Frame name="$parentRowHeadBob" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFollowTerrain" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFollowTerrain" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraBobbing", "Head Bob",
"OPTION_TOOLTIP_HEAD_BOB")
</OnLoad></Scripts>
</Frame>
<!-- UIOptionsFrameSliders row 2. Deviation: no partner
write of cameraPitchSmoothSpeed, which has no reader:
the follow here has one rate. -->
<Frame name="$parentRowAutoFollowSpeed" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowHeadBob" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowHeadBob" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraYawSmoothSpeed", "Auto-Follow Speed",
"OPTION_TOOLTIP_AUTO_FOLLOW_SPEED")
OptionsSliderRow_Setup(self, 90, 270, 10, "raw")
</OnLoad></Scripts>
</Frame>
<!-- One CVar, two consumers that move together: the
`0xf0000` nibble in `0x50e570`'s trace mask, and
`0x50e629`'s pivot floor and cap test. -->
<Frame name="$parentRowWaterCollision" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAutoFollowSpeed" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAutoFollowSpeed" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraWaterCollision", "Water Collision",
"OPTION_TOOLTIP_WATER_COLLISION")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowSmartPivot" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowWaterCollision" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowWaterCollision" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraPivot", "Smart Pivot",
"OPTION_TOOLTIP_SMART_PIVOT")
</OnLoad></Scripts>
</Frame>
<!-- UIOptionsFrameSliders row 3, with the partner write
of cameraPitchMoveSpeed at half (l.355-356). -->
<Frame name="$parentRowMouseLookSpeed" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSmartPivot" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSmartPivot" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraYawMoveSpeed", "Mouse Look Speed",
"OPTION_TOOLTIP_MOUSE_LOOK_SPEED")
OptionsSliderRow_Setup(self, 90, 270, 10, "raw")
self.partner = { cvar = "cameraPitchMoveSpeed", scale = 0.5 }
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMaxCameraDistance" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMouseLookSpeed" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMouseLookSpeed" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "cameraDistanceMaxFactor",
"Max Camera Distance", "OPTION_TOOLTIP_MAX_FOLLOW_DIST")
OptionsSliderRow_Setup(self, 1.0, 2.0, 0.1, "yards")
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Audio page: the era order (volumes, then enables) over
the 1.12 rows; the three volumes are children of Master, in
SoundOptionsFrame.lua's order. -->
<Frame name="$parentAudio" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowEnableAll" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "MasterSoundEffects", "Enable All Sound",
"OPTION_TOOLTIP_ENABLE_ALL_SOUND")
self.soundQuirk = 1
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMaster" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnableAll" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnableAll" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "MasterVolume", "Master Volume",
"OPTION_TOOLTIP_MASTER_VOLUME")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowSound" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMaster" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMaster" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "SoundVolume", "Sound Volume",
"OPTION_TOOLTIP_SOUND_VOLUME", 1)
-- Era parentInitializer (SettingsPanel.lua l.665).
self.parentRow = "RowMaster"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMusic" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSound" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSound" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "MusicVolume", "Music Volume",
"OPTION_TOOLTIP_MUSIC_VOLUME", 1)
self.parentRow = "RowMaster"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAmbience" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMusic" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMusic" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "AmbienceVolume", "Ambience Volume",
"OPTION_TOOLTIP_AMBIENCE_VOLUME", 1)
self.parentRow = "RowMaster"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowEnableMusic" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAmbience" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAmbience" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "EnableMusic", "Enable Music",
"OPTION_TOOLTIP_ENABLE_MUSIC")
self.soundQuirk = 1
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowEnableAmbience" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnableMusic" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnableMusic" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "EnableAmbience", "Enable Ambience",
"OPTION_TOOLTIP_ENABLE_AMBIENCE")
self.soundQuirk = 1
</OnLoad></Scripts>
</Frame>
<!-- 1.12's checkbox 4 (SoundOptionsFrame.lua l.2). -->
<Frame name="$parentRowEnableErrorSpeech" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnableAmbience" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnableAmbience" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "EnableErrorSpeech", "Enable Error Speech",
"OPTION_TOOLTIP_ENABLE_ERROR_SPEECH")
self.soundQuirk = 1
</OnLoad></Scripts>
</Frame>
<!-- Deviation: an era row; 1.12 always mutes when the
window loses focus, which off matches. soundQuirk is
the panel's, so it applies here too. -->
<Frame name="$parentRowBackgroundSound" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnableErrorSpeech" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnableErrorSpeech" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "Sound_EnableSoundWhenGameIsInBG",
"Enable Sound in Background",
"BENILLA_TOOLTIP_BACKGROUND_SOUND")
self.soundQuirk = 1
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Graphics page: 1.12's OptionsFrameSliders rows that have
a knob, bounds read from the table. Deviation: no useUiScale
checkbox; the UI scale always applies. -->
<Frame name="$parentGraphics" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowUiScale" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "uiScale", "UI Scale",
"OPTION_TOOLTIP_UI_SCALE")
OptionsSliderRow_Setup(self, OptionsFrameSliders[1].minValue,
OptionsFrameSliders[1].maxValue,
OptionsFrameSliders[1].valueStep)
-- Era CommitFlag.Apply (Graphics.lua l.684): a
-- live write would rescale the slider mid-drag.
self.deferred = 1
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowFarclip" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowUiScale" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowUiScale" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "farclip", "Terrain Distance",
"OPTION_TOOLTIP_FARCLIP")
OptionsSliderRow_Setup(self, OptionsFrameSliders[2].minValue,
OptionsFrameSliders[2].maxValue,
OptionsFrameSliders[2].valueStep, "raw")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowWorldDetail" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFarclip" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFarclip" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "WorldDetail", "Environment Detail",
"OPTION_TOOLTIP_ENVIRONMENT_DETAIL")
-- Stop names from the era quality ladder.
OptionsSliderRow_Setup(self, OptionsFrameSliders[3].minValue,
OptionsFrameSliders[3].maxValue,
OptionsFrameSliders[3].valueStep, nil,
{ "Low", "Medium", "High" })
</OnLoad></Scripts>
</Frame>
<!-- The reference's slider 6 (`func = "Gamma"`): an API
row over GetGamma/SetGamma, whose unit is 1 - gamma;
writing `gamma` directly would invert the control. -->
<Frame name="$parentRowBrightness" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowWorldDetail" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowWorldDetail" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- OptionsFrame_SetDefaults' default (l.441-445);
-- `or 1` covers a VM with no CVars.
local gd = tonumber(GetCVarDefault("gamma")) or 1
OptionsNumFuncRow_OnLoad(self, GetGamma, SetGamma,
tostring(1 - gd), "Brightness",
"BENILLA_TOOLTIP_BRIGHTNESS")
OptionsSliderRow_Setup(self, OptionsFrameSliders[6].minValue,
OptionsFrameSliders[6].maxValue,
OptionsFrameSliders[6].valueStep, "travel")
</OnLoad></Scripts>
</Frame>
<!-- The reference's slider 9, on the CVar directly, as
1.12's lands: with no SetweatherDensity global,
OptionsFrame_Save falls through to SetCVar. -->
<Frame name="$parentRowWeatherDensity" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowBrightness" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowBrightness" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "weatherDensity", "Weather Intensity",
"OPTION_TOOLTIP_WEATHER_DETAIL")
-- Our stop names for the reference's rates:
-- `0x67b870` maps 0 to 3 onto the spawn-rate gains
-- {0.1, 0.33, 0.66, 1.0} in `[0x8680ec]`.
OptionsSliderRow_Setup(self, OptionsFrameSliders[9].minValue,
OptionsFrameSliders[9].maxValue,
OptionsFrameSliders[9].valueStep, nil,
{ "Minimal", "Low", "Medium", "Full" })
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowDisplayMode" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowWeatherDensity" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowWeatherDensity" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Deviation: modern Classic's two-entry Display
-- Mode dropdown (Graphics.lua in
-- Blizzard_SettingsDefinitions_Shared), as there
-- is no exclusive fullscreen; gxWindow "0" is the
-- borderless window. Applies on the click.
OptionsRow_OnLoad(self, "gxWindow", "Display Mode",
"BENILLA_TOOLTIP_DISPLAY_MODE")
OptionsDropdownRow_Setup(self, {
{ text = "Windowed (Fullscreen)", value = "0" },
{ text = "Windowed", value = "1" },
})
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowVerticalSync" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowDisplayMode" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowDisplayMode" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- 1.12's Video Options checkbox 5. Not deferred
-- despite its gxRestart = 1: the present mode
-- changes live.
OptionsRow_OnLoad(self, "gxVSync", "Vertical Sync",
"OPTION_TOOLTIP_VERTICAL_SYNC")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (advanced graphics): Real Character Shadows,
World Shadows and Shadow Distance stood here between
Vertical Sync and Render Scale. They are the Advanced
Graphics page's now, unchanged — same CVars, same
labels, same descriptions, same deferred commit on the
slider — because they are three rows of one rig whose
other fifteen a player could not reach at all. -->
<Frame name="$parentRowRenderScale" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowVerticalSync" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowVerticalSync" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Deviation: benilla's own row (the reference draws
-- to the backbuffer), and no Multisampling row,
-- which misses alpha-tested cutouts. Deferred: a
-- live write rebuilds the world render target on
-- every drag tick.
OptionsRow_OnLoad(self, "renderScale", "Render Scale",
"BENILLA_TOOLTIP_RENDER_SCALE")
OptionsSliderRow_Setup(self, 0.5, 2.0, 0.05)
self.deferred = 1
</OnLoad></Scripts>
</Frame>
</Frames>
<!-- Re-apply OptionsFrameSliders' bounds on show, as
OptionsFrame_Load does, so an addon's write (pfUI's
hdgraphic) reaches the slider. fmt and stops are ours. -->
<Scripts>
<OnShow>
for i, name in BENILLA_GRAPHICS_SLIDER_ROWS do
local info = OptionsFrameSliders[i]
local row = getglobal(this:GetName() .. name)
if ( info and row ) then
OptionsSliderRow_Setup(row, info.minValue, info.maxValue,
info.valueStep, row.fmt, row.stops)
end
end
</OnShow>
</Scripts>
</Frame>
<!-- ══ MONKEY (advanced graphics): the ADVANCED GRAPHICS page ═══
The dynamic light and shadow system, as a page a player can
reach. Nothing here is a new mechanism: every row is a seat on
a CVar this client already registers, reads per frame and
persists, and the page is built out of the same three row
templates and the same OptionsRow_* store as every page above
it. What it adds is a way in — before it, a player build had
none, because the native lighting panel is a dev-build window
and `/console` is not a setting.
Order is coarse to fine, and each master sits above what it
gates: the preset (which writes the rest), the sun rig, the
room lane with its torches, the invented lights, the two
darkness dials. The three rows that moved here from Graphics
keep their CVars, labels, descriptions and — on Shadow
Distance — the deferred commit, verbatim.
Every label and description is bilingual (BENILLA_ADVGFX);
every VALUE written stays the engine's own string. -->
<Frame name="$parentAdvancedGraphics" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<!-- MONKEY (presets): the Graphics Preset. Like Lighting
Quality below it, ONE CVar: the host's
`cvars::GRAPHICS_PRESETS` writes the rows and
re-derives this one every frame. -->
<Frame name="$parentRowGraphicsQuality" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "graphicsQuality",
BENILLA_ADVGFX.graphicsQuality,
"BENILLA_TOOLTIP_GRAPHICS_QUALITY")
self.preset = 1
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.pClassic, value = "Classic" },
{ text = BENILLA_ADVGFX.qLow, value = "Low" },
{ text = BENILLA_ADVGFX.qMedium, value = "Medium" },
{ text = BENILLA_ADVGFX.qHigh, value = "High" },
{ text = BENILLA_ADVGFX.qUltra, value = "Ultra" },
{ text = BENILLA_ADVGFX.qCustom, value = "Custom" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (presets): `farclip`, the Graphics page's Terrain
Distance, on the extended range (`view::FARCLIP_RANGE`,
177..1497 on the 1.12 grid of 60). Live like its
Graphics twin; both read the one CVar. -->
<Frame name="$parentRowRenderDistance" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowGraphicsQuality" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowGraphicsQuality" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "farclip",
BENILLA_ADVGFX.renderDistance,
"BENILLA_TOOLTIP_RENDER_DISTANCE")
OptionsSliderRow_Setup(self, 177, 1497, 60, "yd")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowLightingQuality" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowRenderDistance" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowRenderDistance" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- The preset ladder. This row writes ONE CVar and
-- nothing else: the host's own table
-- (`cvars::LIGHTING_PRESETS`) answers the write by
-- setting the member rows, and re-derives this
-- row's value from them every frame — which is why
-- Custom is an entry the capsule can SHOW but
-- picking it writes nothing anyone keeps.
--
-- The table is deliberately NOT here. Three other
-- ways reach the same ladder (the console, the
-- native lighting panel, a hand-edited
-- config.toml), and a copy carried by this window
-- would be a copy the other three cannot see.
-- The page's OnUpdate poll is what brings the
-- member rows' new values back onto the screen.
OptionsRow_OnLoad(self, "lightingQuality",
BENILLA_ADVGFX.lightingQuality,
"BENILLA_TOOLTIP_LIGHTING_QUALITY")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.qOff, value = "Off" },
{ text = BENILLA_ADVGFX.qLow, value = "Low" },
{ text = BENILLA_ADVGFX.qMedium, value = "Medium" },
{ text = BENILLA_ADVGFX.qHigh, value = "High" },
{ text = BENILLA_ADVGFX.qUltra, value = "Ultra" },
{ text = BENILLA_ADVGFX.qCustom, value = "Custom" },
})
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowWaterQuality" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowLightingQuality" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowLightingQuality" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "waterQuality",
BENILLA_ADVGFX.waterQuality,
"BENILLA_TOOLTIP_WATER_QUALITY")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.waterClassic, value = "0" },
{ text = BENILLA_ADVGFX.waterEnhanced, value = "1" },
{ text = BENILLA_ADVGFX.waterHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (volumetric fog): live numeric tiers use the existing localised dropdown. -->
<Frame name="$parentRowVolumetricFog" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowWaterQuality" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowWaterQuality" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "volumetricFog", BENILLA_ADVGFX.volumetricFog,
"BENILLA_TOOLTIP_VOLUMETRIC_FOG")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.fogOff, value = "0" },
{ text = BENILLA_ADVGFX.qLow, value = "1" },
{ text = BENILLA_ADVGFX.qHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (sky): the sky tier, Classic / Enhanced / High. -->
<Frame name="$parentRowSkyQuality" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowVolumetricFog" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowVolumetricFog" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "skyQuality", BENILLA_ADVGFX.skyQuality,
"BENILLA_TOOLTIP_SKY_QUALITY")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.waterClassic, value = "0" },
{ text = BENILLA_ADVGFX.waterEnhanced, value = "1" },
{ text = BENILLA_ADVGFX.waterHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (post): live HDR/bloom tier; Off is the baseline. -->
<Frame name="$parentRowBloom" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSkyQuality" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSkyQuality" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "bloom", BENILLA_ADVGFX.bloom,
"BENILLA_TOOLTIP_BLOOM")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.fogOff, value = "0" },
{ text = BENILLA_ADVGFX.qLow, value = "1" },
{ text = BENILLA_ADVGFX.qHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (post): depth-occluded radial sunlight, world only. -->
<Frame name="$parentRowSunShafts" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowBloom" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowBloom" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "sunShafts", BENILLA_ADVGFX.sunShafts,
"BENILLA_TOOLTIP_SUN_SHAFTS")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (post): zone/day-night 32-cube grade, world only. -->
<Frame name="$parentRowColorGrading" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSunShafts" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSunShafts" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "colorGrading", BENILLA_ADVGFX.colorGrading,
"BENILLA_TOOLTIP_COLOR_GRADING")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowCharacterShadows" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<!-- MONKEY (post): screen effects sit immediately above this one. -->
<Anchor point="TOPLEFT" relativeTo="$parentRowColorGrading" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowColorGrading" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "characterShadows",
BENILLA_ADVGFX.characterShadows,
"BENILLA_TOOLTIP_CHARACTER_SHADOWS")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowWorldShadows" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowCharacterShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowCharacterShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "worldShadows",
BENILLA_ADVGFX.worldShadows,
"BENILLA_TOOLTIP_WORLD_SHADOWS")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowShadowDistance" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowWorldShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowWorldShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Realtime-shadow render distance (yd): the cascade
-- range + caster reach. 40-200, matching the CVar's
-- own clamp (SHADOW_DISTANCE_RANGE). DEFERRED to
-- Apply so a drag doesn't re-fit the cascade + recollect
-- casters on every tick (one rebuild on commit instead).
OptionsRow_OnLoad(self, "shadowDistance",
BENILLA_ADVGFX.shadowDistance,
"BENILLA_TOOLTIP_SHADOW_DISTANCE")
-- `"yd"`, not `"yards"`: the value is already a
-- distance in yards, where the format beside it
-- multiplies a FACTOR by the 15 yd camera base.
-- This row rode the wrong one from the day it was
-- seated and printed "1200 yd" for an 80 yd
-- cascade.
OptionsSliderRow_Setup(self, 40, 200, 10, "yd")
self.deferred = 1
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowShadowResolution" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShadowDistance" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShadowDistance" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- The three stops the CVar's own snap accepts
-- (`shadow_core::SHADOW_MAP_SIZES`): a dropdown
-- rather than a slider because an off-ladder value
-- is not a weaker setting, it is one the renderer
-- rounds UP into a bigger and slower map than the
-- one that was asked for. The entry texts are the
-- numbers themselves — nothing to translate.
OptionsRow_OnLoad(self, "shadowMapSize",
BENILLA_ADVGFX.shadowResolution,
"BENILLA_TOOLTIP_SHADOW_RESOLUTION")
OptionsDropdownRow_Setup(self, {
{ text = "1024", value = "1024" },
{ text = "2048", value = "2048" },
{ text = "4096", value = "4096" },
})
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMoonShadows" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShadowResolution" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShadowResolution" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- 0..1, the CVar's own clamp, and 0 is the FAITHFUL
-- null rather than a floor: every consumer guards
-- on it, so the left end of this groove is the
-- night the client rendered before the moon lane
-- existed.
OptionsRow_OnLoad(self, "moonShadowStrength",
BENILLA_ADVGFX.moonShadows,
"BENILLA_TOOLTIP_MOON_SHADOWS")
OptionsSliderRow_Setup(self, 0, 1, 0.05)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowInteriorLight" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMoonShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMoonShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "interiorLight",
BENILLA_ADVGFX.interiorLight,
"BENILLA_TOOLTIP_INTERIOR_LIGHT")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowInteriorShadows" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowInteriorLight" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowInteriorLight" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "interiorShadows",
BENILLA_ADVGFX.interiorShadows,
"BENILLA_TOOLTIP_INTERIOR_SHADOWS")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowExteriorShadows" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowInteriorShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowInteriorShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "exteriorShadows",
BENILLA_ADVGFX.exteriorShadows,
"BENILLA_TOOLTIP_EXTERIOR_SHADOWS")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (daylight: terrain torch casters) -->
<Frame name="$parentRowTorchTerrainShadows" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowExteriorShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowExteriorShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "torchTerrainShadows",
BENILLA_ADVGFX.torchTerrainShadows,
"BENILLA_TOOLTIP_TORCH_TERRAIN_SHADOWS")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowTorchSoft" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowTorchTerrainShadows" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowTorchTerrainShadows" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- 0.5..3, the CVar's own clamp verbatim: it is a
-- SCALE on the PCF tap radius at a contact, so the
-- readout is a percentage of the shipped radius
-- and 100% is what the lane was tuned at.
OptionsRow_OnLoad(self, "interiorShadowSoft",
BENILLA_ADVGFX.torchSoft,
"BENILLA_TOOLTIP_TORCH_SOFT")
OptionsSliderRow_Setup(self, 0.5, 3, 0.1)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowFireLight" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowTorchSoft" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowTorchSoft" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Full 0..4 registry range, in five-percent steps.
OptionsRow_OnLoad(self, "fireLightGain",
BENILLA_ADVGFX.fireLight,
"BENILLA_TOOLTIP_FIRE_LIGHT")
OptionsSliderRow_Setup(self, 0, 4, 0.05)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowFireFlicker" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFireLight" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFireLight" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- 0..2, the CVar's own clamp verbatim: the
-- amplitudes are authored at 100%, and 200% is the
-- deliberate over-drive for judging the shape.
OptionsRow_OnLoad(self, "fireFlicker",
BENILLA_ADVGFX.fireFlicker,
"BENILLA_TOOLTIP_FIRE_FLICKER")
OptionsSliderRow_Setup(self, 0, 2, 0.05)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowSpellLights" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFireFlicker" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFireFlicker" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Full 0..4 registry range, in five-percent steps.
OptionsRow_OnLoad(self, "spellLightGain",
BENILLA_ADVGFX.spellLights,
"BENILLA_TOOLTIP_SPELL_LIGHTS")
OptionsSliderRow_Setup(self, 0, 4, 0.05)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowLavaGlow" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSpellLights" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSpellLights" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "lavaLightGain",
BENILLA_ADVGFX.lavaGlow,
"BENILLA_TOOLTIP_LAVA_GLOW")
OptionsSliderRow_Setup(self, 0, 4, 0.05)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowNightDarkness" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowLavaGlow" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowLavaGlow" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- 0.2..1.5, the CVar's own clamp verbatim: the
-- floor is 0.2 rather than 0 because a true 0 is
-- indistinguishable from a broken light pack, and
-- the "off" a player wants is the reference's own
-- night at gain 1.
--
-- The readout is `darkness` — travel read from the
-- right — because the stored unit is a GAIN while
-- the row is named for the darkness: left is
-- darker, and this is what makes the number say so
-- too. The store keeps the gain, untouched.
OptionsRow_OnLoad(self, "nightGain",
BENILLA_ADVGFX.nightDarkness,
"BENILLA_TOOLTIP_NIGHT_DARKNESS")
OptionsSliderRow_Setup(self, 0.2, 1.5, 0.05, "darkness")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowInteriorDarkness" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowNightDarkness" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowNightDarkness" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- The room lane's own dim dial, same clamp and same
-- backwards readout as the night one above it.
OptionsRow_OnLoad(self, "interiorGain",
BENILLA_ADVGFX.interiorDarkness,
"BENILLA_TOOLTIP_INTERIOR_DARKNESS")
OptionsSliderRow_Setup(self, 0.2, 1.5, 0.05, "darkness")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (p0 skyDither): the combine's deband dither. -->
<Frame name="$parentRowSkyDither" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowInteriorDarkness" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowInteriorDarkness" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "skyDither",
BENILLA_ADVGFX.skyDither,
"BENILLA_TOOLTIP_SKY_DITHER")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (fog): the distance-fog model. -->
<Frame name="$parentRowFogModel" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowSkyDither" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowSkyDither" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "fogModel",
BENILLA_ADVGFX.fogModel,
"BENILLA_TOOLTIP_FOG_MODEL")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (wet): wet surfaces + rain ripples. -->
<Frame name="$parentRowRainSurfaces" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFogModel" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFogModel" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "rainSurfaces",
BENILLA_ADVGFX.rainSurfaces,
"BENILLA_TOOLTIP_RAIN_SURFACES")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (wind): three foliage tiers; appended at the end of the page. -->
<Frame name="$parentRowFoliageWind" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowRainSurfaces" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowRainSurfaces" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "foliageWind",
BENILLA_ADVGFX.foliageWind,
"BENILLA_TOOLTIP_FOLIAGE_WIND")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.qOff, value = "0" },
{ text = BENILLA_ADVGFX.windGrass, value = "1" },
{ text = BENILLA_ADVGFX.windTrees, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (ao): numeric tiers through the existing localised dropdown. -->
<Frame name="$parentRowAmbientOcclusion" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFoliageWind" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFoliageWind" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "ambientOcclusion", BENILLA_ADVGFX.ambientOcclusion,
"BENILLA_TOOLTIP_AMBIENT_OCCLUSION")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.fogOff, value = "0" },
{ text = BENILLA_ADVGFX.qLow, value = "1" },
{ text = BENILLA_ADVGFX.qHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (lampfog): night point-light airlight tiers. -->
<Frame name="$parentRowLampFog" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAmbientOcclusion" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAmbientOcclusion" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "lampFog", BENILLA_ADVGFX.lampFog,
"BENILLA_TOOLTIP_LAMP_FOG")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.fogOff, value = "0" },
{ text = BENILLA_ADVGFX.qLow, value = "1" },
{ text = BENILLA_ADVGFX.qHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (integration): the daylight lane's district window split (checkbox). -->
<Frame name="$parentRowDaylightWindowSplit" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowLampFog" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowLampFog" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "daylightWindowSplit",
BENILLA_ADVGFX.daylightWindowSplit,
"BENILLA_TOOLTIP_DAYLIGHT_WINDOW_SPLIT")
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (skybox): the zone skybox switch (integration: appended at the page end). -->
<Frame name="$parentRowZoneSkyboxes" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowDaylightWindowSplit" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowDaylightWindowSplit" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "zoneSkyboxes",
BENILLA_ADVGFX.zoneSkyboxes,
"BENILLA_TOOLTIP_ZONE_SKYBOXES")
</OnLoad></Scripts>
</Frame>
</Frames>
<!-- The poll (see AdvGfx_OnUpdate): this is the one page whose
settings move from outside it — the Lighting Quality row
writes its members through the host, and the console and
the dev lighting panel reach the same CVars while the page
is open. A signature compare four times a second, and a
refresh only when it actually moves. -->
<Scripts>
<OnUpdate>AdvGfx_OnUpdate(this, arg1)</OnUpdate>
</Scripts>
</Frame>
<!-- The Combat page: 1.12's AdvancedOptionsCombatText box as uvar
rows, each applying CombatText_UpdateOrLoad on the click. -->
<Frame name="$parentCombat" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowCombatText" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "SHOW_COMBAT_TEXT",
"Enable Floating Combat Text", "OPTION_TOOLTIP_SHOW_COMBAT_TEXT")
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<!-- 1.12's scroll-mode values: 1 up, 2 down, 3 arc. -->
<Frame name="$parentRowFloatMode" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowCombatText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowCombatText" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_FLOAT_MODE",
"Combat Text Float Mode", "OPTION_TOOLTIP_COMBAT_TEXT_MODE", 1)
OptionsDropdownRow_Setup(self, {
{ text = "Scroll Up", value = "1" },
{ text = "Scroll Down", value = "2" },
{ text = "Arc", value = "3" },
})
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowLowHealthMana" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFloatMode" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFloatMode" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_LOW_HEALTH_MANA",
"Show Low Mana and Health",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_LOW_HEALTH_MANA", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAuras" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowLowHealthMana" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowLowHealthMana" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_AURAS",
"Show Auras", "OPTION_TOOLTIP_COMBAT_TEXT_SHOW_AURAS", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAuraFade" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAuras" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAuras" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_AURA_FADE",
"Show Fading Auras", "OPTION_TOOLTIP_COMBAT_TEXT_SHOW_AURA_FADE", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowCombatState" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAuraFade" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAuraFade" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_COMBAT_STATE",
"Show Combat State",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_COMBAT_STATE", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowDodgeParryMiss" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowCombatState" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowCombatState" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_DODGE_PARRY_MISS",
"Show Dodge/Parries/Misses",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_DODGE_PARRY_MISS", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowResistances" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowDodgeParryMiss" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowDodgeParryMiss" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_RESISTANCES",
"Show Damage Reduction",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_RESISTANCES", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowReputation" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowResistances" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowResistances" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_REPUTATION",
"Show Reputation",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_REPUTATION", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowReactives" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowReputation" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowReputation" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_REACTIVES",
"Show Reactive Spells and Abilities",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_REACTIVES", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowFriendlyNames" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowReactives" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowReactives" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_FRIENDLY_NAMES",
"Show Friendly Healer Names",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_FRIENDLY_NAMES", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<!-- Greyed for all but rogues and druids, as in 1.12. -->
<Frame name="$parentRowComboPoints" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFriendlyNames" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFriendlyNames" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_COMBO_POINTS",
"Show Combo Points",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_COMBO_POINTS", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowEnergyGains" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowComboPoints" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowComboPoints" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_MANA",
"Show Energy Gains",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_MANA", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowHonorGained" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnergyGains" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnergyGains" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "COMBAT_TEXT_SHOW_HONOR_GAINED",
"Show Honor Gained",
"OPTION_TOOLTIP_COMBAT_TEXT_SHOW_HONOR_GAINED", 1)
self.parentRow = "RowCombatText"
self.applyFunc = "CombatText_UpdateOrLoad"
</OnLoad></Scripts>
</Frame>
<!-- CombatDamage masters what floats over a unit, apart
from SHOW_COMBAT_TEXT (l.709-714); at "0" neither
`0x607140` nor `0x6128b0` floats anything. -->
<Frame name="$parentRowShowDamage" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowHonorGained" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowHonorGained" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "CombatDamage", "Show Target Damage",
"OPTION_TOOLTIP_SHOW_DAMAGE")
</OnLoad></Scripts>
</Frame>
<!-- Off drops the whole SMSG_PERIODICAURALOG body
(`0x626dee`): lines, tick numbers and misses. -->
<Frame name="$parentRowPeriodicDamage" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShowDamage" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShowDamage" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "CombatLogPeriodicSpells", "Periodic Damage",
"OPTION_TOOLTIP_LOG_PERIODIC_EFFECTS", 1)
self.parentRow = "RowShowDamage"
</OnLoad></Scripts>
</Frame>
<!-- Also writes PetSpellDamage (l.334-336). -->
<Frame name="$parentRowPetDamage" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowPeriodicDamage" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowPeriodicDamage" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "PetMeleeDamage", "Pet Damage",
"OPTION_TOOLTIP_SHOW_PET_MELEE_DAMAGE", 1)
self.parentRow = "RowShowDamage"
self.partner = { cvar = "PetSpellDamage" }
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Action Bars page. Bar rows are API rows over the
character's PLAYER_FIELD_BYTES byte 2, re-sent on change;
Always Show ActionBars is a uvar, since SetActionBarToggles
drops a fifth argument (`cmp esi,4` at `0x4e770e`). The
closures resolve their callees at click time, not load. -->
<Frame name="$parentActionBars" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowMultiBar1" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self,
function() return SHOW_MULTI_ACTIONBAR_1 end,
function(value)
local on
if value and value ~= "0" and value ~= 0 then on = 1 end
SHOW_MULTI_ACTIONBAR_1 = on
MultiActionBar_Update()
SetActionBarToggles(SHOW_MULTI_ACTIONBAR_1, SHOW_MULTI_ACTIONBAR_2,
SHOW_MULTI_ACTIONBAR_3, SHOW_MULTI_ACTIONBAR_4)
UIParent_ManageFramePositions()
end,
"0", "Show Bottom Left ActionBar", "OPTION_TOOLTIP_SHOW_MULTIBAR1")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMultiBar2" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMultiBar1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMultiBar1" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self,
function() return SHOW_MULTI_ACTIONBAR_2 end,
function(value)
local on
if value and value ~= "0" and value ~= 0 then on = 1 end
SHOW_MULTI_ACTIONBAR_2 = on
MultiActionBar_Update()
SetActionBarToggles(SHOW_MULTI_ACTIONBAR_1, SHOW_MULTI_ACTIONBAR_2,
SHOW_MULTI_ACTIONBAR_3, SHOW_MULTI_ACTIONBAR_4)
UIParent_ManageFramePositions()
end,
"0", "Show Bottom Right ActionBar", "OPTION_TOOLTIP_SHOW_MULTIBAR2")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowMultiBar3" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMultiBar2" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMultiBar2" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self,
function() return SHOW_MULTI_ACTIONBAR_3 end,
function(value)
local on
if value and value ~= "0" and value ~= 0 then on = 1 end
SHOW_MULTI_ACTIONBAR_3 = on
MultiActionBar_Update()
SetActionBarToggles(SHOW_MULTI_ACTIONBAR_1, SHOW_MULTI_ACTIONBAR_2,
SHOW_MULTI_ACTIONBAR_3, SHOW_MULTI_ACTIONBAR_4)
UIParent_ManageFramePositions()
end,
"0", "Show Right ActionBar", "OPTION_TOOLTIP_SHOW_MULTIBAR3")
</OnLoad></Scripts>
</Frame>
<!-- A child of bar 3: MultiBarLeft shows only beside
MultiBarRight (l.722-726). -->
<Frame name="$parentRowMultiBar4" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMultiBar3" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMultiBar3" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self,
function() return SHOW_MULTI_ACTIONBAR_4 end,
function(value)
local on
if value and value ~= "0" and value ~= 0 then on = 1 end
SHOW_MULTI_ACTIONBAR_4 = on
MultiActionBar_Update()
SetActionBarToggles(SHOW_MULTI_ACTIONBAR_1, SHOW_MULTI_ACTIONBAR_2,
SHOW_MULTI_ACTIONBAR_3, SHOW_MULTI_ACTIONBAR_4)
UIParent_ManageFramePositions()
end,
"0", "Show Right ActionBar 2", "OPTION_TOOLTIP_SHOW_MULTIBAR4", 1)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAlwaysShowMultibars" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowMultiBar4" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowMultiBar4" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "ALWAYS_SHOW_MULTIBARS",
"Always Show ActionBars", "OPTION_TOOLTIP_ALWAYS_SHOW_MULTIBARS")
-- The click arm (UIOptionsFrame.xml:683); the load
-- arm is the stock VARIABLES_LOADED one.
self.applyFunc = "MultiActionBar_UpdateGridVisibility"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowLockActionBar" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAlwaysShowMultibars" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAlwaysShowMultibars" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "LOCK_ACTIONBAR",
"Lock ActionBars", "OPTION_TOOLTIP_LOCK_ACTIONBAR")
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Interface page. 62 (HIDE_OUTDOOR_WORLD_STATE) is absent:
no zone-objective tracker. A row has an applyFunc only when
something derived from it is set once and kept. -->
<Frame name="$parentInterface" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<!-- CheckButtons 12 and 2 head the Display box; the
cvarEvent wakes TextStatusBar.xml's CVAR_UPDATE. -->
<Frame name="$parentRowEnhancedTooltips" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "UberTooltips", "Enhanced Tooltips",
"OPTION_TOOLTIP_USE_UBERTOOLTIPS")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowStatusText" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnhancedTooltips" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnhancedTooltips" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "statusBarText",
"Status Bar Text", "OPTION_TOOLTIP_STATUS_BAR")
self.cvarEvent = "STATUS_BAR_TEXT"
</OnLoad></Scripts>
</Frame>
<!-- Saved globals in 1.12, not CVars. The mode row is a
child, as 1.12's dropdown hangs off CheckButton50 and
greys with it (l.694-700). -->
<Frame name="$parentRowTargetOfTarget" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowStatusText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowStatusText" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "SHOW_TARGET_OF_TARGET",
"Show Target of Target", "OPTION_TOOLTIP_SHOW_TARGET_OF_TARGET")
self.applyFunc = "TargetofTarget_Update"
</OnLoad></Scripts>
</Frame>
<!-- Deviation: the label is ours; 1.12 never sets this
dropdown's. Entries are its strings in its order. -->
<Frame name="$parentRowTargetOfTargetMode" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowTargetOfTarget" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowTargetOfTarget" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "SHOW_TARGET_OF_TARGET_STATE",
"Show When", "OPTION_TOOLTIP_TARGETOFTARGET5", 1)
OptionsDropdownRow_Setup(self, {
{ text = "Raid", value = "1", tip = "OPTION_TOOLTIP_TARGETOFTARGET1" },
{ text = "Party", value = "2", tip = "OPTION_TOOLTIP_TARGETOFTARGET2" },
{ text = "Solo", value = "3", tip = "OPTION_TOOLTIP_TARGETOFTARGET3" },
{ text = "Party or Raid", value = "4", tip = "OPTION_TOOLTIP_TARGETOFTARGET4" },
{ text = "Always", value = "5", tip = "OPTION_TOOLTIP_TARGETOFTARGET5" },
})
self.applyFunc = "TargetofTarget_Update"
</OnLoad></Scripts>
</Frame>
<!-- Bits of the character's PLAYER_FLAGS: API rows, as
1.12's `func` pair (UIOptionsFrame.lua l.18-19). -->
<Frame name="$parentRowShowCloak" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowTargetOfTargetMode" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowTargetOfTargetMode" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self, ShowingCloak, ShowCloak, "1",
"Show Cloak", "OPTION_TOOLTIP_SHOW_CLOAK")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowShowHelm" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShowCloak" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShowCloak" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self, ShowingHelm, ShowHelm, "1",
"Show Helm", "OPTION_TOOLTIP_SHOW_HELM")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowInstantQuestText" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShowHelm" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShowHelm" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "QUEST_FADING_DISABLE",
"Instant Quest Text", "OPTION_TOOLTIP_SHOW_QUEST_FADING")
</OnLoad></Scripts>
</Frame>
<!-- Its applyFunc re-states the buff bar's row pitch. -->
<Frame name="$parentRowBuffDurations" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowInstantQuestText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowInstantQuestText" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "SHOW_BUFF_DURATIONS",
"Buff Durations", "OPTION_TOOLTIP_SHOW_BUFF_DURATION")
self.applyFunc = "BuffButtons_UpdatePositions"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowAutoQuestWatch" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowBuffDurations" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowBuffDurations" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "AUTO_QUEST_WATCH",
"Automatic Quest Tracking", "OPTION_TOOLTIP_AUTO_QUEST_WATCH")
</OnLoad></Scripts>
</Frame>
<!-- CheckButton5, closing the chain under 66. The CVar
gates in the shared masker (`0x4a1a66`). -->
<Frame name="$parentRowProfanityFilter" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAutoQuestWatch" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAutoQuestWatch" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "profanityFilter", "Profanity Filter",
"OPTION_TOOLTIP_PROFANITY_FILTER")</OnLoad></Scripts>
</Frame>
<!-- The Help box, 28 -> 44 -> 29. Reset Tutorials does
not ship: ticking this row resets them. -->
<Frame name="$parentRowShowTutorials" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowProfanityFilter" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowProfanityFilter" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<!-- An API row over the tutorial bank, default "1"
(UIOptionsFrame_SetDefaults l.645). -->
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self, TutorialsEnabled,
BenillaOptionsFrame_SetTutorialsEnabled, "1",
"Show Tutorials", "OPTION_TOOLTIP_SHOW_TUTORIALS")
</OnLoad></Scripts>
</Frame>
<!-- The label and its tooltip name the tips
differently; both are 1.12's strings. -->
<Frame name="$parentRowTipOfTheDay" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowShowTutorials" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowShowTutorials" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "showGameTips",
"Show Loading Screen Tips",
"OPTION_TOOLTIP_SHOW_TIPOFTHEDAY")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowNewbieTips" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowTipOfTheDay" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowTipOfTheDay" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsGlobalRow_OnLoad(self, "SHOW_NEWBIE_TIPS",
"Show Detailed Tooltips", "OPTION_TOOLTIP_SHOW_NEWBIE_TIPS")
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Chat page. The chat window's look stays on the chat tab's
menu, as in 1.12. Party Chat Bubbles is not a child: the
client gates party bubbles on their own CVar. -->
<Frame name="$parentChat" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowGuildMemberAlert" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
<!-- 1.12 registers it "0" (cvars.rs cites it). -->
OptionsRow_OnLoad(self, "guildMemberNotify",
"Guild Member Alert",
"OPTION_TOOLTIP_GUILDMEMBER_ALERT")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowRemoveChatDelay" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowGuildMemberAlert" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowGuildMemberAlert" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
<!-- A uvar, as 1.12's CheckButton18; its applyFunc
moves ChatFrame.xml's fade constants. -->
OptionsGlobalRow_OnLoad(self, "REMOVE_CHAT_DELAY",
"Remove Chat Hover Delay",
"OPTION_TOOLTIP_REMOVE_CHAT_DELAY")
self.applyFunc = "ChatFrame_ApplyMouseOverDelay"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowChatBubbles" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowRemoveChatDelay" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowRemoveChatDelay" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "ChatBubbles",
"Show Chat Bubbles", "OPTION_TOOLTIP_CHAT_BUBBLES")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowLootSpam" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowChatBubbles" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowChatBubbles" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
<!-- Group loot-roll lines only. -->
OptionsRow_OnLoad(self, "showLootSpam",
"Detailed Loot Information",
"OPTION_TOOLTIP_SHOW_LOOT_SPAM")
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowPartyChatBubbles" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowLootSpam" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowLootSpam" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "ChatBubblesParty",
"Show Party Chat Bubbles", "OPTION_TOOLTIP_PARTY_CHAT_BUBBLES")
</OnLoad></Scripts>
</Frame>
<!-- Inverted, as 1.12 checks it on "0" (l.253) and flips
the write (l.337). The filter drops a line matching
SpamMessages.dbc, in every chat type but
CHAT_MSG_FILTERED (`0x49aad2`). -->
<Frame name="$parentRowSpamFilter" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowPartyChatBubbles" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowPartyChatBubbles" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "spamFilter", "Disable Spam Filter",
"OPTION_TOOLTIP_DISABLE_SPAM_FILTER")
self.invert = 1
</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Nameplates page: the V-key plates (`[0xc4da34]` bits 0
and 3), then the 1.12 UnitName* checkboxes. Deviation: 1.12
has no plate rows, only the keybinding; these are era rows
named after BINDING_NAME_NAMEPLATES. -->
<Frame name="$parentNameplates" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<Frame name="$parentRowEnemyPlates" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "nameplateShowEnemies",
"Enemy Name Plates")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowFriendlyPlates" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowEnemyPlates" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowEnemyPlates" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "nameplateShowFriends",
"Friendly Name Plates")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowPlayerNames" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFriendlyPlates" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFriendlyPlates" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "UnitNamePlayer", "Player Names",
"OPTION_TOOLTIP_SHOW_PLAYER_NAMES")</OnLoad></Scripts>
</Frame>
<!-- A child of Player Names, as CheckButton22 hangs off
21; it gates the guild line of the name stack. -->
<Frame name="$parentRowGuildNames" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowPlayerNames" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowPlayerNames" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "UnitNamePlayerGuild", "Player Guild Names",
"OPTION_TOOLTIP_SHOW_GUILD_NAMES", 1)
self.parentRow = "RowPlayerNames"
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowNpcNames" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowGuildNames" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowGuildNames" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "UnitNameNPC", "NPC Names",
"OPTION_TOOLTIP_SHOW_NPC_NAMES")</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowOwnName" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowNpcNames" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowNpcNames" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>OptionsRow_OnLoad(self, "UnitNameOwn", "Show Own Name",
"OPTION_TOOLTIP_SHOW_OWN_NAME")</OnLoad></Scripts>
</Frame>
</Frames>
</Frame>
<!-- The Keybindings page (its logic is KeyBindingsPage.xml).
enableMouse: rows are plain Frames, so the page itself
catches the wheel. -->
<Frame name="$parentKeybindings" hidden="true" enableMouse="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Layers>
<Layer level="OVERLAY">
<FontString name="$parentOutput" inherits="GameFontNormal">
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="8"/></Offset></Anchor></Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The box at CENTER-40, not CENTER-80: the 1.12
string is longer than the era's and clips there. -->
<Frame name="$parentCharacterRow" enableMouse="true">
<Size><AbsDimension y="26"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-12"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-20" y="-12"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="OVERLAY">
<FontString name="$parentLabel" inherits="GameFontNormal" justifyH="LEFT">
<Anchors>
<Anchor point="LEFT"><Offset><AbsDimension x="37" y="0"/></Offset></Anchor>
<Anchor point="RIGHT" relativePoint="CENTER"><Offset><AbsDimension x="-45" y="0"/></Offset></Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<CheckButton name="$parentCheck">
<Size><AbsDimension x="30" y="29"/></Size>
<Anchors><Anchor point="LEFT" relativePoint="CENTER"><Offset><AbsDimension x="-40" y="0"/></Offset></Anchor></Anchors>
<NormalTexture file="Interface\Buttons\UI-CheckBox-Up"/>
<PushedTexture file="Interface\Buttons\UI-CheckBox-Down"/>
<CheckedTexture file="Interface\Buttons\UI-CheckBox-Check"/>
<DisabledCheckedTexture file="Interface\Buttons\UI-CheckBox-Check-Disabled"/>
<Scripts>
<OnClick>KeyBindings_CharacterToggle(this)</OnClick>
<OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText(KeyBindings_String("CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP",
"Click this to toggle between general key bindings and key bindings specific to this character."), nil, nil, nil, nil, 1)
</OnEnter>
<OnLeave>GameTooltip:Hide()</OnLeave>
</Scripts>
</CheckButton>
</Frames>
<Scripts>
<OnLoad>
getglobal(this:GetName() .. "Label"):SetText(
KeyBindings_String("CHARACTER_SPECIFIC_KEYBINDINGS", "Character Specific Key Bindings"))
</OnLoad>
</Scripts>
</Frame>
<Frame name="$parentRow1" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-47"/></Offset></Anchor>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-32" y="-47"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="$parentRow2" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow1" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow1" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow3" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow2" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow2" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow4" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow3" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow3" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow5" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow4" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow4" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow6" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow5" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow5" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow7" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow6" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow6" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow8" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow7" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow7" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow9" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow8" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow8" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow10" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow9" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow9" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow11" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow10" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow10" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow12" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow11" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow11" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow13" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow12" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow12" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow14" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow13" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow13" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow15" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow14" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow14" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow16" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow15" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow15" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow17" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow16" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow16" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow18" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow17" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow17" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<Frame name="$parentRow19" inherits="KeyBindingRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRow18" relativePoint="BOTTOMLEFT"/>
<Anchor point="TOPRIGHT" relativeTo="$parentRow18" relativePoint="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<!-- The bar's trough (1.12 authors it per window), named
off the bar for BenillaScrollBar_SetShown. Declared
before the faux frame so it draws beneath it. -->
<Frame name="$parentScrollFrameScrollBarTrough" inherits="BenillaScrollTroughTemplate"/>
<!-- Ends at -32 so the kit's bar, hung 6 right, rides
the -26..-10 gutter (the TrainerFrame seating). -->
<ScrollFrame name="$parentScrollFrame" inherits="FauxScrollFrameTemplate">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-47"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-32" y="28"/></Offset></Anchor>
</Anchors>
<Scripts>
<OnLoad>ScrollFrame_OnLoad()</OnLoad>
<!-- The 1.12 kit updates `offset` only here.
KEYBINDINGS_ROW_HEIGHT must stay a global:
this chunk cannot see another file's local. -->
<OnVerticalScroll>FauxScrollFrame_OnVerticalScroll(KEYBINDINGS_ROW_HEIGHT, KeyBindingsPage_Update)</OnVerticalScroll>
<!-- Replaces the inherited wheel handler, which
fires before the page's guard: while a capsule
is armed the wheel binds, never scrolls. -->
<OnMouseWheel>
if not KeyBindingsPage.selected then
ScrollFrameTemplate_OnMouseWheel(arg1)
end
</OnMouseWheel>
</Scripts>
</ScrollFrame>
</Frames>
<!-- Rows and the bar bubble the wheel here; an armed
capsule binds it instead. -->
<Scripts>
<OnMouseWheel>
if not KeyBindingsPage.selected then
BenillaFauxScrollFrame_OnMouseWheel(getglobal(this:GetName() .. "ScrollFrame"), arg1)
end
</OnMouseWheel>
</Scripts>
</Frame>
<!-- The search heads, one per OPTIONS_PAGE_ROWS page; a new
page needs one here. -->
<Button name="$parentSearchHeadControls" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Controls"
getglobal(self:GetName() .. "Label"):SetText("Controls")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadAudio" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Audio"
getglobal(self:GetName() .. "Label"):SetText("Audio")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadGraphics" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Graphics"
getglobal(self:GetName() .. "Label"):SetText("Graphics")
</OnLoad></Scripts>
</Button>
<!-- MONKEY (advanced graphics): its own head, like every page with
rows. The label is the page's own bilingual title. -->
<Button name="$parentSearchHeadAdvancedGraphics" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "AdvancedGraphics"
getglobal(self:GetName() .. "Label"):SetText(BENILLA_ADVGFX.page)
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadCombat" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Combat"
getglobal(self:GetName() .. "Label"):SetText("Combat")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadActionBars" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "ActionBars"
getglobal(self:GetName() .. "Label"):SetText("Action Bars")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadInterface" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Interface"
getglobal(self:GetName() .. "Label"):SetText("Interface")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadChat" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Chat"
getglobal(self:GetName() .. "Label"):SetText("Chat")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadNameplates" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Nameplates"
getglobal(self:GetName() .. "Label"):SetText("Nameplates")
</OnLoad></Scripts>
</Button>
<Button name="$parentSearchHeadKeybindings" inherits="OptionsSearchHeadTemplate">
<Scripts><OnLoad>
self.categoryKey = "Keybindings"
getglobal(self:GetName() .. "Label"):SetText("Keybindings")
</OnLoad></Scripts>
</Button>
<!-- The keybinding search pool: one frame per
KEYBINDINGS_SEARCH_ROWS (8). -->
<Frame name="$parentKeybindSearch1" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch2" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch3" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch4" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch5" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch6" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch7" inherits="KeyBindingRowTemplate" hidden="true"/>
<Frame name="$parentKeybindSearch8" inherits="KeyBindingRowTemplate" hidden="true"/>
</Frames>
</Frame>
<!-- The page scroll bar, inside the right edge in the rows' free
-26..-10 gutter. Inset 21/20 so the trough, which hangs 21 above
and 20 below the bar, lands flush on the page rect. -->
<Slider name="$parentBar" inherits="BenillaScrollBarTemplate" hidden="true">
<Anchors>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-10" y="-21"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-10" y="20"/></Offset></Anchor>
</Anchors>
<Scripts><OnValueChanged>BenillaScrollBar_OnValueChanged(self, arg1)</OnValueChanged></Scripts>
</Slider>
</Frames>
</ScrollFrame>
</Frames>
</Frame>
<!-- The search box: the era SearchBoxTemplate geometry in the 1.12 Common-Input-Border
(InputBoxTemplate UVs). Deviation: no magnifier, which has no 1.12 art, so the
text inset is 5, not 16. -->
<EditBox name="$parentSearchBox" autoFocus="false" letters="64">
<Size><AbsDimension x="350" y="22"/></Size>
<!-- The era seat (SettingsPanel.xml l.76-81). -->
<Anchors>
<Anchor point="BOTTOMRIGHT" relativeTo="$parentContainer" relativePoint="TOPRIGHT"><Offset><AbsDimension x="4" y="20"/></Offset></Anchor>
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentBorderLeft" file="Interface\Common\Common-Input-Border">
<Size><AbsDimension x="8" y="20"/></Size>
<Anchors><Anchor point="LEFT"><Offset><AbsDimension x="-5" y="0"/></Offset></Anchor></Anchors>
<TexCoords left="0" right="0.0625" top="0" bottom="0.625"/>
</Texture>
<Texture name="$parentBorderRight" file="Interface\Common\Common-Input-Border">
<Size><AbsDimension x="8" y="20"/></Size>
<Anchors><Anchor point="RIGHT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
<TexCoords left="0.9375" right="1" top="0" bottom="0.625"/>
</Texture>
<Texture name="$parentBorderMiddle" file="Interface\Common\Common-Input-Border">
<Size><AbsDimension y="20"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentBorderLeft" relativePoint="RIGHT"/>
<Anchor point="RIGHT" relativeTo="$parentBorderRight" relativePoint="LEFT"/>
</Anchors>
<TexCoords left="0.0625" right="0.9375" top="0" bottom="0.625"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- The placeholder (the era instructions label, tinted 0.35). -->
<FontString name="$parentInstructions" inherits="GameFontDisableSmall" justifyH="LEFT" text="Search">
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="5" y="0"/></Offset></Anchor>
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-20" y="0"/></Offset></Anchor>
</Anchors>
<Color r="0.35" g="0.35" b="0.35"/>
</FontString>
</Layer>
</Layers>
<Frames>
<!-- The clear button (era ClearButtonMixin), half alpha until hovered. -->
<Button name="$parentClearButton" hidden="true">
<Size><AbsDimension x="17" y="17"/></Size>
<Anchors><Anchor point="RIGHT"><Offset><AbsDimension x="-3" y="0"/></Offset></Anchor></Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture name="$parentIcon" file="Interface\Buttons\UI-Panel-MinimizeButton-Up" alpha="0.5">
<Size><AbsDimension x="17" y="17"/></Size>
<Anchors><Anchor point="CENTER"/></Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnClick>
BenillaOptionsFrameSearchBox:SetText("")
BenillaOptionsFrameSearchBox:ClearFocus()
</OnClick>
<OnEnter>getglobal(this:GetName() .. "Icon"):SetAlpha(1.0)</OnEnter>
<OnLeave>getglobal(this:GetName() .. "Icon"):SetAlpha(0.5)</OnLeave>
</Scripts>
</Button>
</Frames>
<TextInsets><AbsInset left="5" right="20" top="0" bottom="0"/></TextInsets>
<Scripts>
<OnTextChanged>
if this:GetText() == "" then
BenillaOptionsFrameSearchBoxInstructions:Show()
BenillaOptionsFrameSearchBoxClearButton:Hide()
else
BenillaOptionsFrameSearchBoxInstructions:Hide()
BenillaOptionsFrameSearchBoxClearButton:Show()
end
OptionsSearch_OnTextChanged(this:GetText())
</OnTextChanged>
<OnEscapePressed>this:ClearFocus()</OnEscapePressed>
</Scripts>
<FontString inherits="GameFontHighlightSmall"/>
</EditBox>
<!-- ── Close: no corner X; the red button and ESC close the window ── -->
<!-- The red Close (era SettingsPanel.CloseButton). -->
<Button name="$parentCloseButton" inherits="OptionsRedButtonTemplate" text="Close">
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-16" y="16"/></Offset></Anchor></Anchors>
<Scripts>
<OnClick>
PlaySound("igMainMenuClose")
HideUIPanel(BenillaOptionsFrame)
</OnClick>
</Scripts>
</Button>
<!-- The era Apply (Blizzard_SettingsPanel.xml l.52-57), shown with a pending edit. -->
<Button name="$parentApplyButton" inherits="OptionsRedButtonTemplate" text="Apply" hidden="true">
<Anchors><Anchor point="RIGHT" relativeTo="$parentCloseButton" relativePoint="LEFT"><Offset><AbsDimension x="-2" y="0"/></Offset></Anchor></Anchors>
<Scripts>
<OnLoad>self:Disable()</OnLoad>
<OnClick>OptionsPage_Apply()</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<!-- Controls by default; selection persists and the scale re-fits, as the era's. -->
<OnShow>
BenillaOptionsFrame_UpdateScale()
BenillaOptionsFrame_SelectCategory(this.selectedCategory or "Controls")
if UpdateMicroButtons then UpdateMicroButtons() end
</OnShow>
<!-- Hiding ends a search (the era's ClearSearchBox), discards pending edits, and
disarms a bind capture, which would otherwise swallow all input. -->
<OnHide>
BenillaOptionsFrameSearchBox:SetText("")
OptionsPage_DiscardPending()
KeyBindings_SetSelected(nil)
KeyBindings_Output("")
if UpdateMicroButtons then UpdateMicroButtons() end
</OnHide>
</Scripts>
</Frame>
<!-- The reference's three options windows load hidden off the player's chain; nothing
aliases a stock name onto this window or shows a stock frame. This one is
BenillaOptionsFrame because the stock OptionsFrame.xml owns `OptionsFrame`.
GameMenuFrame.xml wraps ToggleGameMenu, IsOptionFrameOpen and UpdateMicroButtons, which
name only the stock three. Chat-tab hover (FloatingChatFrame.lua l.842/860) reads the
hidden UIOptionsFrame, so it works while this window, which does not cover the chat, is
open. BENILLA_ALLOW_OWN_UI=1 -->
<Script><![CDATA[
-- This window's UIPanelWindows row, the reference's OptionsFrame values (UIParent.lua:16):
-- the centre slot, openable while dead. UIParent.xml, which makes the table, loads first.
UIPanelWindows["BenillaOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 }
]]></Script>
</Ui>