You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.9 KiB

--------------------------------------------
-- http://wow.gamepedia.com/UI_Scale
-- http://www.wowinterface.com/forums/showthread.php?t=31813
--------------------------------------------
local addonName, addon = ...
addon.pixelPerfectFuncs = {}
local P = addon.pixelPerfectFuncs
function P:GetResolution()
-- return string.match(({GetScreenResolutions()})[GetCurrentResolution()], "(%d+)x(%d+)")
return GetPhysicalScreenSize()
end
-- The UI P:Scale goes from 1 to 0.64.
-- At 768y we see pixel-per-pixel accurate representation of our texture,
-- and again at 1200y if at 0.64 scale.
function P:GetPixelPerfectScale()
local hRes, vRes = P:GetResolution()
if vRes then
return 768 / vRes
else -- windowed mode before 8.0, or maybe something goes wrong?
return 1
end
end
-- scale perfect!
function P:PixelPerfectScale(frame)
frame:SetScale(P:GetPixelPerfectScale())
end
-- position perfect!
function P:PixelPerfectPoint(frame)
local left = frame:GetLeft()
local top = frame:GetTop()
frame:ClearAllPoints()
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", math.floor(left + 0.5), math.floor(top + 0.5))
end
--------------------------------------------
-- PixelUtil
--------------------------------------------
-- local effectiveScale = 1
-- function P:SetRelativeScale(scale)
-- effectiveScale = scale
-- end
-- function P:GetEffectiveScale()
-- return effectiveScale
-- end
-- function P:SetEffectiveScale(frame)
-- frame:SetScale(effectiveScale)
-- end
-- function P:Scale(uiUnitSize)
-- if uiUnitSize == 0 then
-- return 0
-- end
-- local uiUnitFactor = PixelUtil.GetPixelToUIUnitFactor()
-- local numPixels = Round((uiUnitSize * effectiveScale) / uiUnitFactor)
-- if uiUnitSize < 0.0 then
-- if numPixels > -1 then
-- numPixels = -1
-- end
-- else
-- if numPixels < 1 then
-- numPixels = 1
-- end
-- end
-- return numPixels * uiUnitFactor / effectiveScale
-- end
--------------------------------------------
-- some are stolen from ElvUI
--------------------------------------------
-- local function GetUIParentScale()
-- local scale = UIParent:GetScale()
-- return scale - scale % 0.1 ^ 2
-- end
local mult = 1
function P:SetRelativeScale(scale)
mult = 1 / scale
end
function P:GetEffectiveScale()
return P:GetPixelPerfectScale() / mult
end
function P:SetEffectiveScale(frame)
frame:SetScale(P:GetEffectiveScale())
end
--[[
local trunc = function(s) return s >= 0 and s-s%01 or s-s%-1 end
local round = function(s) return s >= 0 and s-s%-1 or s-s%01 end
function P:Scale(n)
return (mult == 1 or n == 0) and n or ((mult < 1 and trunc(n/mult) or round(n/mult)) * mult)
end
]]
function P:Scale(n)
if mult == 1 or n == 0 then
return n
else
local x = mult > 1 and mult or -mult
return n - n % (n < 0 and x or -x)
end
end
function P:Size(frame, width, height)
frame.width = width
frame.height = height
frame:SetSize(P:Scale(width), P:Scale(height))
end
function P:Width(frame, width)
frame.width = width
frame:SetWidth(P:Scale(width))
end
function P:Height(frame, height)
frame.height = height
frame:SetHeight(P:Scale(height))
end
function P:SetGridSize(region, gridWidth, gridHeight, gridSpacingH, gridSpacingV, columns, rows)
region._size_grid = true
region._gridWidth = gridWidth
region._gridHeight = gridHeight
region._gridSpacingH = gridSpacingH
region._gridSpacingV = gridSpacingV
region._rows = rows
region._columns = columns
if columns == 0 then
region:SetWidth(0.001)
else
region:SetWidth(P:Scale(gridWidth) * columns + P:Scale(gridSpacingH) * (columns - 1))
end
if rows == 0 then
region:SetHeight(0.001)
else
region:SetHeight(P:Scale(gridHeight) * rows + P:Scale(gridSpacingV) * (rows - 1))
end
end
function P:Point(frame, ...)
if not frame.points then frame.points = {} end
local point, anchorTo, anchorPoint, x, y
local n = select("#", ...)
if n == 1 then
point = ...
elseif n == 3 and type(select(2, ...)) == "number" then
point, x, y = ...
elseif n == 4 then
point, anchorTo, x, y = ...
else
point, anchorTo, anchorPoint, x, y = ...
end
tinsert(frame.points, {point, anchorTo or frame:GetParent(), anchorPoint or point, x or 0, y or 0})
local n = #frame.points
frame:SetPoint(frame.points[n][1], frame.points[n][2], frame.points[n][3], P:Scale(frame.points[n][4]), P:Scale(frame.points[n][5]))
end
function P:ClearPoints(frame)
frame:ClearAllPoints()
if frame.points then wipe(frame.points) end
end
--------------------------------------------
-- scale changed
--------------------------------------------
function P:Resize(frame)
if frame._size_grid then
P:SetGridSize(frame, frame._gridWidth, frame._gridHeight, frame._gridSpacingH, frame._gridSpacingV, frame._columns, frame._rows)
else
if frame.width then
frame:SetWidth(P:Scale(frame.width))
end
if frame.height then
frame:SetHeight(P:Scale(frame.height))
end
end
end
function P:Reborder(frame)
if not frame.backdropInfo then return end
local _r, _g, _b, _a = frame:GetBackdropColor()
local r, g, b, a = frame:GetBackdropBorderColor()
frame.backdropInfo.edgeSize = P:Scale(CELL_BORDER_SIZE or 1)
frame:ApplyBackdrop()
if _r then frame:SetBackdropColor(_r, _g, _b, _a) end
if r then frame:SetBackdropBorderColor(r, g, b, a) end
end
function P:Repoint(frame)
if not frame.points or #frame.points == 0 then return end
frame:ClearAllPoints()
for _, t in pairs(frame.points) do
frame:SetPoint(t[1], t[2], t[3], P:Scale(t[4]), P:Scale(t[5]))
end
end
-- local frames = {}
-- function P:SetPixelPerfect(frame)
-- tinsert(frames, frame)
-- end
-- function P:UpdatePixelPerfectFrames()
-- for _, f in pairs(frames) do
-- f:UpdatePixelPerfect()
-- end
-- end
--------------------------------------------
-- save & load position
--------------------------------------------
function P:SavePosition(frame, positionTable)
wipe(positionTable)
local left = math.floor(frame:GetLeft() + 0.5)
local top = math.floor(frame:GetTop() + 0.5)
positionTable[1], positionTable[2] = left, top
end
function P:LoadPosition(frame, positionTable)
if type(positionTable) ~= "table" or #positionTable ~= 2 then return end
P:ClearPoints(frame)
P:Point(frame, "TOPLEFT", UIParent, "BOTTOMLEFT", positionTable[1], positionTable[2])
return true
end
---------------------------------------------------------------------
-- pixel perfect (ElvUI)
---------------------------------------------------------------------
local function CheckPixelSnap(frame, snap)
if (frame and not frame:IsForbidden()) and frame.PixelSnapDisabled and snap then
frame.PixelSnapDisabled = nil
end
end
local function DisablePixelSnap(frame)
if (frame and not frame:IsForbidden()) and not frame.PixelSnapDisabled then
if frame.SetSnapToPixelGrid then
frame:SetSnapToPixelGrid(false)
frame:SetTexelSnappingBias(0)
frame.PixelSnapDisabled = true
elseif frame.GetStatusBarTexture then
local texture = frame:GetStatusBarTexture()
if type(texture) == "table" and texture.SetSnapToPixelGrid then
texture:SetSnapToPixelGrid(false)
texture:SetTexelSnappingBias(0)
frame.PixelSnapDisabled = true
end
end
end
end
local function UpdateMetatable(obj)
local t = getmetatable(obj).__index
if not obj.DisabledPixelSnap and (t.SetSnapToPixelGrid or t.SetStatusBarTexture or t.SetColorTexture or t.SetVertexColor or t.CreateTexture or t.SetTexCoord or t.SetTexture) then
if t.SetSnapToPixelGrid then hooksecurefunc(t, "SetSnapToPixelGrid", CheckPixelSnap) end
if t.SetStatusBarTexture then hooksecurefunc(t, "SetStatusBarTexture", DisablePixelSnap) end
if t.SetColorTexture then hooksecurefunc(t, "SetColorTexture", DisablePixelSnap) end
if t.SetVertexColor then hooksecurefunc(t, "SetVertexColor", DisablePixelSnap) end
if t.CreateTexture then hooksecurefunc(t, "CreateTexture", DisablePixelSnap) end
if t.SetTexCoord then hooksecurefunc(t, "SetTexCoord", DisablePixelSnap) end
if t.SetTexture then hooksecurefunc(t, "SetTexture", DisablePixelSnap) end
t.DisabledPixelSnap = true
end
end
local obj = CreateFrame("Frame")
UpdateMetatable(CreateFrame("StatusBar"))
UpdateMetatable(obj:CreateTexture())
UpdateMetatable(obj:CreateMaskTexture())