Release OEVG Cursive 1.6 with ClassicAPI tracking and appearance options

This commit is contained in:
2026-11-03 19:55:47 -04:00
parent 6fd8901c0f
commit 8240256726
13 changed files with 611 additions and 46 deletions
+276 -23
View File
@@ -4,6 +4,79 @@ end
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
local function ThemeBorder(frame)
if ShaguTweaks and (ShaguTweaks.DarkMode or ShaguTweaks.GoldMode) and GameTooltip then
frame:SetBackdropBorderColor(GameTooltip:GetBackdropBorderColor())
else
frame:SetBackdropBorderColor(1, 1, 1, 1)
end
end
local tooltipBorder = { edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8 }
local function AddAuraBorder(icon, parent)
if not Cursive.db.profile.auraborder then return end
local border = CreateFrame("Frame", nil, parent)
border:SetPoint("TOPLEFT", icon, "TOPLEFT", -2, 2)
border:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 2, -2)
border:SetBackdrop(tooltipBorder)
border:EnableMouse(false)
border:Hide()
icon.tooltipBorder = border
end
local function UpdateAuraBorder(icon)
if icon.tooltipBorder then
if icon:IsShown() then ThemeBorder(icon.tooltipBorder); icon.tooltipBorder:Show()
else icon.tooltipBorder:Hide() end
end
end
function Cursive.ApplyMenuStyle()
local f = CursiveSettingsWindow
if not f then return end
if Cursive.db.profile.classicmenu then
f:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true,
tileSize = 32, edgeSize = 32, insets = {left=8, right=8, top=8, bottom=8}})
f:SetBackdropColor(1, 1, 1, (Cursive.db.profile.menuopacity or 100) / 100)
ThemeBorder(f)
else
f:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Buttons\\WHITE8X8", edgeSize = 1})
f:SetBackdropColor(0.05, 0.05, 0.08, (Cursive.db.profile.menuopacity or 100) / 100)
f:SetBackdropBorderColor(0.25, 0.25, 0.35, 1)
end
if f.menuFill then
f.menuFill:SetTexture(0.025, 0.025, 0.035, (Cursive.db.profile.menuopacity or 100) / 100)
end
if f.classicHeader then
if ShaguTweaks and (ShaguTweaks.DarkMode or ShaguTweaks.GoldMode) and GameTooltip then
local r, g, b = GameTooltip:GetBackdropBorderColor()
f.classicHeader:SetVertexColor(r, g, b, 1)
else
f.classicHeader:SetVertexColor(1, 1, 1, 1)
end
end
if f.titleText then
f.titleText:ClearAllPoints()
if Cursive.db.profile.classicmenu then
f.titleText:SetPoint("TOP", f, "TOP", 0, -1)
else
f.titleText:SetPoint("LEFT", f.titleBar, "LEFT", 8, 0)
end
end
if f.titleBar then
if Cursive.db.profile.classicmenu then
f.titleBar:SetBackdrop(nil)
f.classicHeader:Show()
f.titleBar:SetHeight(32)
else
f.titleBar:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8X8"})
f.classicHeader:Hide()
f.titleBar:SetHeight(24)
f.titleBar:SetBackdropColor(0.22, 0.08, 0.38, 1)
end
end
end
local utils = Cursive.utils
local filter = Cursive.filter
@@ -102,10 +175,16 @@ local function GetBarThirdSectionWidth()
return config.maxcurses * (config.curseiconsize + ui.padding)
end
local function GetAuraGap()
-- Inverted rows put auras on the left, away from the top-right dragon.
local config = Cursive.db.profile
return (config.showelitedragon and not config.invertbars) and 12 or 0
end
local function GetBarWidth()
return GetBarFirstSectionWidth() +
GetBarSecondSectionWidth() +
GetBarThirdSectionWidth()
GetBarThirdSectionWidth() + GetAuraGap()
end
local function UpdateRootBarFrame()
@@ -221,6 +300,7 @@ end
ui.unitFrames = {} -- holds all unitFrames for all columns/rows
Cursive.UpdateFramesFromConfig = function()
if ui.UpdateFontPreview then ui.UpdateFontPreview(GetUIFont()) end
for col, rows in pairs(ui.unitFrames) do
for row, unitFrame in pairs(rows) do
if unitFrame and unitFrame:IsShown() then
@@ -233,8 +313,8 @@ Cursive.UpdateFramesFromConfig = function()
UpdateRootBarFrame()
end
-- after 3 seconds reset the unit frames so all changes are applied
Cursive:ScheduleEvent("resetUnitFrames", Cursive.ResetUnitFrames, 3)
-- Debounce slider movement, then rebuild rows with the new geometry.
Cursive:ScheduleEvent("resetUnitFrames", Cursive.ResetUnitFrames, 0.1)
end
Cursive.ResetUnitFrames = function()
@@ -246,12 +326,15 @@ Cursive.ResetUnitFrames = function()
end
end
end
-- Retired frames must not remain referenced by the flash driver.
for icon in pairs(ui.flashingCurseIcons) do ui.flashingCurseIcons[icon] = nil end
-- clear cached frames so they are recreated
ui.unitFrames = {}
end
ui.BarEnter = function()
if this.parent.healthBar then
if this.parent.testMode then return end
if this.parent.healthBar and not Cursive.db.profile.healthborder then
this.parent.healthBar.border:SetBackdropBorderColor(1, 1, 1, 1)
end
this.parent.hover = true
@@ -268,6 +351,23 @@ ui.BarLeave = function()
GameTooltip:Hide()
end
local function UpdateEliteDragon(bar, classification)
if not bar.eliteDragon then return end
if classification == "elite" or classification == "worldboss" or classification == "rareelite" then
bar.eliteDragon:SetTexture("Interface\\AddOns\\Cursive\\img\\EliteDragon")
bar.eliteDragon:SetDesaturated(classification == "rareelite")
bar.eliteDragon:Show()
if bar.eliteDragonTail then
bar.eliteDragonTail:SetTexture("Interface\\AddOns\\Cursive\\img\\EliteDragon")
bar.eliteDragonTail:SetDesaturated(classification == "rareelite")
bar.eliteDragonTail:Show()
end
else
bar.eliteDragon:Hide()
if bar.eliteDragonTail then bar.eliteDragonTail:Hide() end
end
end
ui.BarUpdate = function()
if not this.guid or this.guid == 0 then
this:Hide()
@@ -280,6 +380,7 @@ ui.BarUpdate = function()
this.tick = GetTime() + 0.05
end
UpdateEliteDragon(this, UnitClassification(this.guid))
-- update statusbar values if it exists
if this.healthBar then
this.healthBar:SetMinMaxValues(0, UnitHealthMax(this.guid))
@@ -290,7 +391,7 @@ ui.BarUpdate = function()
this.healthBar:SetStatusBarColor(r, g, b, a)
-- update health bar border
if this.healthBar.border then
if this.healthBar.border and not Cursive.db.profile.healthborder then
if this.hover then
this.healthBar.border:SetBackdropBorderColor(1, 1, 1, 1)
elseif UnitAffectingCombat(this.guid) then
@@ -354,6 +455,7 @@ ui.BarUpdate = function()
end
ui.BarClick = function()
if this.parent.testMode then return end
if arg1 == "LeftButton" then
TargetUnit(this.parent.guid)
elseif arg1 == "RightButton" then
@@ -375,7 +477,7 @@ local function CreateBarFirstSection(unitFrame, guid)
-- Normal positioning (leftmost)
firstSection:SetPoint("LEFT", unitFrame, "LEFT", 0, 0)
end
firstSection:SetWidth(GetBarFirstSectionWidth())
firstSection:SetHeight(config.height)
firstSection:EnableMouse(false)
@@ -424,7 +526,7 @@ local function CreateBarSecondSection(unitFrame, guid)
-- Normal positioning relative to first section
secondSection:SetPoint("LEFT", unitFrame.firstSection, "RIGHT", 0, 0)
end
secondSection:SetWidth(GetBarSecondSectionWidth())
secondSection:SetHeight(config.height)
unitFrame.secondSection = secondSection
@@ -438,7 +540,7 @@ local function CreateBarSecondSection(unitFrame, guid)
-- create health bar
if config.showhealthbar then
local healthBar = CreateFrame("StatusBar", "CursiveHealthBar", secondSection)
healthBar:SetStatusBarTexture(config.bartexture)
healthBar:SetStatusBarTexture(config.modernhealth and "Interface\\AddOns\\Cursive\\img\\BlizzardRetailBar" or config.bartexture)
healthBar:SetStatusBarColor(1, .8, .2, 1)
healthBar:SetMinMaxValues(0, 100)
healthBar:SetValue(20)
@@ -465,18 +567,18 @@ local function CreateBarSecondSection(unitFrame, guid)
end
-- create health bar backdrops
if pfUI and pfUI.uf then
if pfUI and pfUI.uf and not config.healthborder then
pfUI.api.CreateBackdrop(healthBar)
healthBar.border = healthBar.backdrop
else
healthBar:SetBackdrop(ui.background)
healthBar:SetBackdropColor(0, 0, 0, 1)
local border = CreateFrame("Frame", "CursiveBorder", healthBar.bar)
border:SetBackdrop(ui.border)
local border = CreateFrame("Frame", "CursiveBorder", healthBar)
border:SetBackdrop(config.healthborder and tooltipBorder or ui.border)
border:SetBackdropColor(.2, .2, .2, 1)
border:SetPoint("TOPLEFT", healthBar.bar, "TOPLEFT", -2, 2)
border:SetPoint("BOTTOMRIGHT", healthBar.bar, "BOTTOMRIGHT", 2, -2)
border:SetPoint("TOPLEFT", healthBar, "TOPLEFT", -2, 2)
border:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", 2, -2)
healthBar.border = border
end
else
@@ -503,9 +605,9 @@ local function CreateBarThirdSection(unitFrame, guid)
thirdSection:SetPoint("LEFT", unitFrame, "LEFT", 0, 0)
else
-- Normal positioning relative to second section
thirdSection:SetPoint("LEFT", unitFrame.secondSection, "RIGHT", 0, 0)
thirdSection:SetPoint("LEFT", unitFrame.secondSection, "RIGHT", GetAuraGap(), 0)
end
thirdSection:SetWidth(GetBarThirdSectionWidth())
thirdSection:SetHeight(config.height)
thirdSection:EnableMouse(false)
@@ -526,6 +628,7 @@ local function CreateBarThirdSection(unitFrame, guid)
curse:SetPoint("LEFT", thirdSection, "LEFT", i * ui.padding + ((i - 1) * config.curseiconsize), 0)
end
AddAuraBorder(curse, thirdSection)
curse.timer = thirdSection:CreateFontString(nil, "OVERLAY", "GameFontNormal")
curse.timer:SetFontObject(GameFontHighlight)
SafeSetFont(curse.timer, GetUIFont(), config.cursetimersize, "OUTLINE")
@@ -549,6 +652,7 @@ local function CreateBarThirdSection(unitFrame, guid)
ghost:SetHeight(config.curseiconsize)
ghost:SetAlpha(config.ghosticonalpha)
ghost:Hide()
AddAuraBorder(ghost, thirdSection)
unitFrame.ghostIcons[i] = ghost
end
@@ -561,6 +665,7 @@ local function CreateBarThirdSection(unitFrame, guid)
shadowVulnIcon:SetTexture("Interface\\Icons\\Spell_Shadow_ShadowBolt")
shadowVulnIcon:SetAlpha(0.3)
AddAuraBorder(shadowVulnIcon, thirdSection)
shadowVulnIcon.timer = thirdSection:CreateFontString(nil, "OVERLAY", "GameFontNormal")
shadowVulnIcon.timer:SetFontObject(GameFontHighlight)
SafeSetFont(shadowVulnIcon.timer, GetUIFont(), config.cursetimersize, "OUTLINE")
@@ -575,6 +680,27 @@ end
local function CreateBar(row, col, guid)
local unitFrame = CreateFrame("Frame", "CursiveUnitFrame", ui.rootBarFrame)
unitFrame.guid = guid
if Cursive.db.profile.showelitedragon then
local dragonLayer = CreateFrame("Frame", nil, unitFrame)
dragonLayer:EnableMouse(false)
local dragon = dragonLayer:CreateTexture(nil, "OVERLAY")
unitFrame.eliteDragonLayer = dragonLayer
dragon:SetWidth(30)
dragon:SetHeight(28 * 34 / 108)
-- Anchored after the health/name section has been constructed.
-- Two adjoining crops keep the crest and right wing, leaving out
-- the portrait ring and the bottom-left curl.
dragon:SetTexCoord(140 / 256, 1, 0, 34 / 128)
local tail = dragonLayer:CreateTexture(nil, "OVERLAY")
tail:SetWidth(30 * 36 / 116)
tail:SetHeight(28 * 74 / 108)
tail:SetTexCoord(220 / 256, 1, 34 / 128, 108 / 128)
tail:SetPoint("TOPRIGHT", dragon, "BOTTOMRIGHT", 0, 0)
tail:Hide()
unitFrame.eliteDragonTail = tail
dragon:Hide()
unitFrame.eliteDragon = dragon
end
unitFrame:SetScript("OnUpdate", ui.BarUpdate)
@@ -596,6 +722,19 @@ local function CreateBar(row, col, guid)
CreateBarThirdSection(unitFrame, guid)
end
if unitFrame.eliteDragon then
-- Raise above the health StatusBar and its border child frame.
local anchor = unitFrame.healthBar or unitFrame.secondSection
local topLevel = anchor:GetFrameLevel()
if unitFrame.healthBar and unitFrame.healthBar.border then
topLevel = math.max(topLevel, unitFrame.healthBar.border:GetFrameLevel())
end
unitFrame.eliteDragonLayer:SetFrameLevel(topLevel + 2)
unitFrame.eliteDragonLayer:SetAllPoints(anchor)
-- Curl the ornament around the upper-right corner of the health/name bar.
unitFrame.eliteDragon:SetPoint("TOPRIGHT", unitFrame.healthBar or unitFrame.secondSection,
"TOPRIGHT", 8, 5)
end
ui.unitFrames[col][row] = unitFrame
return unitFrame
end
@@ -650,6 +789,13 @@ local GHOST_CURSE_FALLBACK_ICON = "Interface\\Icons\\Spell_Shadow_CurseOfSargera
-- focus frame support at all (that's a later-expansion addition), and
-- UnitExists("focus") hard-errors here rather than just returning nil.
local function SafeUnitDebuff(guid, i)
if Cursive.db.profile.useclassicapi and C_UnitAuras and C_UnitAuras.UnitAura then
local _, targetGuid = UnitExists("target")
if guid == targetGuid then
local name, texture = C_UnitAuras.UnitAura("target", i, "HARMFUL")
return texture
end
end
local _, targetGuid = UnitExists("target")
if targetGuid and guid == targetGuid then
return UnitDebuff("target", i)
@@ -945,6 +1091,12 @@ local function DisplayGuid(guid)
end
end
for i = 1, Cursive.db.profile.maxcurses do
UpdateAuraBorder(unitFrame["curse" .. i])
UpdateAuraBorder(unitFrame.ghostIcons[i])
end
UpdateAuraBorder(unitFrame.shadowVulnIcon)
if unitFrame.healthBar and Cursive.db.profile.healthborder then ThemeBorder(unitFrame.healthBar.border) end
unitFrame:Show()
ui.numDisplayed = ui.numDisplayed + 1
@@ -985,6 +1137,81 @@ local function CheckForCleanup(guid, time)
end
end
-- Session-only samples reuse the real row construction and layout.
function Cursive.SetTestMode(enabled)
Cursive.testMode = enabled and true or false
Cursive.ResetUnitFrames()
end
local testIcons = {
"Interface\\Icons\\Spell_Shadow_CurseOfSargeras",
"Interface\\Icons\\Spell_Shadow_AbominationExplosion",
"Interface\\Icons\\Spell_Fire_Immolation",
"Interface\\Icons\\Spell_Shadow_Requiem",
}
local function RenderTestBars()
local config = Cursive.db.profile
local now = GetTime()
for col = 1, config.maxcol do
ui.unitFrames[col] = ui.unitFrames[col] or {}
for row = 1, config.maxrow do
local bar = ui.unitFrames[col][row]
if not bar then
bar = CreateBar(row, col, nil)
bar.testMode = true
bar:SetScript("OnUpdate", nil)
end
UpdateEliteDragon(bar, row == 1 and "elite" or (row == 2 and "rareelite" or "normal"))
local x, y = GetBarCords(row, col)
bar:ClearAllPoints()
bar:SetPoint(config.expandupwards and "BOTTOMLEFT" or "TOPLEFT", ui.rootBarFrame,
config.expandupwards and "BOTTOMLEFT" or "TOPLEFT", x, y)
if bar.nameText then bar.nameText:SetText(row == 1 and "Test: Defias Raider" or "Test: Training Dummy") end
if bar.hpText then bar.hpText:SetText("2453") end
if bar.healthBar then
bar.healthBar:SetMinMaxValues(0, 4000)
bar.healthBar:SetValue(2453)
bar.healthBar:SetStatusBarColor(0.8, 0.2 + math.mod(row, 3) * 0.2, 0.2, 1)
if config.healthborder then ThemeBorder(bar.healthBar.border) end
end
if bar.icon then SetRaidTargetIconTexture(bar.icon, math.mod(row - 1, 8) + 1); bar.icon:Show() end
if bar.target_left then
if row == 1 then bar.target_left:Show() else bar.target_left:Hide() end
end
local offset = config.notifyshadowvuln and 1 or 0
if config.notifyshadowvuln then
bar.shadowVulnIcon:ClearAllPoints()
bar.shadowVulnIcon:SetPoint(config.invertbars and "RIGHT" or "LEFT", bar.thirdSection,
config.invertbars and "RIGHT" or "LEFT", config.invertbars and -ui.padding or ui.padding, 0)
bar.shadowVulnIcon:SetAlpha(1)
bar.shadowVulnIcon.timer:SetText("5")
bar.shadowVulnIcon.timer:Show()
bar.shadowVulnIcon:Show()
else bar.shadowVulnIcon:Hide() end
for i = 1, config.maxcurses do
local icon = bar["curse" .. i]
local slot = i + offset
if slot <= config.maxcurses then
local position = slot * ui.padding + (slot - 1) * config.curseiconsize
icon:ClearAllPoints()
icon:SetPoint(config.invertbars and "RIGHT" or "LEFT", bar.thirdSection,
config.invertbars and "RIGHT" or "LEFT", config.invertbars and -position or position, 0)
icon:SetTexture(testIcons[math.mod(i - 1, table.getn(testIcons)) + 1])
icon:SetAlpha(1)
local remaining = 18 - math.mod(now + i * 3, 18)
icon.timer:SetText(config.curseshowdecimals and string.format("%.1f", remaining) or math.ceil(remaining))
icon.timer:Show()
icon:Show()
else icon:Hide(); icon.timer:Hide() end
bar.ghostIcons[i]:Hide()
UpdateAuraBorder(icon)
end
UpdateAuraBorder(bar.shadowVulnIcon)
bar:Show()
end
end
end
local shouldDisplayGuids = {};
local displayedGuids = {};
@@ -992,7 +1219,7 @@ ui:SetAllPoints()
ui:SetScript("OnUpdate", function()
local config = Cursive.db.profile
if not config.enabled then
if not config.enabled and not Cursive.testMode then
return
end
@@ -1011,6 +1238,11 @@ ui:SetScript("OnUpdate", function()
return
end
if Cursive.testMode then
RenderTestBars()
return
end
-- reset display data
ui.row = 1
ui.col = 1
@@ -1207,7 +1439,7 @@ gcdTicker:SetScript("OnUpdate", function()
-- Preview mode: triggered directly by changing a GCD bar setting,
-- rather than trying to detect whether the options menu is open.
if ui.gcdPreviewUntil and GetTime() < ui.gcdPreviewUntil then
if (Cursive.testMode and bar.enabled) or (ui.gcdPreviewUntil and GetTime() < ui.gcdPreviewUntil) then
bar:SetMinMaxValues(0, 1)
bar:SetValue(0.6)
if not bar:IsShown() then
@@ -1744,7 +1976,10 @@ local function MakeRangeWidget(parent, entry, yOff)
getglobal(sliderName .. "High"):SetText(tostring(entry.max or 100))
getglobal(sliderName .. "Text"):SetText("")
slider:SetScript("OnValueChanged", function()
CallGetSet(entry, true, this:GetValue())
local minimum, maximum, step = entry.min or 0, entry.max or 100, entry.step or 1
local value = minimum + math.floor((this:GetValue() - minimum) / step + 0.5) * step
value = math.max(minimum, math.min(maximum, value))
CallGetSet(entry, true, value)
valLbl:SetText(tostring(CallGetSet(entry, false)))
end)
@@ -1956,8 +2191,14 @@ function ui.CreateSettingsWindow()
edgeSize = 1,
insets = { left = 1, right = 1, top = 1, bottom = 1 }
})
f:SetBackdropColor(0.05, 0.05, 0.08, 0.95)
f:SetBackdropColor(0.05, 0.05, 0.08, (Cursive.db.profile.menuopacity or 100) / 100)
f:SetBackdropBorderColor(0.25, 0.25, 0.35, 1)
Cursive.ApplyMenuStyle()
local menuFill = f:CreateTexture(nil, "BACKGROUND")
menuFill:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -8)
menuFill:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -8, 8)
f.menuFill = menuFill
Cursive.ApplyMenuStyle()
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
@@ -1973,10 +2214,20 @@ function ui.CreateSettingsWindow()
titleBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
titleBar:SetBackdropColor(0.22, 0.08, 0.38, 1)
f.titleBar = titleBar
local classicHeader = titleBar:CreateTexture(nil, "BACKGROUND")
classicHeader:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
classicHeader:SetWidth(360)
classicHeader:SetHeight(64)
classicHeader:SetPoint("TOP", f, "TOP", 0, 14)
f.classicHeader = classicHeader
Cursive.ApplyMenuStyle()
local title = titleBar:CreateFontString(nil, "OVERLAY")
title:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
title:SetTextColor(1, 0.84, 0, 1)
title:SetPoint("Left", titleBar, "Left", 8, 0)
f.titleText = title
local versionStr = GetAddOnMetadata("Cursive", "Version") or "?"
title:SetText("Cursive — Settings (v"..versionStr..")")
@@ -2006,7 +2257,7 @@ function ui.CreateSettingsWindow()
previewLabel:SetFont(STANDARD_TEXT_FONT, 9, "")
previewLabel:SetTextColor(0.6, 0.6, 0.65, 1)
previewLabel:SetPoint("TopLeft", previewSection, "TopLeft", 4, -2)
previewLabel:SetText("Font Preview")
previewLabel:SetText("Text Preview (bar sizes apply to unit rows)")
local previewName = previewSection:CreateFontString(nil, "OVERLAY")
SafeSetFont(previewName, GetUIFont(), 12, "THINOUTLINE")
@@ -2037,12 +2288,13 @@ function ui.CreateSettingsWindow()
previewSacrifice:SetText("Sacrifice: 18s | 1200 absorb")
local function ApplyPreviewFont(fontPath)
previewName:SetFont(fontPath, 12, "THINOUTLINE")
previewHp:SetFont(fontPath, 12, "THINOUTLINE")
previewCurseTimer:SetFont(fontPath, 12, "OUTLINE")
previewName:SetFont(fontPath, Cursive.db.profile.textsize, "THINOUTLINE")
previewHp:SetFont(fontPath, Cursive.db.profile.textsize, "THINOUTLINE")
previewCurseTimer:SetFont(fontPath, Cursive.db.profile.cursetimersize, "OUTLINE")
previewSacrifice:SetFont(fontPath, 10, "OUTLINE")
end
ui.UpdateFontPreview = ApplyPreviewFont
ApplyPreviewFont(GetUIFont())
local scrollFrame = CreateFrame("ScrollFrame", "CursiveSettingsScrollFrame", f, "UIPanelScrollFrameTemplate")
scrollFrame:SetPoint("TopLeft", f, "TopLeft", 16, -116)
@@ -2056,6 +2308,7 @@ function ui.CreateSettingsWindow()
local finalY = RenderOptionsInto(content, Cursive.cmdtable.args, -4)
content:SetHeight(math.abs(finalY) + 30)
Cursive.ApplyMenuStyle()
settingsWindow = f
return f
end