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)