-- https://www.youtube.com/watch?v=vuo8kD5zF5I MoveIt = LibStub("AceAddon-3.0"):NewAddon("MoveIt", "AceConsole-3.0", "AceEvent-3.0") AceGUI = LibStub("AceGUI-3.0") AceDB = LibStub("AceDB-3.0") MoveIt.version = "2.06" MoveIt.Modules = {} MoveIt.GUI = {} MoveIt.GUI.Modules = {} MoveIt.frameEvents = { StatusBar = { Normal = { "OnEvent" } } } MoveIt.frameHooks = {} MoveIt.enabledHooks = {} MoveIt.originalSettings = {} MoveIt.hookCount = 0 MoveIt.playerData = {} function MoveIt:OnInitialize() self.db = LibStub("AceDB-3.0"):New("MoveItDB", defaults, true) self:ConvertSettings() self:RegisterChatCommand("mit", "ChatCommand") end function MoveIt:OnEnable() self.Utils:GetPlayerData() local update = function() C_Timer.After(0.1, function() MoveIt:UpdateHooks() MoveIt:ApplyAll() end) end self:RegisterEvent("PLAYER_ENTERING_WORLD", update) self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", update) self:RegisterEvent("PLAYER_REGEN_ENABLED", update) self:RegisterEvent("ADDON_LOADED", update) self:RegisterEvent("PLAYER_LEVEL_UP", update) self:RegisterEvent("ZONE_CHANGED", update) end function MoveIt:ChatCommand(input) if self:GetArgs(input, 1) == "hooks" then self:PrintHooks(); return end if self:GetArgs(input, 1) == "pd" then self.Utils:PrintPlayerData(); return end if self:GetArgs(input, 1) == "find" and select(2, self:GetArgs(input, 2)) ~= nil then local searchTerm = select(2, self:GetArgs(input, 2)) local parent = select(3, self:GetArgs(input, 3)) print(self:FrameSearch(searchTerm, parent, true, " ")) return end MoveIt.GUI:Create() end function MoveIt:FrameSearch(text, parent, showType, seperator) local root = _G if parent ~= nil and _G[parent] ~= nil then root = _G[parent] end local results = "" local count = 0 local first = true local delimiter = seperator or "," for k, _ in pairs(root) do if string.sub(k, 1, string.len(text)) == text then local type = self:GetFrameType(k) if type ~= nil and type ~= "Font" then if not first then results = results .. delimiter else first = false end results = results .. k if showType then results = results .. ":" .. self.Utils.ColouredText(type, "ffff00") end count = count + 1 end end end if count > 100 then return "Too many results" end return results end function MoveIt:ConvertSettings() if self.db.profile.frames == nil then self.db.profile.frames = {} return end for k, v in pairs(self.db.profile.frames) do local oldSettings = v["ModifiedSettings"] if oldSettings ~= nil then self.db.profile.frames[k].Reposition = { Enabled = oldSettings.Reposition, OffsetX = oldSettings.RepositionOffsetX, OffsetY = oldSettings.RepositionOffsetY, AnchorPointFrom = oldSettings.AnchorPointFrom, AnchorPointTo = oldSettings.AnchorPointTo, AnchorTargetFrame = oldSettings.AnchorTargetFrame, } self.db.profile.frames[k].Resize = { Enabled = oldSettings.Resize, Width = oldSettings.ResizeWidth, Height = oldSettings.ResizeHeight } self.db.profile.frames[k].Scale = { Enabled = oldSettings.Scale, Multiplier = oldSettings.ScaleMultiplier } self.db.profile.frames[k].Flags = { Hide = oldSettings.Hide, Clamp = oldSettings.Clamp, Force = oldSettings.Force } v["ModifiedSettings"] = nil end end end function MoveIt:DeleteSettings(frameName) self.db.profile.frames[frameName] = nil end function MoveIt:GetFrameName(frame) --local name = "UIParent" --if pcall(frame:GetName() ~= nil then -- if _G[frame:GetName()] ~= nil then return frame:GetName() end --end return frame:GetDebugName() end function MoveIt:GetFrameHandle(frameName) if _G[frameName] ~= nil then return _G[frameName] end if string.find(frameName, ".") then local ref, count = self.Utils:SplitString(frameName, ".") if ref == nil then return nil end local parent = nil for i, v in ipairs(ref) do if i == 1 then --first if _G[v] == nil then return nil end parent = _G[v] elseif parent[v] == nil then return nil elseif i == count then return parent[v] else parent = parent[v] end end end end function MoveIt:IsValidFrame(frameName) local handle = self:GetFrameHandle(frameName) if handle == nil then return false end local frameType = nil if not pcall(function() frameType = handle:GetObjectType() end) then return false end if frameType == nil or frameType == "Font" then return false end return true end function MoveIt:GetFrameSettings(frameName, moduleName) if self.originalSettings[frameName] == nil then self.originalSettings[frameName] = {} end if self.db.profile.frames[frameName] == nil then self.db.profile[frameName] = {} end if moduleName ~= nil then if self.originalSettings[frameName][moduleName] == nil then self.originalSettings[frameName][moduleName] = self.Modules[moduleName]:GetOriginalSettings(frameName) end if self.db.profile.frames[frameName][moduleName] == nil then self.db.profile.frames[frameName][moduleName] = {} MoveIt:CopyOriginalSettings(frameName, moduleName) elseif self.db.profile.frames[frameName][moduleName].Enabled == false then MoveIt:CopyOriginalSettings(frameName, moduleName) end return self.db.profile.frames[frameName][moduleName] end return self.db.profile.frames[frameName] end function MoveIt:CopyOriginalSettings(frameName, moduleName) MoveIt.Utils:SimpleTableCopy(self.originalSettings[frameName][moduleName], self.db.profile.frames[frameName][moduleName]) if moduleName ~= "Flags" then self.db.profile.frames[frameName][moduleName].Enabled = false end end function MoveIt:SetFrameSettings(frameName, moduleName, settingsTable) self.db.profile.frames[frameName][moduleName] = settingsTable end function MoveIt:FrameHasSettings(frameName) return MoveIt.db.profile.frames[frameName] ~= nil end function MoveIt:IsModuleEnabled(frameName, moduleName) if self.db.profile.frames[frameName][moduleName] == nil then return false end return self.db.profile.frames[frameName][moduleName].Enabled end function MoveIt:IsFrameClampable(frameName) local handle = self:GetFrameHandle(frameName) if pcall (function() _ = handle:IsClampedToScreen() end) then return true end return false end function MoveIt:ApplyFrameSettings(frameName) if frameName == nil then MoveIt.Utils:Error("ApplyFrameSettings: frameName was nil") return end if not self:FrameHasSettings(frameName) then return end local handle = self:GetFrameHandle(frameName) if handle ~= nil then if InCombatLockdown() and handle:IsProtected() then return end self.Modules.Flags:Apply(frameName) if self:IsModuleEnabled(frameName, "Reposition") then self.Modules.Reposition:Apply(frameName) end if self:IsModuleEnabled(frameName, "Scale") then self.Modules.Scale:Apply(frameName) end if self:IsModuleEnabled(frameName, "Resize") then self.Modules.Resize:Apply(frameName) end if self:IsModuleEnabled(frameName, "Parent") then self.Modules.Parent:Apply(frameName) end if self:IsModuleEnabled(frameName, "Alpha") then self.Modules.Alpha:Apply(frameName) end if self:IsModuleEnabled(frameName, "Strata") then self.Modules.Strata:Apply(frameName) end end end function MoveIt:ApplyAll() if self.db.profile.frames ~= nil then for k, v in pairs(self.db.profile.frames) do self:ApplyFrameSettings(k) end end end function MoveIt:PrintHooks() print(self.Utils.ColouredText("MoveIt hooked frames:", "ffff00")) for k, v in pairs(self.frameHooks) do local status = self.Utils.ColouredText("Disabled", "ff0000") if self.enabledHooks[k] then status = self.Utils.ColouredText("Enabled", "00ff00") end print(k .. " " .. status) end print("Total Hooks: " .. self.hookCount) end function MoveIt:FrameHasStrata(frameName) local handle = self:GetFrameHandle(frameName) return pcall(function() _ = handle:GetFrameStrata() end) end function MoveIt:FrameExists(frameName) return self:GetFrameHandle(frameName) ~= nil end function MoveIt:GetFrameType(frameName) local handle = MoveIt:GetFrameHandle(frameName) if handle == nil then return nil end local objectType = nil pcall(function() objectType = handle:GetObjectType() end) return objectType end function MoveIt:UpdateHooks() if self.db.profile.frames == nil then return end self.enabledHooks = {} for k, _ in pairs(self.db.profile.frames) do local frameType = MoveIt:GetFrameType(k) self:TryAddHook(k, "OnShow") if self.frameEvents[frameType] ~= nil then if self.frameEvents[frameType]["Normal"] ~= nil then for _, v in ipairs(self.frameEvents[frameType]["Normal"]) do self:TryAddHook(k, v) end end end if self:GetFrameSettings(k).Flags.Force then self:TryAddHook(k, "OnUpdate") if self.frameEvents[frameType] ~= nil then if self.frameEvents[frameType]["Force"] ~= nil then for _, v in ipairs(self.frameEvents[frameType]["Force"]) do self:TryAddHook(k, v) end end end end end end function MoveIt:FrameHook(frameName, hookName) if MoveIt.enabledHooks[hookName] and MoveIt:FrameHasSettings(frameName) then if self:IsModuleEnabled(frameName, "Delay") and not self.db.profile.frames[frameName].Flags.Force then C_Timer.After(self.db.profile.frames[frameName].Delay.MS / 1000, function() MoveIt:ApplyFrameSettings(frameName) end) else MoveIt:ApplyFrameSettings(frameName) end end end function MoveIt:TryAddHook(frameName, event) local hookName = frameName .. ":" .. event self.enabledHooks[hookName] = true --print("Trying hook " .. hookName) local handle = self:GetFrameHandle(frameName) if handle ~= nil and self.frameHooks[hookName] == nil then if pcall(function() handle:HookScript(event, function() MoveIt:FrameHook(frameName, hookName) end) end) then --print("Added Hook " .. frameName .. ":" .. event) self.frameHooks[hookName] = true self.hookCount = self.hookCount + 1 else MoveIt.Utils:Error("Could not add hook: " .. hookName) end end end