Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions EllesmereUIDamageMeters/EllesmereUIDamageMeters.lua
Original file line number Diff line number Diff line change
Expand Up @@ -996,24 +996,22 @@ local function PhysicalPixels(userValue)
return value
end

-- Row geometry with both terms on ONE pixel grid. barHeight is stored as a
-- physical pixel count (plain slider), barSpacing in coordinate units (pixel
-- slider), so it carries the UI scale it was set at. Snapping only the height
-- left the stride between two grids and -((i-1) * stride) drifted down the
-- list: a spacing of 1 then rendered as 0px on some rows and 2px on others, at
-- a fractional UI scale and equally at a pixel-perfect one whenever the value
-- had been saved at another scale.
-- Row geometry with both terms on ONE pixel grid. barHeight and barSpacing are
-- both coordinate units, like the window width and fonts, so bars keep their
-- proportion to the window at any UI scale and a shared profile renders the
-- same relative size for everyone. Both are snapped against the same effective
-- scale: a stride between two grids drifts down the list (-((i-1) * stride)),
-- rendering a spacing of 1 as 0px on some rows and 2px on others.
-- Returns barH, barSp, stride and one physical pixel, in coordinate units.
local function RowMetrics(heightPx, spacingCoord, es)
local function RowMetrics(height, spacingCoord, es)
local PP = EUI and EUI.PP
if PP and PP.perfect and PP.SnapForES then
if not es or es <= 0 then es = (UIParent and UIParent:GetEffectiveScale()) or 1 end
local onePixel = PP.perfect / es
local barH = PP.SnapForES((heightPx or 18) * onePixel, es)
local barH = PP.SnapForES(height or 18, es)
local barSp = PP.SnapForES(spacingCoord or 2, es)
return barH, barSp, barH + barSp, onePixel
return barH, barSp, barH + barSp, PP.perfect / es
end
local barH, barSp = PhysicalPixels(heightPx or 18), spacingCoord or 2
local barH, barSp = height or 18, spacingCoord or 2
return barH, barSp, barH + barSp, (PP and PP.mult) or 1
end
-- On ns as well: CreateDMWindow sits at Lua 5.1's 60-upvalue cap, so its call
Expand Down
16 changes: 7 additions & 9 deletions EllesmereUIDamageMeters/EllesmereUIDamageMeters_SpellHistory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,12 @@ local function SetFont(fs, size)
fs:SetFont(font, size, flags)
end

-- Snapped through PP.Scale so accumulated row offsets (stride * index) don't drift off the pixel
-- grid from float dust -- without this, a spacing of 1 can round to 0px on some rows and 2px on others.
local function PhysicalPixels(val)
-- Icon size is a coordinate value like the window width and icon spacing, so it
-- keeps its proportion at any UI scale; only snapped onto the pixel grid.
local function SnapSize(val)
local PP = EUI and EUI.PP
local mult = (PP and PP.mult) or 1
local value = (val or 0) * mult
if PP and PP.Scale then return PP.Scale(value) end
return value
if PP and PP.Snap then return PP.Snap(val or 0) end
return val or 0
end

local function GetBarTexturePath()
Expand Down Expand Up @@ -485,7 +483,7 @@ local ANIM_SLIDE_PX = 6
-- the history length or growth direction never makes the row wander.
local function IconStripGeometry(count)
local sh = DB()
local iconSz = PhysicalPixels(sh.iconSize or 24)
local iconSz = SnapSize(sh.iconSize or 24)
local gap = sh.iconSpacing or 1
local dir = sh.growDirection or "LEFT"
count = max(1, count or sh.iconCount or 5)
Expand Down Expand Up @@ -807,7 +805,7 @@ BuildIconStrip = function()
-- during animation. No strip-level background needed.
end

local iconSz = PhysicalPixels(sh.iconSize or 24)
local iconSz = SnapSize(sh.iconSize or 24)
local gap = sh.iconSpacing or 1
local dir = sh.growDirection or "LEFT"
local iconZoom = sh.iconZoom or 0.08
Expand Down
60 changes: 60 additions & 0 deletions EllesmereUI_Migration.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4226,3 +4226,63 @@ EllesmereUI.RegisterMigration({
strip(ctx.profile.condOverrides)
end,
})

-- Damage Meters barHeight and Spell History shBarHeight/iconSize now render in UI
-- units instead of physical pixels (value * perfect / ppUIScale, UIParent-parented
-- frames). Multiply by that factor once so existing profiles keep their exact size.
-- GLOBAL on purpose: a profile stamp rides exports, so an old string would get the
-- RECIPIENT's factor frozen in; imports after this ran are read as UI units.
-- Per-profile stamps keep it idempotent when a full-account import resets flags.
EllesmereUI.RegisterMigration({
id = "dm_bar_height_ui_units_v1",
scope = "global",
description = "Convert Damage Meters bar height and Spell History bar height/icon size from physical pixels to UI units, keeping every existing profile's rendered size.",
body = function(ctx)
local ID = "dm_bar_height_ui_units_v1"
local db = ctx.db
if not db or type(db.profiles) ~= "table" then return end
-- No stamp without the real factor: an error retries next session
-- (Startup seeds ppUIScale at login).
local _, physH = GetPhysicalScreenSize()
if type(physH) ~= "number" or physH <= 0 then error("physical screen size not available") end
local uiScale = db.ppUIScale
if type(uiScale) ~= "number" or uiScale <= 0 then error("ppUIScale not set yet") end
-- Same legacy normalization EllesmereUI_Startup applies before SetScale.
if uiScale == 0.53 then uiScale = 0.5333333333
elseif uiScale == 0.71 then uiScale = 0.7111111111 end
local factor = (768 / physH) / uiScale
-- Within 1% the 40px slider maximum moves by under half a pixel, so the
-- snapped size is identical: pixel-perfect setups keep their values as-is.
local convert = math.abs(factor - 1) > 0.01
local function conv(v, default)
local n = type(v) == "number" and v or default
return floor(n * factor * 10000 + 0.5) / 10000
end
for _, profData in pairs(db.profiles) do
if type(profData) == "table" then
local stamps = profData._migrations
if type(stamps) ~= "table" then
stamps = {}
profData._migrations = stamps
end
if not stamps[ID] then
-- Folder present = DM ran in this profile; dm itself is
-- missing when every value was a stripped default.
local addon = convert and type(profData.addons) == "table"
and profData.addons.EllesmereUIDamageMeters
if type(addon) == "table" then
if type(addon.dm) ~= "table" then addon.dm = {} end
local dm = addon.dm
dm.barHeight = conv(dm.barHeight, 18)
local sh = dm.spellHistory
if type(sh) == "table" then
sh.shBarHeight = conv(sh.shBarHeight, 20)
sh.iconSize = conv(sh.iconSize, 36)
end
end
stamps[ID] = true
end
end
end
end,
})