Vampify v0.4.0

This commit is contained in:
2026-08-30 15:37:26 +02:00
parent ad50ebe636
commit d3ad691770
14 changed files with 271 additions and 41 deletions
+76 -9
View File
@@ -30,7 +30,7 @@ if CreateFrame then
-- -- refreshSliders() below needs to push their persisted values in on OnShow, same as
-- sliderFont/sliderRise already do.
local swatch, btnMove, btnPosReset, posLabel, sliderFont, sliderRise, btnDemo, btnOutline,
sliderPillH, sliderPanelBarH
sliderPillH, sliderPanelBarH, sliderDuration
local function db() return VampifyConfig.get() end
@@ -247,6 +247,10 @@ if CreateFrame then
-- W.SetSliderEnabled, which follows Blizzard's own hide-the-thumb recipe.
W.SetSliderEnabled(sliderRise, posEnabled)
W.SetSliderEnabled(sliderFont, posEnabled)
-- Fade duration is the same category as fontSize/rise above: it shapes OUR pooled
-- FontStrings only (gui/sct.lua's S.spawn reads sct.duration into s.dur), so it follows
-- the same posEnabled greying.
W.SetSliderEnabled(sliderDuration, posEnabled)
if btnDemo then W.SetButtonEnabled(btnDemo, posEnabled) end
-- The outline shapes OUR numbers only; Blizzard's engine draws its own.
if btnOutline then W.SetButtonEnabled(btnOutline, posEnabled) end
@@ -274,6 +278,12 @@ if CreateFrame then
sliderPanelBarH:SetValue(v)
getglobal("VampifyOptionsPanelBarHeightSliderText"):SetText(sliderPanelBarH.vfLabel .. ": " .. v)
end
if sliderDuration then
local v = sliderDuration.vfGetter()
sliderDuration:SetValue(v)
getglobal("VampifyOptionsDurationSliderText"):SetText(
sliderDuration.vfLabel .. ": " .. string.format(sliderDuration.vfFmt or "%s", v))
end
end
-- ------------------------------------------------------------------
@@ -284,7 +294,10 @@ if CreateFrame then
local f = CreateFrame("Frame", "VampifyOptionsFrame", UIParent)
f:SetWidth(340)
f:SetHeight(540)
f:SetHeight(608) -- +42 (Fade duration slider) +26 (Text shadow checkbox) over the
-- previous 540; fitHeight() below still re-measures against the
-- real info-panel position on every OnShow, so this is only the
-- pre-first-show estimate, not the operative bound.
f:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
-- HIGH, deliberately NOT DIALOG. Blizzard's ColorPickerFrame lives at DIALOG, and a frame
-- created later in the same strata draws on top of it -- so at DIALOG this window buried
@@ -593,27 +606,42 @@ if CreateFrame then
-- ---- SCT sliders -------------------------------------------------------------------
-- Replaces the X/Y entry boxes: raw anchor offsets meant nothing to a human, whereas these
-- two are the values you actually want to tune by eye.
local function makeSlider(name, label, lo, hi, step, getter, setter)
-- fmt (optional): a string.format pattern for the slider's own value, e.g. "%.1f" for a
-- fractional-second slider (Fade duration below, step 0.1). Omitted, values print with a
-- plain tostring -- unchanged behaviour for every integer-step slider that existed before it.
local function makeSlider(name, label, lo, hi, step, getter, setter, fmt)
local sl = CreateFrame("Slider", name, f, "OptionsSliderTemplate")
sl:SetWidth(200)
sl:SetHeight(16)
sl:SetMinMaxValues(lo, hi)
sl:SetValueStep(step)
sl:SetPoint("TOPLEFT", f, "TOPLEFT", x + 6, y)
getglobal(name .. "Low"):SetText(tostring(lo))
getglobal(name .. "High"):SetText(tostring(hi))
getglobal(name .. "Low"):SetText(fmt and string.format(fmt, lo) or tostring(lo))
getglobal(name .. "High"):SetText(fmt and string.format(fmt, hi) or tostring(hi))
local cap = getglobal(name .. "Text")
W.ApplyFont(cap, 11)
sl.vfLabel = label
sl.vfSetter = setter
sl.vfGetter = getter
sl.vfStep = step
sl.vfFmt = fmt
sl:SetScript("OnValueChanged", function()
local v = this:GetValue()
-- OptionsSliderTemplate does not quantise for us in 1.12; round to the step so the
-- stored value stays a clean integer instead of 15.9999.
v = math.floor(v + 0.5)
-- OptionsSliderTemplate does not quantise for us in 1.12; round to the slider's own
-- step by hand. math.floor(v/step+0.5)*step generalises the old "nearest integer"
-- rounding (which was step-1-only, hardcoded) to the fractional step a duration-in-
-- seconds slider needs (0.1) -- and is a no-op for every existing step-1 slider.
v = math.floor(v / this.vfStep + 0.5) * this.vfStep
-- Round-trip a fractional value through its own format string (e.g. "%.1f") before
-- storing it. The multiply above leaves binary-float noise (1.2000000000000002),
-- which would both write an ugly value into SavedVariables and never compare equal
-- to the plain decimal literal a getter's own fallback or a test uses -- the
-- round-trip snaps it back to the canonical double for "1.2". No-op for integer
-- sliders (fmt is nil there).
local txt = this.vfFmt and string.format(this.vfFmt, v) or tostring(v)
if this.vfFmt then v = tonumber(txt) end
this.vfSetter(v)
getglobal(this:GetName() .. "Text"):SetText(this.vfLabel .. ": " .. v)
getglobal(this:GetName() .. "Text"):SetText(this.vfLabel .. ": " .. txt)
end)
y = y - 42
return sl
@@ -642,6 +670,24 @@ if CreateFrame then
cfg.sct.rise = v
end)
-- Fade duration -- how long a number stays on screen (gui/sct.lua's S.spawn does
-- "s.dur = sct.duration or DUR_FALLBACK" fresh on every spawn, not cached, so no applyX
-- entry point is needed here: the very next number picks up a changed value on its own,
-- same as the rise slider above.
sliderDuration = makeSlider("VampifyOptionsDurationSlider", "Fade duration", 0.5, 4.0, 0.1,
function()
local cfg = db()
return (cfg and cfg.sct and cfg.sct.duration) or 1.5
end,
function(v)
local cfg = db()
if not (cfg and cfg.sct) then return end
cfg.sct.duration = v
end,
"%.1f")
W.AttachTooltip(sliderDuration, "How long a Vampify combat-text number stays on screen"
.. " before fading out, in seconds.")
-- Text effect. Cycles rather than three radio buttons: it is one setting with three steps,
-- and the label always states the current one, so nothing is hidden behind a menu.
local OUTLINES = { "THICKOUTLINE", "OUTLINE", "" }
@@ -672,6 +718,27 @@ if CreateFrame then
end
y = y - 28
-- Text shadow -- the other half of "readable over anything" alongside the outline above.
-- Getter mirrors gui/sct.lua's own shadowOn(): default ON, an EXPLICIT false is what turns
-- it off (a missing/unmigrated key must not read as off). applyFont() re-stamps every
-- pooled FontString immediately, same as the outline cycle button above -- otherwise
-- already-spawned slots would keep the old shadow state until the pool cycled.
local cbShadow = CreateCheckbox(f, "Text shadow",
function()
local cfg = db()
local sct = cfg and cfg.sct
if sct and sct.shadow == false then return false end
return true
end,
function(v)
local cfg = db()
if cfg and cfg.sct then cfg.sct.shadow = v end
if VampifySCT and VampifySCT.applyFont then VampifySCT.applyFont() end
end)
place(cbShadow, -26)
W.AttachTooltip(cbShadow, "Drops a shadow behind Vampify's own combat-text numbers, for"
.. " readability over bright backgrounds. On by default.")
-- ---- display size (2026-08-25, feature request: "two more sliders in the options that
-- determine the height of the bar and the detail bars") -----------------------------------
-- Two sliders, same makeSlider() recipe as the SCT ones above, driving VampifyDisplay's own