-------------------------------------------- -- 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: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.width then frame:SetWidth(P:Scale(frame.width)) end if frame.height then frame:SetHeight(P:Scale(frame.height)) end end function P:Reborder(frame) local _r, _g, _b, _a = frame:GetBackdropColor() local r, g, b, a = frame:GetBackdropBorderColor() frame:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Buttons\\WHITE8x8", edgeSize = P:Scale(1)}) frame:SetBackdropColor(_r, _g, _b, _a) frame:SetBackdropBorderColor(r, g, b, a) 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