Common/frames.lua

297 lines
8.1 KiB
Lua

local name, addon = ...
local embed = addon:LibInit("zzCommon-Frames", 18, {'AddDrag','LoadFrame','GetFrameCoords','CreateSecureFrame'})
if(type(embed) ~= 'function') then return end
local base = LibStub('zzCommon-Frames')
base['frames'] = base['frames'] or {}
local function round(num, idp)
return math.floor(num * (10^(idp or 0)) + 0.5) / (10^(idp or 0))
end
local function dragAble()
return true
end
local defaults = {
['parent'] = UIParent,
['inherit'] = "SecureHandlerBaseTemplate SecureHandlerStateTemplate SecureHandlerEnterLeaveTemplate SecureHandlerMouseUpDownTemplate",
['width'] = 30,
['height'] = 30,
['selfPoint'] = "CENTER",
['relativTo'] = UIParent,
['relativPoint'] = "CENTER",
['xoff'] = 0,
['yoff'] = 0,
['dragAble'] = dragAble,
['db'] = {},
}
local function setDefaultValues(frame)
if(not frame['db'] and frame['name'] and addon['db']) then
addon['db']['profile'][frame['name']] = addon['db']['profile'][frame['name']] or {}
addon['db']['profile'][frame['name']]['points'] = addon['db']['profile'][frame['name']]['points'] or {}
frame['db'] = addon['db']['profile'][frame['name']]['points']
end
for k, v in pairs(defaults) do
if(frame[k] == nil) then
frame[k] = v
end
end
return frame
end
local function saveFrame(frame)
local db = frame['db']
local fn = frame:GetName()
db[fn] = db[fn] or {
['xpos'] = 0,
['ypos'] = 0,
}
local x, y = frame:GetCenter()
local s = frame:GetEffectiveScale()
local uis = UIParent:GetScale()
x = x*s - GetScreenWidth()*uis/2
y = y*s - GetScreenHeight()*uis/2
db[fn]['xpos'] = round(x/uis,0)
db[fn]['ypos'] = round(y/uis,0)
end
local schedules = {}
local scheduleframe = CreateFrame("Frame")
scheduleframe:SetScript("OnEvent", function(self, event)
for i=1,#schedules do
schedules[i]['func'](schedules[i]['frame'])
end
wipe(schedules)
self:UnregisterEvent(event)
end)
local function addSchedule(frame, func)
schedules[#schedules + 1] = {
['frame'] = frame,
['func'] = func,
}
if(#schedules == 1) then
scheduleframe:RegisterEvent("PLAYER_REGEN_ENABLED")
end
end
local function getCoords(frame)
local s = frame:GetEffectiveScale()
local uis = UIParent:GetScale()
local fn = frame:GetName()
return frame['db'][fn]['xpos']*uis/s, frame['db'][fn]['ypos']*uis/s
end
local function loadFrame(frame)
if not frame then return end
if( InCombatLockdown() ) then
addSchedule(frame, loadFrame)
return
end
frame:SetMovable(true)
local db = frame['db']
local fn = frame:GetName()
db[fn] = db[fn] or {
['xpos'] = 0,
['ypos'] = 0,
}
local x, y = getCoords(frame)
frame:ClearAllPoints()
frame:SetPoint("CENTER", UIParent, "CENTER", x, y)
frame:SetUserPlaced(true)
end
local function storePoints(frame)
wipe(frame['db'])
for i = 1, frame:GetNumPoints() do
frame['db'][#frame['db'] + 1] = {frame:GetPoint(i)}
frame['db'][#frame['db']][2] = frame['db'][#frame['db']][2] and frame['db'][#frame['db']][2]:GetName() or "UIParent"
frame['db'][#frame['db']][4] = round(frame['db'][#frame['db']][4])
frame['db'][#frame['db']][5] = round(frame['db'][#frame['db']][5])
-- print("save", frame:GetName(),frame:GetPoint(i),frame['db'][#frame['db']][4],frame['db'][#frame['db']][5])
end
end
local function restorePoints(frame)
if(#frame['db']<1) then
storePoints(frame)
end
frame:ClearAllPoints()
for i = 1, #frame['db'] do
if(frame['db'][i][2] == "UIParent") then
frame['db'][i][2] = UIParent
end
-- print("load", frame:GetName(),frame['db'][i][1],_G[frame['db'][i][2]],frame['db'][i][3],frame['db'][i][4],frame['db'][i][5])
frame:SetPoint(frame['db'][i][1],frame['db'][i][2] == "UIParent" and UIParent or _G[frame['db'][i][2]],frame['db'][i][3],frame['db'][i][4],frame['db'][i][5])
end
end
local function toggle(frame)
if(frame:IsVisible()) then
frame:Hide()
else
frame:Show()
end
end
local function center(frame)
frame:ClearAllPoints()
frame:SetPoint("Center", UIParent,"Center",0,0)
saveFrame(frame)
end
local function center2(frame)
frame:ClearAllPoints()
frame:SetPoint("Center", UIParent,"Center",0,0)
storePoints(frame)
end
local function startMove(frame)
if InCombatLockdown() then return end
if(frame['locked']) then return end
if(frame['moveparent']) then
frame:GetParent():StartMoving()
frame:GetParent():SetUserPlaced(false)
else
frame:StartMoving()
frame:SetUserPlaced(false)
end
end
local function stopMove(frame)
if(frame['moveparent']) then
frame:GetParent():StopMovingOrSizing()
saveFrame(frame:GetParent())
else
frame:StopMovingOrSizing()
saveFrame(frame)
end
end
local function startMove2(frame)
if(not frame:dragAble()) then return end
frame:StartMoving()
frame:SetUserPlaced(false)
end
local function stopMove2(frame)
frame:StopMovingOrSizing()
storePoints(frame)
end
local function dragView(frame)
if(IsAltKeyDown() and frame:GetParent()['dragAble']() and not InCombatLockdown()) then
frame['tex']:SetColorTexture(0, .5, 0, .5)
frame:Show()
else
if(frame:IsVisible()) then
frame['tex']:SetColorTexture(0, 1, 0 , 0)
stopMove(frame)
frame:Hide()
end
end
end
local function checkShow(frame, elapsed)
frame['elapsed'] = frame['elapsed'] + elapsed
if(frame['elapsed']>1) then
dragView(frame)
frame['elapsed'] = 0
end
end
local function dragView2(frame)
if(IsAltKeyDown() and frame['dragAble']()) then
if(not frame:GetScript("OnUpdate")) then
frame:SetScript("OnUpdate", function(self, elapsed)
self['elapsed'] = self['elapsed'] + elapsed
if(self['elapsed']>1) then
self['elapsed'] = 0
dragView2(self)
end
end)
end
frame['tex']:SetColorTexture(0, .5, 0, .5)
else
frame:SetScript("OnUpdate", nil)
frame['tex']:SetColorTexture(0, 0, 0 , 0)
end
end
local lib = {}
function lib:GetFrameCoords()
return getCoords(self)
end
function lib:LoadFrame()
loadFrame(self)
end
function lib:AddDrag(frame,typ,tab)
tab = tab or {
['width'] = 32,
['height'] = 32,
['anchor'] = "BOTTOMLEFT",
['parentanchor'] = "TOPLEFT",
['xOffset'] = 0,
['yOffset'] = 0,
['offset'] = 16,
}
loadFrame(frame)
frame['center'] = center
frame['toggle'] = toggle
frame['dragframe'] = frame['dragframe'] or CreateFrame("Frame","$PARENTdrag",frame)
frame['dragframe']['elapsed'] = 0
frame['dragframe']:SetFrameStrata("LOW")
frame:SetMovable(true)
frame['dragframe']:SetMovable(true)
frame['dragframe']:EnableMouse(true)
frame['dragframe'].moveparent = true
frame['dragframe']:SetScript("OnUpdate", checkShow)
frame['dragframe']:SetScript("OnMouseDown", startMove)
frame['dragframe']:SetScript("OnMouseUp", stopMove)
if(typ == "BOX") then
frame['dragframe']:SetWidth(tab['width'])
frame['dragframe']:SetHeight(tab['height'])
frame['dragframe']:SetPoint(tab['anchor'], frame, tab['parentanchor'], tab['xOffset'], tab['yOffset'])
else
local offset = tab['offset']
frame['dragframe']:ClearAllPoints()
frame['dragframe']:SetPoint("TOPLEFT", frame, "TOPLEFT", -offset/2, offset/2)
frame['dragframe']:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", offset/2, -offset/2)
end
frame['dragframe']['tex'] = frame['dragframe']['tex'] or frame['dragframe']:CreateTexture()
frame['dragframe']['tex']:SetAllPoints(frame.dragframe)
frame['dragframe']['tex']:SetColorTexture(0,0,0,0)
frame['dragframe']:RegisterEvent("MODIFIER_STATE_CHANGED")
frame['dragframe']:SetScript("OnEvent",dragView)
frame['dragframe']:Hide()
end
function lib:CreateSecureFrame(fname)
if(type(fname) == 'string') then fname = {['name'] = fname} end
fname = setDefaultValues(fname)
local f = CreateFrame("Frame", fname['name'], fname['parent'], fname['inherit'], fname['id'])
f:SetSize(fname['width'], fname['height'])
f:SetPoint(fname['selfPoint'], fname['relativTo'], fname['relativPoint'], fname['xoff'], fname['yoff'])
f['elapsed'] = 0
f['db'] = fname['db']
f['center'] = center2
f['toggle'] = toggle
f['dragAble'] = fname['dragAble']
f['tex'] = f:CreateTexture()
f['tex']:SetAllPoints(f)
f['tex']:SetColorTexture(0,0,0,0)
f['tex']:SetDrawLayer("BACKGROUND")
f:RegisterEvent("MODIFIER_STATE_CHANGED")
f:SetScript("OnEvent",dragView2)
f:SetMovable(true)
f:EnableMouse(true)
f:SetScript("OnMouseUp", stopMove2)
f:SetScript("OnMouseDown", startMove2)
restorePoints(f)
base['frames'][#base['frames'] + 1] = f
return f
end
embed(lib)