Files
benilla-octo/crates/benilla-app/assets/ui/OptionsFrame.xml
T
gromandClaude Opus 5 1c786b7ecb Anisotropic Filtering takes its seat on the Graphics page
The CVar has been registered and read since the filter policy landed, and
last commit put it on the Graphics Preset ladder — but a player had no way
to reach it. The reference's own `OptionsFrameSliders` declares the row at
index 7; ours left that index a hole, so the only route to anisotropy was
`/console anisotropic 16`, and a player whose preset reads Custom (the
seeder never overwrites one) never met the setting at all.

Seated where the reference's own slider order puts it: after Brightness,
before Weather Intensity. Three things it does differently, each stated
beside it:

- The groove runs 1 to 16, the CVar's own `ANISO_RANGE`, not the stock
  table's 1 to 4. That ceiling was the reference *slider's*, not the
  CVar's — its callback parses 1-16 (`0x689110`) — and both the High and
  the Ultra rung ask for 16. So the row carries literal bounds and stays
  out of `BENILLA_GRAPHICS_SLIDER_ROWS`, exactly as `RowRenderScale` does
  for a CVar the stock table never had, which leaves `OptionsFrameSliders`
  verbatim for any addon that reads it.
- `1` reads out as "Off", not "1x": the reference writes filter mode 5
  only at 2 and above, so 1 is the feature off and not its weakest stop.
- The description is ours. 1.12's own OPTION_TOOLTIP_ANISOTROPIC describes
  a four-stop slider, and this one is sixteen.

Deferred to Apply, as Vertical Sync and Render Scale are: a sampler is
baked into each `Image` at load, so the write cannot reach a texture that
is already resident. The tooltip says so in the row rather than leaving a
player to wonder why the ground did not change — the same thing the
reference's UI means by "enabled upon restart".

Verified: `benilla-app --lib` at the exact 269-failure data-gated baseline,
set-identical by `comm`, with the new row's own test and the two census
counts (tooltip keys, raised plates) moved 116 -> 117 as the row asks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
2026-10-26 14:39:25 -06:00

4656 lines
342 KiB
XML

<Ui>
<!--
The Options window the game menu opens. 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. Every art byte is 1.12-native or a colour fill, so era
names below cite geometry only. Hiding discards pending edits and Apply commits outright.
A slider shows the 1.12 range; an out-of-range value displays clamped, not written back.
-->
<!-- The era's 14 and 20 white fonts, outside Fonts.xml's 1.12 set; MasterFont's shadow. -->
<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[
-- UIOptionsFrame.xml loads first and owns the uvars; each row captures its default at
-- OnLoad.
-- 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); 1 ~= "1" in Lua 5.0.
AUTO_QUEST_WATCH = "1"
RegisterForSave("AUTO_QUEST_WATCH")
-- UIOptionsFrame.lua:370-376: Blizzard_CombatText is LoadOnDemand, so the master loads it.
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: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:318-327); there is no tutorial CVar. The `~=`
-- guard is the reference's: re-ticking an on row must not 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
-- UIOptionsFrame.lua:768-780. Deviation: stock l.776 is dropped. On 1.12 its show-then-hide
-- clears volatile bits (`[0xc4da34]`); here the verbs write the CVar pair that is the
-- store, so it would erase the saved setting at every world entry.
function UpdateNameplates()
if ( NAMEPLATES_ON ) then
ShowNameplates()
else
HideNameplates()
end
if ( FRIENDNAMEPLATES_ON ) then
ShowFriendNameplates()
else
HideFriendNameplates()
end
end
-- The category tree in list order; keys are the row name suffixes.
-- 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", "AddOns",
}
-- The era UIParent draws smaller than our 768-unit canvas; a chosen value, not the
-- reference's.
ERA_WINDOW_SCALE = 0.78
function BenillaOptionsFrame_UpdateScale()
-- The era panel's checkFit: it also shrinks to fit the screen.
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, label + 40, measured after OnShow sets the scale.
function OptionsTab_FitWidth(tab)
tab:SetWidth(getglobal(tab:GetName() .. "Text"):GetStringWidth() + 40)
end
-- The wash at the era atlas size, in the 1.14 hover steel-blue.
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
-- 1.14's OptionsList_SelectButton. SetText("") ends a search and re-enters here.
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)
-- Leaving Keybindings disarms a pending capture, which must never outlive the page.
local kb = getglobal("BenillaOptionsFrameContainerBodyKeybindings")
local addons = getglobal("BenillaOptionsFrameContainerBodyAddOns")
if key == "Keybindings" then
kb:Show()
addons:Hide()
KeyBindingsPage_Refresh()
BenillaOptionsFrameContainerUnbind:Show()
BenillaOptionsFrameContainerDefaults:Enable()
elseif key == "AddOns" then
kb:Hide()
addons:Show()
OptionsAddOns_Refresh()
BenillaOptionsFrameContainerUnbind:Hide()
BenillaOptionsFrameContainerDefaults:Disable()
else
kb:Hide()
addons: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 ──
-- Tags are labels uppercased, matched by plain substring and scored by matched length.
-- Results are the live rows, so writes work mid-search.
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's MatchesSearchTags score, 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
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; 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 ──
-- Only frames hung off the body's top are measured, so the size converges.
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
-- The AddOns page's dynamic rows: row 0 is the Load out of date AddOns row.
for i = 0, table.getn(OptionsAddOns_Rows) do
local row = OptionsAddOns_Rows[i]
if row then take(row:GetName()) end
end
return bottom
end
-- From OnUpdate, off the previous frame's rects; 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 era SettingsList layout: the head at (10,-12), each next at (0,-9), as in the XML.
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
-- Back on the 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 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
getglobal("BenillaOptionsFrameContainerBodyKeybindings"):Hide()
getglobal("BenillaOptionsFrameContainerBodySearchHeadKeybindings"):Hide()
for i = 1, KEYBINDINGS_SEARCH_ROWS do
getglobal("BenillaOptionsFrameContainerBodyKeybindSearch" .. i):Hide()
end
-- The AddOns page is not in OPTIONS_PAGE_ROWS; hide it and its rows with it.
BenillaOptionsFrameContainerBodyAddOns:Hide()
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
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
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
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 ──
-- Descriptions 1.12 lacks take a BENILLA_ prefix.
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."
-- 1.12's own OPTION_TOOLTIP_ANISOTROPIC describes a four-stop slider that takes
-- effect on restart. Ours is neither: the groove runs the CVar's own 1-16 (the
-- reference's callback parses that range, `0x689110`; only its *slider* stopped at 4),
-- and it commits in place on Apply. So the text is ours.
BENILLA_TOOLTIP_ANISOTROPIC =
"Sharpens ground and wall texture seen at a grazing angle - the road running away "
.. "from you, a floor stretching into a room.\n\n"
.. "Off is what the original client shipped, which smears that texture to mush a few "
.. "yards out. 16x costs about a millisecond of graphics time and nothing at all on "
.. "the processor, so it is close to free on any modern card.\n\n"
.. "Each texture is sampled the way it was when it loaded, so this takes effect the "
.. "next time you start the game."
-- 1.12 has no such checkbox.
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."
-- 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."
BENILLA_TOOLTIP_RESOLUTION =
"The size of the game window, from the modes this monitor reports.\n\n"
.. "In Windowed (Fullscreen) the window already fills the screen, so this sets the "
.. "size it returns to in Windowed. Takes effect on Apply."
-- 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",
foliageWindStrength = "Foliage Wind Strength", -- MONKEY (fix-wind)
-- MONKEY (ao): localised contact-shadow row.
ambientOcclusion = "Ambient Occlusion",
-- MONKEY (lampfog)
lampFog = "Lamp Fog",
-- GFX (volumetric light) / (moonlight)
volumetricLight = "Volumetric Light",
volumetricLightStrength = "Volumetric Light Strength",
moonLight = "Moonlight",
-- 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, "
.. "Zone Skyboxes, Volumetric Light and Moonlight.\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.\n\n"
.. "It does not scale the weather. A storm's fog reaches indoors at full "
.. "strength, as it does in the original client, so with this turned well "
.. "down in bad weather that fog is most of what is left and rooms read "
.. "flat and grey. Raise this rather than hunt for the cause elsewhere.",
-- 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 (fix-wind)
FOLIAGE_WIND_STRENGTH =
"How far grass and foliage swing in the wind. 100% is the standard sway; lower "
.. "is calmer, higher is a blustery day. Storms swing everything harder on top. "
.. "Grass still parts around characters the same way. Needs Foliage Wind on.",
-- 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.",
-- GFX (volumetric light)
VOLUMETRIC_LIGHT =
"Sunlight and moonlight shine through the air as visible shafts: rays through "
.. "tree canopies, between buildings and past your character, following the "
.. "real shadows. Thicker at dawn, in fog and in rain. Needs World Shadows or "
.. "Real Character Shadows; not drawn indoors.\n\n"
.. "Medium uses fewer samples; High is smoother. Off is unchanged.",
VOLUMETRIC_LIGHT_STRENGTH =
"How bright the volumetric light shafts are. 100% is the default; 0 hides them.",
-- GFX (moonlight)
MOONLIGHT =
"The moon lights the world at night: a cool, dim light from where the moon "
.. "really stands in the sky, added on top of the original night colours, with "
.. "moon shadows when Moon Shadows is above 0.\n\n"
.. "At 0 the night looks exactly as the original client drew it. Costs nothing by day.",
},
},
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 = "Трава + деревья",
foliageWindStrength = "Сила ветра листвы", -- MONKEY (fix-wind)
-- MONKEY (ao): Russian contact-shadow row.
ambientOcclusion = "Затенение окружения",
-- MONKEY (lampfog)
lampFog = "Свечение фонарей в тумане",
-- GFX (volumetric light) / (moonlight)
volumetricLight = "Объёмный свет",
volumetricLightStrength = "Сила объёмного света",
moonLight = "Лунный свет",
-- 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 оставляет эти составляющие без изменений. Ничего не стоит при любом значении.\n\n"
.. "Погоды не касается: туман непогоды проникает внутрь в полную силу, как "
.. "и в оригинальном клиенте. При сильно пониженном значении в плохую "
.. "погоду именно этот туман и остаётся, и помещения выглядят плоско и "
.. "серо. Поднимите этот ползунок, а не ищите причину в другом месте.",
-- MONKEY (p0 skyDither)
SKY_DITHER =
"Добавляет едва заметный шум в итоговое изображение, чтобы плавные переходы цвета "
.. "неба и тумана не распадались на полосы. Выключено — вид оригинального клиента. "
.. "Почти ничего не стоит.",
-- MONKEY (fog)
FOG_MODEL =
"Более мягкий туман в духе современного клиента: он сгущается постепенно, а не "
.. "по прямой, днём светлеет в сторону солнца, а вдали принимает цвет неба, "
.. "так что земля растворяется в горизонте. Дальность тумана в каждой зоне "
.. "прежняя; за пределом дальности обзора оригинала туман отступает вместе с ней."
.. "\n\nВыключено — туман оригинального клиента. Почти ничего не стоит.",
-- MONKEY (wet)
RAIN_SURFACES =
"Дождь постепенно намачивает землю, камень и дерево под открытым небом: они темнеют, "
.. "на ровной земле собираются лужи, мокрые поверхности блестят, а капли расходятся "
.. "кругами по воде. После дождя всё высыхает за несколько минут. Выключено — вид "
.. "оригинального клиента. Почти ничего не стоит и работает, только пока всё мокрое.",
-- MONKEY (wind)
FOLIAGE_WIND =
"Трава гнётся двумя бегущими волнами ветра и расступается вокруг персонажей. "
.. "Трава + деревья также добавляет мягкое качание листвы деревьев и кустов.\n\n"
.. "Выключено не смещает вершины и восстанавливает исходный вид. Тени деревьев остаются неподвижными.",
-- MONKEY (fix-wind)
FOLIAGE_WIND_STRENGTH =
"Насколько сильно трава и листва качаются на ветру. 100% — обычное качание; меньше — "
.. "спокойнее, больше — ветреный день. В грозу всё качается ещё сильнее. "
.. "Трава по-прежнему расступается вокруг персонажей. Работает, если включён ветер листвы.",
-- 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"
.. "Выключено — без изменений; днём изображение не меняется при любом значении.",
-- GFX (volumetric light)
VOLUMETRIC_LIGHT =
"Солнечный и лунный свет виден в воздухе лучами: сквозь кроны деревьев, между "
.. "зданиями и рядом с персонажем, по настоящим теням. Гуще на рассвете, в тумане "
.. "и под дождём. Нужны тени мира или реальные тени персонажей; в помещениях не "
.. "рисуется.\n\n"
.. "«Среднее» использует меньше выборок, «Высокое» — более плавное. Выключено — "
.. "без изменений.",
VOLUMETRIC_LIGHT_STRENGTH =
"Яркость лучей объёмного света. 100% — по умолчанию; 0 скрывает их.",
-- GFX (moonlight)
MOONLIGHT =
"Луна освещает мир ночью: холодный тусклый свет с того места, где луна "
.. "действительно стоит на небе, поверх исходных ночных цветов, с лунными тенями, "
.. "если «Лунные тени» больше 0.\n\n"
.. "При 0 ночь выглядит точно так же, как в оригинальном клиенте. Днём не стоит ничего.",
},
},
}
-- 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 first; the rest follow their 1.12 box's columns.
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",
-- GFX (anisotropic): index 7 of OptionsFrameSliders, in that table's own order.
"RowAnisotropic", "RowWeatherDensity",
"RowDisplayMode", "RowResolution", "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 (fix-wind): the sway strength, right under its tier.
"RowFoliageWindStrength",
-- 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",
-- GFX (volumetric light) / (moonlight): appended so the other rows keep their indices.
"RowVolumetricLight", "RowVolumetricLightStrength", "RowMoonLight",
},
-- Guild Names is a child of Player Names (UIOptionsFrame.lua:703-709).
Nameplates = {
"RowEnemyPlates", "RowFriendlyPlates",
"RowPlayerNames", "RowGuildNames", "RowNpcNames", "RowOwnName",
},
-- 1.12's Display box by column, then Help; target-of-target sits under Status Text.
Interface = {
"RowEnhancedTooltips", "RowStatusText", "RowTargetOfTarget", "RowTargetOfTargetMode",
"RowShowCloak", "RowShowHelm",
"RowInstantQuestText", "RowBuffDurations", "RowAutoQuestWatch",
"RowProfanityFilter",
"RowShowTutorials", "RowTipOfTheDay", "RowNewbieTips",
},
-- 1.12's chat box (UIOptionsFrame.xml:751-840). Not shipped: Simple Chat, which needs
-- FCF_Set_SimpleChat's re-layout, Lock Chat Settings and Guild Recruitment.
Chat = {
"RowGuildMemberAlert", "RowRemoveChatDelay", "RowChatBubbles", "RowLootSpam",
"RowPartyChatBubbles", "RowSpamFilter",
},
-- Deviation: the bar toggles precede the lock, which 1.12's box leads with, so what is
-- on screen reads first.
ActionBars = {
"RowMultiBar1", "RowMultiBar2", "RowMultiBar3", "RowMultiBar4",
"RowAlwaysShowMultibars", "RowLockActionBar",
},
-- The combat-text box in its anchor-chain order.
Combat = {
"RowCombatText", "RowFloatMode", "RowLowHealthMana", "RowAuras", "RowAuraFade",
"RowCombatState", "RowDodgeParryMiss", "RowResistances", "RowReputation",
"RowReactives", "RowFriendlyNames", "RowComboPoints", "RowEnergyGains",
"RowHonorGained",
-- Under their own master (UIOptionsFrame.lua:710-716).
"RowShowDamage", "RowPeriodicDamage", "RowPetDamage",
},
}
-- `tip` is a GlobalStrings key, resolved at hover as UIOptionsFrame.lua:265 does.
function OptionsRow_OnLoad(row, cvar, label, tip, child)
row.cvar = cvar
row.tip = tip
row.searchTag = string.upper(label)
-- OptionsRow_SetEnabled's disabled font must keep the child size.
row.child = child
local l = getglobal(row:GetName() .. "Label")
l:SetText(label)
if child then
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 ──
-- 1.12's `cvar`, `uvar` or `func`/`setFunc` (UIOptionsFrame.lua:230-377), all strings. Keep
-- OptionsRow_HasStore in OptionsRow_Set's order.
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
-- OptionsFrame.lua:110/135, formatted like the slider's write so strings compare
-- equal.
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
-- A uvar row applies on the click; `cvarEvent` is CVAR_UPDATE's arg1.
function OptionsRow_Set(row, value)
if row.uvar then
setglobal(row.uvar, value)
-- Looked up when applied: most definers load after this file.
local apply = row.applyFunc
if type(apply) == "string" then apply = getglobal(apply) end
if apply then apply() end
return
end
-- The "1"/"0" string, as UIOptionsFrame.lua:291-297.
if row.setFunc then
-- A number, as OptionsFrame.lua: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
-- UIOptionsFrame_Save's partner writes: 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).
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
-- A uvar's default is captured at OnLoad, before the saved-variables chunk runs.
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
-- 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
-- Stated, as UIOptionsFrame_SetDefaults hand-writes it (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
-- `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
-- UIOptionsFrame.lua:193-227 re-applies saved uvars, so this window has no load ladder.
-- OptionsFrameSliders is the stock table (OptionsFrame.lua:24-34), which addons write.
-- Deviation: TurtleWoW's patch-4 replaces OptionsFrame.lua with a 2.0-era file that never
-- defines it, so the rows below restore the 1.12 table verbatim — `OPTIONS_FARCLIP_MIN/MAX`
-- resolved to their 177/777 values (they live in the 1.12 OptionsFrame.lua:1-2, not in
-- GlobalStrings, so a replacement loses them) — for the graphics rows and any addon.
OptionsFrameSliders = {
{ text = UI_SCALE, func = "uiscale", minValue = 0.64, maxValue = 1.0, valueStep = 0.01, tooltipText = OPTION_TOOLTIP_UI_SCALE },
{ text = FARCLIP, func = "farclip", minValue = 177, maxValue = 777, valueStep = 60, tooltipText = OPTION_TOOLTIP_FARCLIP },
{ text = ENVIRONMENT_DETAIL, func = "WorldDetail", minValue = 0, maxValue = 2, valueStep = 1, tooltipText = OPTION_TOOLTIP_ENVIRONMENT_DETAIL },
{ text = TERRAIN_MIP, func = "TerrainMip", minValue = 0, maxValue = 1, valueStep = 1, tooltipText = OPTION_TOOLTIP_TERRAIN_TEXTURE, restartClient = 1, tooltipRequirement = OPTION_RESTART_REQUIREMENT },
{ text = TEXTURE_DETAIL, func = "BaseMip", minValue = 0, maxValue = 1, valueStep = 1, tooltipText = OPTION_TOOLTIP_TEXTURE_DETAIL },
{ text = GAMMA, func = "Gamma", cvar1 = "gamma", minValue = -0.5, maxValue = 0.5, valueStep = 0.1, tooltipText = OPTION_TOOLTIP_GAMMA },
{ text = ANISOTROPIC, func = "anisotropic", minValue = 1, maxValue = 4, valueStep = 1, tooltipText = OPTION_TOOLTIP_ANISOTROPIC, restartClient = 1, tooltipRequirement = OPTION_RESTART_REQUIREMENT },
{ text = SPELL_DETAIL, func = "spellEffectLevel", minValue = 0, maxValue = 2, valueStep = 1, tooltipText = OPTION_TOOLTIP_SPELL_DETAIL },
{ text = WEATHER_DETAIL, func = "weatherDensity", minValue = 0, maxValue = 3, valueStep = 1, tooltipText = OPTION_TOOLTIP_WEATHER_DETAIL },
}
-- The rows whose bounds ARE the stock table's, re-applied on show so an addon's write to
-- OptionsFrameSliders lands. Holes at 4, 5, 7 and 8, so the OnShow loop uses the pairs
-- form: ipairs would stop at 3.
--
-- 7 (ANISOTROPIC) is a seated row but deliberately not listed: the stock entry caps at 4,
-- which was the reference *slider's* limit and not the CVar's (its callback parses 1-16,
-- `0x689110`), and High and Ultra both ask for 16. So that row carries its own literal
-- bounds, as `RowRenderScale` does for a CVar the table never had — and the table above
-- stays verbatim for any addon that reads it.
BENILLA_GRAPHICS_SLIDER_ROWS = {
"RowUiScale", "RowFarclip", "RowWorldDetail",
[6] = "RowBrightness", [9] = "RowWeatherDensity",
}
-- 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
-- Deviation: a named ladder reads out its stop; 1.12's slider labels only its ends, and
-- 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 ──
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
-- A row whose entries come from LIVE ENGINE STATE rather than from a fixed list has to be
-- rebuilt before it is read, because that state is not there yet when this file loads:
-- the display's mode list is pushed by a Bevy system a frame or more later
-- (`video.rs`'s `publish_display_modes`, and `addon_harness/mod.rs` documents the empty
-- list a freshly-loaded VM sees). Built once at OnLoad, such a row ends up with no
-- entries at all — which shows as the raw stored index in the capsule and an empty menu
-- that does nothing when clicked, since there is nothing to list.
function OptionsResolutionRow_Rebuild(row)
local modes = { GetScreenResolutions() }
local entries = {}
for i = 1, table.getn(modes) do
-- A STRING value, as every other dropdown row's is: `OptionsRow_Get` formats a
-- numeric row's value as a string too, so this is what lets
-- `OptionsDropdown_ShowValue` match on equality instead of falling through to
-- its nearest-value search.
table.insert(entries, { text = modes[i], value = tostring(i) })
end
row.entries = entries
end
function OptionsDropdownRow_InitMenu()
local dd = getglobal(UIDROPDOWNMENU_INIT_MENU)
local row = dd:GetParent()
if row.rebuild then row.rebuild(row) end
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
-- Write a row's value, or stage it for Apply when the row is `deferred`.
--
-- The slider path had this inline and the checkbox and dropdown paths did not, so a
-- deferred checkbox or dropdown wrote straight through and the Apply button — which only
-- appears when some row is pending — never came up. That is how vertical sync looked
-- like it was not persisting: `gxVSync` is a **latched** CVar, so `SetCVar` only stages
-- it on the host side until `RestartGx`, and with no Apply button there was nothing to
-- press to get there.
function OptionsRow_Commit(row, value)
if row.deferred then
-- A pending equal to the committed value is dropped, as the slider's is.
if value == OptionsRow_Get(row) then
row.pending = nil
else
row.pending = value
end
OptionsApply_Update()
else
OptionsRow_Set(row, value)
end
end
-- `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_Commit(row, this.value)
OptionsDropdown_ShowValue(row)
end
-- A field, not SetSelectedValue, whose Refresh walks the shared DropDownList1. An off-grid
-- value shows the nearest entry.
function OptionsDropdown_ShowValue(row)
local dd = getglobal(row:GetName() .. "Dropdown")
-- A staged pick shows at once, as `OptionsPage_Refresh` already does for the other
-- control kinds: a deferred row would otherwise snap back to the committed value the
-- instant it was chosen, which reads as the pick not having registered.
local v = row.pending or OptionsRow_Get(row)
local match
for _, e in ipairs(row.entries) do
-- `alt`: a stored "3" shows as Never, where the nearest value would show Always.
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)
-- As UIOptionsFrameCameraDropDown_OnClick retargets OPTION_TOOLTIP_CAMERA<id>.
if match.tip then row.tip = match.tip end
else
dd.selectedValue = v
UIDropDownMenu_SetText(v, dd)
end
end
function OptionsRow_FormatValue(row, value)
if row.fmt == "raw" then
return string.format("%d", math.floor(value + 0.5))
end
-- 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
-- "yards": cameraDistanceMaxFactor over the 15 yd base.
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
-- The anisotropy groove. 1 is not "1x", it is the feature OFF (`tex_filter.rs`:
-- the reference writes filter mode 5 only at 2 and above), and a player reading "1x"
-- next to "2x" would take it for the weakest setting rather than for none.
if row.fmt == "aniso" then
local n = math.floor(value + 0.5)
if n <= 1 then return "Off" end
return string.format("%dx", n)
end
return string.format("%d%%", math.floor(value * 100 + 0.5))
end
-- Crossing controls does not blink: 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
-- 1.12's per-option string alone in gold (OptionsFrameTemplates.xml:52-64).
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
-- neighbour's text cannot stand when its OnLeave was missed.
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:509-515), 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_Commit(row, "1")
else
OptionsRow_Commit(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
-- Snaps to the grid from the minimum (farclip's is 177+n*60); a refresh sets it
-- 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
-- Trailing zeros stripped, so a value at its default stays out of the config file.
local str = string.gsub(string.format("%.2f", value), "%.?0+$", "")
if row.deferred then
-- Stored on Apply; a pending equal to the committed value is dropped.
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
-- "0" unchecks; an inverted row checks on "0".
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
if row.rebuild then row.rebuild(row) end
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.
getglobal(base .. rkey .. "ControlValue"):SetText(
OptionsRow_FormatValue(row, slider:GetValue()))
end
end
OptionsPage_UpdateDependencies(key)
OptionsApply_Update()
end
-- ── The AddOns page: the era's per-addon enable list ──
-- Rows are built on show from the AddOn API: one checkbox per installed addon (its
-- `GetAddOnInfo` enabled state), then the Load out of date AddOns row. A toggle calls
-- `EnableAddOn`/`DisableAddOn`, which the host persists to `AddOns.txt` at logout, so the
-- change applies on the next world entry — the reference's own contract for the AddOns
-- screen. Row 0 is the Load out of date AddOns row.
OptionsAddOns_Rows = {}
function OptionsAddOns_GetRow(i)
local row = OptionsAddOns_Rows[i]
if row then return row end
row = CreateFrame("Frame", "BenillaOptionsFrameContainerBodyAddOnsRow" .. i,
BenillaOptionsFrameContainerBodyAddOns, "OptionsCheckboxRowTemplate")
row.index = i
OptionsAddOns_Rows[i] = row
return row
end
function OptionsAddOns_OnClick(box)
local row = box:GetParent()
local checked = box:GetChecked()
PlaySound(checked and "igMainMenuOptionCheckBoxOn" or "igMainMenuOptionCheckBoxOff")
if checked then
EnableAddOn(row.index)
else
DisableAddOn(row.index)
end
end
function OptionsAddOns_Refresh()
local n = GetNumAddOns()
local prev = nil
for i = 1, n do
local name, title, notes, enabled = GetAddOnInfo(i)
local row = OptionsAddOns_GetRow(i)
row:Show()
local label = getglobal(row:GetName() .. "Label")
label:SetText(title or name)
row.searchTag = string.upper(title or name)
local box = getglobal(row:GetName() .. "Check")
box:SetChecked(enabled)
box:SetScript("OnClick", OptionsAddOns_OnClick)
OptionsSearch_Place(row:GetName(), prev)
prev = row:GetName()
end
for i = n + 1, table.getn(OptionsAddOns_Rows) do
OptionsAddOns_Rows[i]:Hide()
end
-- The Load out of date AddOns row, under the list; inverted, `checkAddonVersion`
-- "1" enforces the check (`0x402c3b`), so checked means "0".
local lod = OptionsAddOns_GetRow(0)
if not lod.cvar then
OptionsRow_OnLoad(lod, "checkAddonVersion", "Load out of date AddOns")
lod.invert = 1
end
lod:Show()
getglobal(lod:GetName() .. "Check"):SetChecked(
OptionsRow_Get(lod) == "0" and 1 or nil)
OptionsSearch_Place(lod:GetName(), prev)
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
-- Each page's dependency rules, the 1.12 panel's own.
function OptionsPage_UpdateDependencies(key)
if key == "Combat" then
-- Combo Points is for rogues and druids only.
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.
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
-- UIOptionsFrame.lua:710-716: 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")
-- MONKEY (fix-wind): the strength only matters while some foliage sways.
OptionsRow_SetEnabled(getglobal(base .. "RowFoliageWindStrength"),
GetCVar("foliageWind") ~= "0")
return
end
if key == "Controls" then
-- UIOptionsFrame.lua:717-721: dead while the style is Never, "0" or a stray "3".
local style = GetCVar("cameraSmoothStyle")
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyControlsRowAutoFollowSpeed,
style ~= "0" and style ~= "3")
return
end
if key == "Nameplates" then
-- UIOptionsFrame.lua:703-709: Player Names off greys Player Guild Names.
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyNameplatesRowGuildNames,
GetCVar("UnitNamePlayer") ~= "0")
return
end
if key == "Interface" then
-- UIOptionsFrame.lua:697-701: the mode is dead while its switch is off.
OptionsRow_SetEnabled(BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetMode,
SHOW_TARGET_OF_TARGET ~= "0")
return
end
if key == "ActionBars" then
-- UIOptionsFrame.lua:722-726: Right ActionBar 2 needs Right ActionBar.
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
-- As OptionsFrame_DisableDropDown; 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")
-- As OptionsFrame_DisableSlider (l.481-486); a press on the track would seat 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
-- 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 ──
-- Pending edits survive a category switch; hiding discards them.
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
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
-- Commit the latched rows. A CVar registered with the latch flag — gxVSync,
-- gxResolution, gxWindow — does not take the write that `OptionsRow_Set` just made:
-- it is staged until `RestartGx`, which is what the reference's own video options
-- call on Apply. Without this they stayed pending for the whole session, never
-- reached the live value, and so were never written to `config.toml` either: a
-- vertical-sync change that looked accepted and was back on after a relaunch.
RestartGx()
OptionsApply_Update()
end
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>
<!-- A copy of the stock GameMenuButtonTemplate (UIPanelTemplates.xml:403) at the era's
96x22. -->
<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>
<!-- The wash is 1.14's OptionsListButtonTemplate: 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 label box spans the row, so the text centres vertically but not 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 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; the era's wash has no 1.12 art. -->
<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; a click selects the category, ending the search. -->
<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 row with the 1.12 UI-CheckBox set; the row-wide wash 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 label half; 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>
<!-- 1.12's OptionsSliderTemplate groove (OptionsFrameTemplates.xml:74); no steppers, as in
1.12. The +3 seats the art, 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: one column keeps the plate 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>
<!-- At CENTER-71, so the capsule's ink opens at the groove's column. -->
<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 era SettingsPanel's size and strata, HIGH, where 1.12's OptionsFrame is DIALOG;
toplevel as 1.12's OptionsFrame.xml:5. -->
<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 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">
<!-- 0.88 combined with the tile, so labels read over bright terrain. Inset 15:
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">
<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">
<!-- 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>
<!-- 1.14's OptionsFrameListTemplate outlines, declared first so siblings draw above;
tops at -52 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>
<!-- Static: only Game has pages. Each plate is a UI-Character tab piece flipped, 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"/>
<!-- The AddOns page below: the era's per-addon enable list. -->
<Scripts>
<OnShow>OptionsTab_FitWidth(self)</OnShow>
</Scripts>
</Button>
<!-- ── The category list ── -->
<Frame name="$parentCategoryList">
<Size><AbsDimension x="199"/></Size>
<!-- The box top (-52) plus the era's 12-unit 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>
<Button name="$parentRowAddOns" inherits="OptionsCategoryRowTemplate">
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentRowAudio" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
<Scripts><OnLoad>OptionsCategoryRow_OnLoad(self, "AddOns", "AddOns")</OnLoad></Scripts>
</Button>
</Frames>
</Frame>
<!-- ── The page area ── -->
<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 divider as a fill: 630x1 white at about 0.3. -->
<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>
<!-- 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>
<!-- Declared before the body and the bar so it draws beneath both. -->
<Frame name="$parentBarTrough" inherits="BenillaScrollTroughTemplate"/>
<!-- Sized, not anchored: SetScrollChild pins its TOPLEFT and
OptionsScroll_Fit sizes it. -->
<Frame name="BenillaOptionsFrameContainerBody">
<Size><AbsDimension x="665" y="563"/></Size>
<Layers>
<Layer level="OVERLAY">
<!-- The no-match line, 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>
<!-- Sticky Targeting is inverted, as 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": 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>
<!-- Smart 1, Always 2, Never 0 (UIOptionsFrame.lua:525,
536, 547). -->
<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>
<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: 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>
<!-- Writes cameraPitchMoveSpeed at half (l.354-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 three volumes are children of Master. -->
<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)
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:3). -->
<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>
<!-- An era row, not in 1.12, which always mutes when
the window loses focus; off matches it. -->
<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 era AddOns page: one checkbox per installed addon (enabled
state), then the Load out of date AddOns row; the rows are
built by OptionsAddOns_Refresh on show. -->
<Frame name="$parentAddOns" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
</Frame>
<!-- No useUiScale checkbox, which 1.12 has: benilla registers
useUiScale but never reads it, so 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)
-- 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>
<!-- An API row over GetGamma/SetGamma, whose unit is
`1 - gamma`; writing `gamma` 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.444-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>
<Frame name="$parentRowAnisotropic" 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>
-- Index 7 of OptionsFrameSliders, seated where the
-- reference's own slider order puts it: after
-- Brightness, before Weather Intensity. Before this
-- the row was a hole, so the only way to anisotropy
-- was `/console anisotropic 16` — and a player on a
-- Custom graphics preset never met it at all, since
-- the preset ladder is what seeds the value.
OptionsRow_OnLoad(self, "anisotropic", "Anisotropic Filtering",
"BENILLA_TOOLTIP_ANISOTROPIC")
-- 1 to 16, the CVar's own range (`ANISO_RANGE`),
-- not the stock table's 1-4 — see
-- BENILLA_GRAPHICS_SLIDER_ROWS. Step 1 rather than
-- a power-of-two ladder because the value is a
-- MAXIMUM the driver is free to round down: an
-- off-ladder stop is a weaker setting, never a
-- wrong one, which is the test `RowShadowResolution`
-- fails and so takes a dropdown instead.
OptionsSliderRow_Setup(self, 1, 16, 1, "aniso")
-- DEFERRED, as the two rows below it are, because
-- the write does not reach a texture that is
-- already resident: a sampler is baked into each
-- `Image` at load (`tex_filter.rs`), which is why
-- the reference's own UI says "enabled upon
-- restart". Apply is therefore the honest commit
-- point, and a drag does not write a CVar on every
-- step of the groove that only the next launch
-- reads.
self.deferred = 1
</OnLoad></Scripts>
</Frame>
<!-- On the CVar, as 1.12's lands: there is no
SetweatherDensity global. -->
<Frame name="$parentRowWeatherDensity" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowAnisotropic" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowAnisotropic" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "weatherDensity", "Weather Intensity",
"OPTION_TOOLTIP_WEATHER_DETAIL")
-- Our names for `0x67b870`'s spawn-rate gains
-- `{0.1, 0.33, 0.66, 1.0}` (`[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, as there is no exclusive fullscreen;
-- gxWindow "0" is the borderless window.
-- Latched, like the other two video rows.
self.deferred = 1
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="$parentRowResolution" inherits="OptionsDropdownRowTemplate">
<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>
-- The window size. Backed by the index verbs, not
-- by `gxResolution` directly: `SetScreenResolution`
-- is 1-based into `GetScreenResolutions`, and
-- `GetCurrentResolution` reports the *live* window
-- rather than the CVar, which in borderless
-- fullscreen are not the same thing.
--
-- Built from the real list, so the entries are
-- whatever this monitor actually offers. 1.12's
-- own video panel had this row; benilla shipped
-- the display-mode and vsync rows without it, so
-- there was no way to resize from inside the game.
-- `rebuild`, not a list baked here: at OnLoad
-- the engine has pushed no modes yet, so a list
-- built now is empty for the whole session.
self.rebuild = OptionsResolutionRow_Rebuild
self.deferred = 1
OptionsNumFuncRow_OnLoad(self,
GetCurrentResolution, SetScreenResolution,
"1", "Resolution",
"BENILLA_TOOLTIP_RESOLUTION")
OptionsResolutionRow_Rebuild(self)
OptionsDropdownRow_Setup(self, self.entries)
</OnLoad></Scripts>
</Frame>
<Frame name="$parentRowVerticalSync" inherits="OptionsCheckboxRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowResolution" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowResolution" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
-- Deferred: `gxVSync` is registered **latched**
-- (`cvars.rs`), so a write only stages until
-- `RestartGx`, which is what Apply calls. An
-- earlier comment here said "vsync changes live"
-- — it cannot, and that mismatch is why the
-- setting came back on after a relaunch.
self.deferred = 1
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: our own row (the reference draws to
-- the backbuffer), and no Multisampling, which
-- misses alpha-tested cutouts. Deferred: a write
-- rebuilds the render target.
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 the bounds on show, as OptionsFrame_Load does, so
an addon's write lands. -->
<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 (fix-wind): the sway gain, 0.25..3 (100% = the shipped tuning). -->
<Frame name="$parentRowFoliageWindStrength" inherits="OptionsSliderRowTemplate">
<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, "foliageWindStrength",
BENILLA_ADVGFX.foliageWindStrength,
"BENILLA_TOOLTIP_FOLIAGE_WIND_STRENGTH")
OptionsSliderRow_Setup(self, 0.25, 3, 0.25)
</OnLoad></Scripts>
</Frame>
<!-- MONKEY (ao): numeric tiers through the existing localised dropdown. -->
<Frame name="$parentRowAmbientOcclusion" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowFoliageWindStrength" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowFoliageWindStrength" 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>
<!-- GFX (volumetric light): the shaft tiers, 0 Off / 1 Medium / 2 High. -->
<Frame name="$parentRowVolumetricLight" inherits="OptionsDropdownRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowZoneSkyboxes" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowZoneSkyboxes" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "volumetricLight", BENILLA_ADVGFX.volumetricLight,
"BENILLA_TOOLTIP_VOLUMETRIC_LIGHT")
OptionsDropdownRow_Setup(self, {
{ text = BENILLA_ADVGFX.fogOff, value = "0" },
{ text = BENILLA_ADVGFX.qMedium, value = "1" },
{ text = BENILLA_ADVGFX.qHigh, value = "2" },
})
</OnLoad></Scripts>
</Frame>
<!-- GFX (volumetric light): the shafts' brightness, 0..2 (1 = shipped). -->
<Frame name="$parentRowVolumetricLightStrength" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowVolumetricLight" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowVolumetricLight" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "volumetricLightStrength",
BENILLA_ADVGFX.volumetricLightStrength,
"BENILLA_TOOLTIP_VOLUMETRIC_LIGHT_STRENGTH")
OptionsSliderRow_Setup(self, 0, 2, 0.25)
</OnLoad></Scripts>
</Frame>
<!-- GFX (moonlight): the additive moon term, 0..2 (0 = the reference night). -->
<Frame name="$parentRowMoonLight" inherits="OptionsSliderRowTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRowVolumetricLightStrength" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
<Anchor point="TOPRIGHT" relativeTo="$parentRowVolumetricLightStrength" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
</Anchors>
<Scripts><OnLoad>
OptionsRow_OnLoad(self, "moonLight", BENILLA_ADVGFX.moonLight,
"BENILLA_TOOLTIP_MOONLIGHT")
OptionsSliderRow_Setup(self, 0, 2, 0.25)
</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>
<!-- 1.12's AdvancedOptionsCombatText box, as uvar rows. -->
<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; 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 SMSG_PERIODICAURALOG body
(`0x626dee`). -->
<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>
<!-- Bar rows are API rows over PLAYER_FIELD_BYTES byte 2, resolved
at click time. Always Show is a uvar: SetActionBarToggles drops
a fifth argument (`0x4e770e`). -->
<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>
<!-- Needs Right ActionBar (UIOptionsFrame.lua: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")
-- UIOptionsFrame.xml:680-683's click arm.
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>
<!-- No HIDE_OUTDOOR_WORLD_STATE row: there is no zone-objective
tracker. -->
<Frame name="$parentInterface" hidden="true">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Frames>
<!-- cvarEvent wakes TextStatusBar'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; the mode greys with its switch
(UIOptionsFrame.lua:697-701). Neither row applies anything:
1.12's options only write the uvars (UIOptionsFrame.lua:65),
and the target frames' OnUpdates show or hide the frame on
the next frame (TargetFrame.lua:492-501). Called from a row,
TargetofTarget_Update would refresh the row's debuffs
(RefreshBuffs(this, ...), TargetFrame.lua:538). -->
<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")
</OnLoad></Scripts>
</Frame>
<!-- The label is ours, since 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" },
})
</OnLoad></Scripts>
</Frame>
<!-- PLAYER_FLAGS bits, API rows
(UIOptionsFrame.lua: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>
<!-- 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>
<!-- No Reset Tutorials button: 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>
<!-- Default "1" (UIOptionsFrame.lua:645-646). -->
<Scripts><OnLoad>
OptionsFuncRow_OnLoad(self, TutorialsEnabled,
BenillaOptionsFrame_SetTutorialsEnabled, "1",
"Show Tutorials", "OPTION_TOOLTIP_SHOW_TUTORIALS")
</OnLoad></Scripts>
</Frame>
<!-- Label and tooltip name the tips differently; both are
1.12's. -->
<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>
<!-- 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". -->
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 reads (UIOptionsFrame.lua:253-255)
and writes it (l.337). The filter drops a
SpamMessages.dbc match 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 1.12's UnitName* checkboxes. The plate rows are era
rows: 1.12 has only the keybinding. -->
<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 of 21. -->
<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>
<!-- enableMouse: rows are plain Frames, so the page 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>
<!-- CENTER-40: the 1.12 string clips at CENTER-80. -->
<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>
<!-- Declared before the faux frame so it draws beneath
it. -->
<Frame name="$parentScrollFrameScrollBarTrough" inherits="BenillaScrollTroughTemplate"/>
<!-- Ends at -32, so the kit's bar rides the -26..-10
gutter. -->
<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>
<!-- KEYBINDINGS_ROW_HEIGHT must stay a global: this
chunk cannot see another file's local. -->
<OnVerticalScroll>FauxScrollFrame_OnVerticalScroll(KEYBINDINGS_ROW_HEIGHT, KeyBindingsPage_Update)</OnVerticalScroll>
<!-- Fires before the page's guard, so it is
replaced: an armed capsule binds the wheel. -->
<OnMouseWheel>
if not KeyBindingsPage.selected then
ScrollFrameTemplate_OnMouseWheel(arg1)
end
</OnMouseWheel>
</Scripts>
</ScrollFrame>
</Frames>
<!-- Rows and the bar bubble the wheel here. -->
<Scripts>
<OnMouseWheel>
if not KeyBindingsPage.selected then
BenillaFauxScrollFrame_OnMouseWheel(getglobal(this:GetName() .. "ScrollFrame"), arg1)
end
</OnMouseWheel>
</Scripts>
</Frame>
<!-- One per OPTIONS_PAGE_ROWS page. -->
<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>
<!-- KEYBINDINGS_SEARCH_ROWS (8) frames. -->
<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>
<!-- Inset 21/20 so the trough, which hangs 21 above and 20 below the
bar, lands flush. -->
<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 geometry in the 1.12 Common-Input-Border; 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>
<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 ── -->
<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, 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, 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>
<!-- BenillaOptionsFrame, because the stock OptionsFrame.xml owns `OptionsFrame`. Chat-tab hover
(FloatingChatFrame.lua:842/860) reads the hidden UIOptionsFrame, so it works while this
window, which does not cover the chat, is open. -->
<Script><![CDATA[
-- The reference's OptionsFrame row (UIParent.lua:16): the centre slot, openable while dead.
UIPanelWindows["BenillaOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 }
]]></Script>
</Ui>