--[[ ############################################################################## _____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_ # ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__ # __\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____ # ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____ # ______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____ # _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____ # __/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ # _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_# ___\///////////___________\///___________\/////////_____\///////////_# ############################################################################## S U P E R - V I L L A I N - U I By: Munglunch # ############################################################################## ########################################################## LOCALIZED LUA FUNCTIONS ########################################################## ]]-- --[[ GLOBALS ]]-- local _G = _G; local unpack = _G.unpack; local select = _G.select; local pairs = _G.pairs; local ipairs = _G.ipairs; local type = _G.type; local error = _G.error; local pcall = _G.pcall; local tostring = _G.tostring; local tonumber = _G.tonumber; local string = _G.string; local math = _G.math; --[[ STRING METHODS ]]-- local format, split = string.format, string.split; --[[ MATH METHODS ]]-- local min, floor = math.min, math.floor; local parsefloat = math.parsefloat; --[[ ########################################################## GET ADDON DATA ########################################################## ]]-- local SV = select(2, ...) local L = SV.L; local Mentalo = SV:NewClass("Mentalo", L["Mentalo the Frame Mover"]); Mentalo.Frames = {} --[[ /$$$$$$ /$$ /$$ /$$ /$$__ $$ | $$ |__/ | $$ | $$ \__//$$$$$$ /$$ /$$$$$$$| $$ /$$ /$$ /$$ | $$$$$$|_ $$_/ | $$ /$$_____/| $$ /$$/| $$ | $$ \____ $$ | $$ | $$| $$ | $$$$$$/ | $$ | $$ /$$ \ $$ | $$ /$$| $$| $$ | $$_ $$ | $$ | $$ | $$$$$$/ | $$$$/| $$| $$$$$$$| $$ \ $$| $$$$$$$ \______/ \___/ |__/ \_______/|__/ \__/ \____ $$ /$$ | $$ | $$$$$$/ \______/ --]] local Sticky = {}; Sticky.Frames = {}; Sticky.Frames[1] = SV.Screen; Sticky.scripts = Sticky.scripts or {} Sticky.rangeX = 15 Sticky.rangeY = 15 Sticky.StuckTo = Sticky.StuckTo or {} local function SnapStickyFrame(frameA, frameB, left, top, right, bottom) local sA, sB = frameA:GetEffectiveScale(), frameB:GetEffectiveScale() local xA, yA = frameA:GetCenter() local xB, yB = frameB:GetCenter() local hA, hB = frameA:GetHeight() / 2, ((frameB:GetHeight() * sB) / sA) / 2 local wA, wB = frameA:GetWidth() / 2, ((frameB:GetWidth() * sB) / sA) / 2 local newX, newY = xA, yA if not left then left = 0 end if not top then top = 0 end if not right then right = 0 end if not bottom then bottom = 0 end if not xB or not yB or not sB or not sA or not sB then return end xB, yB = (xB * sB) / sA, (yB * sB) / sA local stickyAx, stickyAy = wA * 0.75, hA * 0.75 local stickyBx, stickyBy = wB * 0.75, hB * 0.75 local lA, tA, rA, bA = frameA:GetLeft(), frameA:GetTop(), frameA:GetRight(), frameA:GetBottom() local lB, tB, rB, bB = frameB:GetLeft(), frameB:GetTop(), frameB:GetRight(), frameB:GetBottom() local snap = nil lB, tB, rB, bB = (lB * sB) / sA, (tB * sB) / sA, (rB * sB) / sA, (bB * sB) / sA if (bA <= tB and bB <= tA) then if xA <= (xB + Sticky.rangeX) and xA >= (xB - Sticky.rangeX) then newX = xB snap = true end if lA <= (lB + Sticky.rangeX) and lA >= (lB - Sticky.rangeX) then newX = lB + wA if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then newX = newX + 4 end snap = true end if rA <= (rB + Sticky.rangeX) and rA >= (rB - Sticky.rangeX) then newX = rB - wA if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then newX = newX - 4 end snap = true end if lA <= (rB + Sticky.rangeX) and lA >= (rB - Sticky.rangeX) then newX = rB + (wA - left) snap = true end if rA <= (lB + Sticky.rangeX) and rA >= (lB - Sticky.rangeX) then newX = lB - (wA - right) snap = true end end if (lA <= rB and lB <= rA) then if yA <= (yB + Sticky.rangeY) and yA >= (yB - Sticky.rangeY) then newY = yB snap = true end if tA <= (tB + Sticky.rangeY) and tA >= (tB - Sticky.rangeY) then newY = tB - hA if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then newY = newY - 4 end snap = true end if bA <= (bB + Sticky.rangeY) and bA >= (bB - Sticky.rangeY) then newY = bB + hA if frameB == UIParent or frameB == WorldFrame or frameB == SVUIParent then newY = newY + 4 end snap = true end if tA <= (bB + Sticky.rangeY + bottom) and tA >= (bB - Sticky.rangeY + bottom) then newY = bB - (hA - top) snap = true end if bA <= (tB + Sticky.rangeY - top) and bA >= (tB - Sticky.rangeY - top) then newY = tB + (hA - bottom) snap = true end end if snap then frameA:ClearAllPoints() frameA:SetPoint("CENTER", UIParent, "BOTTOMLEFT", newX, newY) return true end end local function GetStickyUpdate(frame, xoffset, yoffset, left, top, right, bottom) return function() local x, y = GetCursorPosition() local s = frame:GetEffectiveScale() x, y = x / s, y / s frame:ClearAllPoints() frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x + xoffset, y + yoffset) Sticky.StuckTo[frame] = nil for i = 1, #Sticky.Frames do local v = Sticky.Frames[i] if(frame ~= v and frame ~= v:GetParent() and IsShiftKeyDown() and v:IsVisible()) then if SnapStickyFrame(frame, v, left, top, right, bottom) then Sticky.StuckTo[frame] = v break end end end end end local function StickyStartMoving(frame, left, top, right, bottom) local x, y = GetCursorPosition() local aX, aY = frame:GetCenter() local aS = frame:GetEffectiveScale() aX, aY = aX * aS, aY * aS local xoffset, yoffset = (aX - x), (aY - y) Sticky.scripts[frame] = frame:GetScript("OnUpdate") frame:SetScript("OnUpdate", GetStickyUpdate(frame, xoffset, yoffset, left, top, right, bottom)) end local function StickyStopMoving(frame) frame:SetScript("OnUpdate", Sticky.scripts[frame]) Sticky.scripts[frame] = nil if Sticky.StuckTo[frame] then local frame2 = Sticky.StuckTo[frame] Sticky.StuckTo[frame] = nil return true, frame2 else return false, nil end end --[[ /$$ /$$ /$$ /$$ | $$$ /$$$ | $$ | $$ | $$$$ /$$$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ | $$ /$$$$$$ | $$ $$/$$ $$ /$$__ $$| $$__ $$|_ $$_/ |____ $$| $$ /$$__ $$ | $$ $$$| $$| $$$$$$$$| $$ \ $$ | $$ /$$$$$$$| $$| $$ \ $$ | $$\ $ | $$| $$_____/| $$ | $$ | $$ /$$ /$$__ $$| $$| $$ | $$ | $$ \/ | $$| $$$$$$$| $$ | $$ | $$$$/| $$$$$$$| $$| $$$$$$/ |__/ |__/ \_______/|__/ |__/ \___/ \_______/|__/ \______/ --]] local CurrentFrameTarget, UpdateFrameTarget; --[[ ########################################################## LOCAL FUNCTIONS ########################################################## ]]-- local function Pinpoint(parent) local centerX, centerY = parent:GetCenter() local screenWidth = GetScreenWidth() local screenHeight = GetScreenHeight() local result; if not centerX or not centerY then return "CENTER" end local heightTop = screenHeight * 0.75; local heightBottom = screenHeight * 0.25; local widthLeft = screenWidth * 0.25; local widthRight = screenWidth * 0.75; if(((centerX > widthLeft) and (centerX < widthRight)) and (centerY > heightTop)) then result = "TOP" elseif((centerX < widthLeft) and (centerY > heightTop)) then result = "TOPLEFT" elseif((centerX > widthRight) and (centerY > heightTop)) then result = "TOPRIGHT" elseif(((centerX > widthLeft) and (centerX < widthRight)) and centerY < heightBottom) then result = "BOTTOM" elseif((centerX < widthLeft) and (centerY < heightBottom)) then result = "BOTTOMLEFT" elseif((centerX > widthRight) and (centerY < heightBottom)) then result = "BOTTOMRIGHT" elseif((centerX < widthLeft) and (centerY > heightBottom) and (centerY < heightTop)) then result = "LEFT" elseif((centerX > widthRight) and (centerY < heightTop) and (centerY > heightBottom)) then result = "RIGHT" else result = "CENTER" end return result end local function CurrentPosition(frame) if not frame then return end local parentName local anchor1, parent, anchor2, x, y = frame:GetPoint() if((not anchor1) or (not anchor2) or (not x) or (not y)) then anchor1, anchor2, x, y = "TOPLEFT", "TOPLEFT", 160, -80 end if(not parent or (parent and (not parent:GetName()))) then parentName = "UIParent" else parentName = parent:GetName() end return ("%s\031%s\031%s\031%d\031%d"):format(anchor1, parentName, anchor2, parsefloat(x), parsefloat(y)) end local function GrabUsableRegions(frame) local parent = frame or SV.Screen local right = parent:GetRight() local top = parent:GetTop() local center = parent:GetCenter() return right, top, center end local function CalculateOffsets(frame) if(not CurrentFrameTarget) then return end local right, top, center = GrabUsableRegions() local xOffset, yOffset = CurrentFrameTarget:GetCenter() local screenLeft = (right * 0.33); local screenRight = (right * 0.66); local topMedian = (top * 0.5); local anchor, a1, a2; if(yOffset >= (top * 0.5)) then a1 = "TOP" yOffset = -(top - CurrentFrameTarget:GetTop()) else a1 = "BOTTOM" yOffset = CurrentFrameTarget:GetBottom() end if xOffset >= screenRight then a2 = "RIGHT" xOffset = (CurrentFrameTarget:GetRight() - right) elseif xOffset <= screenLeft then a2 = "LEFT" xOffset = CurrentFrameTarget:GetLeft() else a2 = "" xOffset = (xOffset - center) end xOffset = parsefloat(xOffset, 0) yOffset = parsefloat(yOffset, 0) anchor = ("%s%s"):format(a1,a2) return xOffset, yOffset, anchor end local function ResetAllAlphas() for entry,_ in pairs(Mentalo.Frames) do local frame = _G[entry] if(frame) then frame:SetAlpha(0.4) end end end --[[ /$$$$$$$$/$$ /$$ /$$$$$$$$ /$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ |__ $$__/ $$ | $$| $$_____/ | $$ | $$ /$$__ $$| $$$ | $$| $$__ $$ | $$ | $$ | $$| $$ | $$ | $$| $$ \ $$| $$$$| $$| $$ \ $$ | $$ | $$$$$$$$| $$$$$ | $$$$$$$$| $$$$$$$$| $$ $$ $$| $$ | $$ | $$ | $$__ $$| $$__/ | $$__ $$| $$__ $$| $$ $$$$| $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$| $$\ $$$| $$ | $$ | $$ | $$ | $$| $$$$$$$$ | $$ | $$| $$ | $$| $$ \ $$| $$$$$$$/ |__/ |__/ |__/|________/ |__/ |__/|__/ |__/|__/ \__/|_______/ --]] local TheHand = CreateFrame("Frame", "SVUI_HandOfMentalo", UIParent) TheHand:SetFrameStrata("DIALOG") TheHand:SetFrameLevel(99) TheHand:SetClampedToScreen(true) TheHand:SetSize(128,128) TheHand:SetPoint("CENTER") TheHand.bg = TheHand:CreateTexture(nil, "OVERLAY") TheHand.bg:SetAllPoints(TheHand) TheHand.bg:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-HAND-OFF]]) TheHand.energy = TheHand:CreateTexture(nil, "OVERLAY") TheHand.energy:SetAllPoints(TheHand) TheHand.energy:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-ENERGY]]) SV.Animate:Orbit(TheHand.energy, 10) TheHand.flash = TheHand.energy.anim; TheHand.energy:Hide() TheHand.elapsedTime = 0; TheHand.flash:Stop() TheHand:Hide() TheHand.UserHeld = false; local TheHand_OnUpdate = function(self, elapsed) self.elapsedTime = self.elapsedTime + elapsed if self.elapsedTime > 0.1 then self.elapsedTime = 0 local x, y = GetCursorPosition() local scale = SV.Screen:GetEffectiveScale() self:SetPoint("CENTER", SV.Screen, "BOTTOMLEFT", (x / scale) + 50, (y / scale) + 50) end end function TheHand:Enable() self:Show() self.bg:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-HAND-ON]]) self.energy:Show() self.flash:Play() self:SetScript("OnUpdate", TheHand_OnUpdate) end function TheHand:Disable() self.flash:Stop() self.energy:Hide() self.bg:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-HAND-OFF]]) self:SetScript("OnUpdate", nil) self.elapsedTime = 0 self:Hide() end --[[ ########################################################## HANDLERS ########################################################## ]]-- local MentaloUpdateHandler = CreateFrame("Frame", nil) local Movable_OnMouseUp = function(self) CurrentFrameTarget = self; local xOffset, yOffset, anchor = CalculateOffsets() SVUI_MentaloPrecisionSetX.CurrentValue = xOffset; SVUI_MentaloPrecisionSetX:SetText(xOffset) SVUI_MentaloPrecisionSetY.CurrentValue = yOffset; SVUI_MentaloPrecisionSetY:SetText(yOffset) SVUI_MentaloPrecision.Title:SetText(self.textString) end local Movable_OnUpdate = function(self) local frame = UpdateFrameTarget; if not frame then return end local rightPos, topPos, centerPos = GrabUsableRegions() local centerX, centerY = frame:GetCenter() local calc1 = rightPos * 0.33; local calc2 = rightPos * 0.66; local calc3 = topPos * 0.5; local anchor1, anchor2; if centerY >= calc3 then anchor1 = "TOP" anchor2 = "BOTTOM" else anchor1 = "BOTTOM" anchor2 = "TOP" end if centerX >= calc2 then anchor1 = "RIGHT" anchor2 = "LEFT" elseif centerX <= calc1 then anchor1 = "LEFT" anchor2 = "RIGHT" end SVUI_MentaloPrecision:ClearAllPoints() SVUI_MentaloPrecision:SetPoint(anchor1, frame, anchor2, 0, 0) SVUI_MentaloPrecision:SetFrameLevel(frame:GetFrameLevel() + 20) Movable_OnMouseUp(frame) end local Movable_OnSizeChanged = function(self) if InCombatLockdown()then return end if self.dirtyWidth and self.dirtyHeight then self.Grip:SetSizeToScale(self.dirtyWidth, self.dirtyHeight) else self.Grip:SetSizeToScale(self:GetSize()) end end local Movable_OnDragStart = function(self) if InCombatLockdown() then SV:AddonMessage(ERR_NOT_IN_COMBAT)return end if SV.db.general.stickyFrames then StickyStartMoving(self, self.snapOffset, -2) else self:StartMoving() end UpdateFrameTarget = self; MentaloUpdateHandler:Show() MentaloUpdateHandler:SetScript("OnUpdate", Movable_OnUpdate) TheHand:Enable() TheHand.UserHeld = true end local Movable_OnDragStop = function(self) if InCombatLockdown()then SV:AddonMessage(ERR_NOT_IN_COMBAT)return end TheHand.UserHeld = false; if SV.db.general.stickyFrames then StickyStopMoving(self) else self:StopMovingOrSizing() end local pR, pT, pC = GrabUsableRegions() local cX, cY = self:GetCenter() local newAnchor; if cY >= (pT * 0.5) then newAnchor = "TOP"; cY = (-(pT - self:GetTop())) else newAnchor = "BOTTOM" cY = self:GetBottom() end if cX >= (pR * 0.66) then newAnchor = newAnchor.."RIGHT" cX = self:GetRight() - pR elseif cX <= (pR * 0.33) then newAnchor = newAnchor.."LEFT" cX = self:GetLeft() else cX = cX - pC end if self.positionOverride then self.parent:ClearAllPoints() self.parent:SetPointToScale(self.positionOverride, self, self.positionOverride) end self:ClearAllPoints() self:SetPointToScale(newAnchor, SV.Screen, newAnchor, cX, cY) Mentalo:SaveMovable(self.name) if SVUI_MentaloPrecision then Movable_OnMouseUp(self) end UpdateFrameTarget = nil; MentaloUpdateHandler:SetScript("OnUpdate", nil) MentaloUpdateHandler:Hide() if(self.postdrag ~= nil and type(self.postdrag) == "function") then self:postdrag(Pinpoint(self)) end self:SetUserPlaced(false) TheHand:Disable() end local Movable_OnEnter = function(self) if TheHand.UserHeld then return end ResetAllAlphas() self:SetAlpha(1) self.text:SetTextColor(0, 1, 1) self:SetBackdropBorderColor(0, 0.7, 1) UpdateFrameTarget = self; SVUI_Mentalo.Portrait:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-ON]]) TheHand:SetPoint("CENTER", self, "TOP", 0, 0) TheHand:Show() if CurrentFrameTarget ~= self then SVUI_MentaloPrecision:Hide() Movable_OnMouseUp(self) end end local Movable_OnLeave = function(self) if TheHand.UserHeld then return end self.text:SetTextColor(0.5, 0.5, 0.5) self:SetBackdropBorderColor(0.5, 0.5, 0.5) SVUI_Mentalo.Portrait:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Doodads\MENTALO-OFF]]) TheHand:Hide() if(CurrentFrameTarget ~= self and not SVUI_MentaloPrecision:IsShown()) then self:SetAlpha(0.4) end end local Movable_OnMouseDown = function(self, arg) if arg == "RightButton" then TheHand.UserHeld = false; if(CurrentFrameTarget == self and not SVUI_MentaloPrecision:IsShown()) then Movable_OnUpdate() SVUI_MentaloPrecision:Show() else SVUI_MentaloPrecision:Hide() end if SV.db.general.stickyFrames then StickyStopMoving(self) else self:StopMovingOrSizing() end end end local Movable_OnShow = function(self) self:SetBackdropBorderColor(0.5, 0.5, 0.5) end --[[ ########################################################## CONSTRUCTS ########################################################## ]]-- function Mentalo:New(frame, moveName, title, snap, dragStopFunc, callbackOnEnter) if(not frame or (self.Frames[moveName] ~= nil)) then return end self.Frames[moveName] = { text = title, postdrag = dragStopFunc, point = CurrentPosition(frame) } local movable = CreateFrame("Button", moveName, SV.Screen) movable:SetFrameLevel(frame:GetFrameLevel() + 1) movable:SetClampedToScreen(true) movable:SetWidth(frame:GetWidth()) movable:SetHeight(frame:GetHeight()) movable:SetFrameStrata("DIALOG") movable.parent = frame; movable.name = moveName; movable.textString = title; movable.postdrag = dragStopFunc; movable.snapOffset = snap or -2; local anchor1, anchorParent, anchor2, xPos, yPos if(SV.cache.Anchors and SV.cache.Anchors[moveName] and (type(SV.cache.Anchors[moveName]) == "string")) then anchor1, anchorParent, anchor2, xPos, yPos = split("\031", SV.cache.Anchors[moveName]) else anchor1, anchorParent, anchor2, xPos, yPos = split("\031", CurrentPosition(frame)) end movable:SetPoint(anchor1, anchorParent, anchor2, xPos, yPos) movable:SetStylePanel("!_Frame", "Transparent") movable:SetAlpha(0.4) frame:SetScript("OnSizeChanged", Movable_OnSizeChanged) frame.Grip = movable; frame:ClearAllPoints() frame:SetPoint(anchor1, movable, anchor1, 0, 0) local mtext = movable:CreateFontString(nil, "OVERLAY") mtext:SetFontObject(SVUI_Font_Default) mtext:SetJustifyH("CENTER") mtext:SetPoint("CENTER") mtext:SetText(title or moveName) mtext:SetTextColor(0.5, 0.5, 0.5) movable:SetFontString(mtext) movable.text = mtext; movable:RegisterForDrag("LeftButton", "RightButton") movable:SetScript("OnMouseUp", Movable_OnMouseUp) movable:SetScript("OnDragStart", Movable_OnDragStart) movable:SetScript("OnDragStop", Movable_OnDragStop) movable:SetScript("OnEnter", Movable_OnEnter) movable:SetScript("OnMouseDown", Movable_OnMouseDown) movable:SetScript("OnLeave", Movable_OnLeave) movable:SetScript("OnShow", Movable_OnShow) movable:SetMovable(true) movable:Hide() if(dragStopFunc and (type(dragStopFunc) == "function") and callbackOnEnter) then movable:RegisterEvent("PLAYER_ENTERING_WORLD") movable:SetScript("OnEvent", function(this, event) local point = Pinpoint(this) dragStopFunc(this, point) this:UnregisterAllEvents() end) end Sticky.Frames[#Sticky.Frames + 1] = movable; end function Mentalo:HasMoved(frameName) if(SV.cache.Anchors and SV.cache.Anchors[frameName]) then return true else return false end end function Mentalo:SaveMovable(frameName) if((not _G[frameName]) or (not SV.cache.Anchors)) then return end SV.cache.Anchors[frameName] = CurrentPosition(_G[frameName]) end function Mentalo:ChangeSnapOffset(frameName, snapOffset) if(not _G[frameName]) then return end _G[frameName].snapOffset = snapOffset or -2; end function Mentalo:Add(frame, title, snapOffset, dragStopFunc, overrideName, callbackOnEnter) if(not frame or (not overrideName and not frame:GetName())) then return end local frameName = overrideName or frame:GetName() local moveName = ("%s_MOVE"):format(frameName) self:New(frame, moveName, title, snapOffset, dragStopFunc, callbackOnEnter) end function Mentalo:Reset(request, bypass) if(request == "" or request == nil) then for frameName, frameData in pairs(self.Frames) do local frame = _G[frameName]; if(frameData.point) then local u, v, w, x, y = split("\031", frameData.point) frame:ClearAllPoints() frame:SetPoint(u, v, w, x, y) if(not bypass) then if(frameData.postdrag and (type(frameData.postdrag) == "function")) then frameData.postdrag(frame, Pinpoint(frame)) end end end if(SV.cache.Anchors and SV.cache.Anchors[frameName]) then SV.cache.Anchors[frameName] = nil end end else for frameName, frameData in pairs(self.Frames) do if(frameData.point and (request == frameData.text)) then local frame = _G[frameName] local u, v, w, x, y = split("\031", frameData.point) frame:ClearAllPoints() frame:SetPoint(u, v, w, x, y) if(not bypass) then if(frameData.postdrag and (type(frameData.postdrag) == "function")) then frameData.postdrag(frame, Pinpoint(frame)) end end if(SV.cache.Anchors and SV.cache.Anchors[frameName]) then SV.cache.Anchors[frameName] = nil end break end end end end function Mentalo:SetPositions() for frameName, frameData in pairs(self.Frames) do local frame = _G[frameName]; local anchor1, parent, anchor2, x, y; if frame then if (SV.cache.Anchors and SV.cache.Anchors[frameName] and (type(SV.cache.Anchors[frameName]) == "string")) then anchor1, parent, anchor2, x, y = split("\031", SV.cache.Anchors[frameName]) frame:ClearAllPoints() frame:SetPoint(anchor1, parent, anchor2, x, y) elseif(frameData.point) then anchor1, parent, anchor2, x, y = split("\031", frameData.point) frame:ClearAllPoints() frame:SetPoint(anchor1, parent, anchor2, x, y) end end end end function Mentalo:Toggle(isConfigMode) if(InCombatLockdown()) then return end local enabled = false; if(isConfigMode ~= nil and isConfigMode ~= "") then self.ConfigurationMode = isConfigMode end if(not self.ConfigurationMode) then if IsAddOnLoaded(SV.ConfigID)then LibStub("AceConfigDialog-3.0"):Close(SV.NameID) GameTooltip:Hide() self.ConfigurationMode = true else self.ConfigurationMode = false end else self.ConfigurationMode = false end if(SVUI_Mentalo:IsShown()) then SVUI_Mentalo:Hide() else SVUI_Mentalo:Show() enabled = true end for frameName, _ in pairs(self.Frames)do if(_G[frameName]) then local movable = _G[frameName] if(not enabled) then movable:Hide() else movable:Show() end end end end --[[ ########################################################## ALIGNMENT GRAPH ########################################################## ]]-- local Graph = {} function Graph:Toggle(enabled) if((not self.Grid) or (self.CellSize ~= SV.db.general.graphSize)) then self:UpdateDataSlots() end if(not enabled) then self.Grid:Hide() else self.Grid:Show() end end function Graph:UpdateDataSlots() local cellSize = SV.db.general.graphSize self.CellSize = cellSize self.Grid = CreateFrame('Frame', nil, UIParent) self.Grid:SetAllPoints(SV.Screen) local size = 1 local width = GetScreenWidth() local ratio = width / GetScreenHeight() local height = GetScreenHeight() * ratio local wStep = width / cellSize local hStep = height / cellSize for i = 0, cellSize do local tx = self.Grid:CreateTexture(nil, 'BACKGROUND') if(i == cellSize / 2) then tx:SetTexture(0, 1, 0, 0.8) else tx:SetTexture(0, 0, 0, 0.8) end tx:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", i*wStep - (size/2), 0) tx:SetPoint('BOTTOMRIGHT', self.Grid, 'BOTTOMLEFT', i*wStep + (size/2), 0) end height = GetScreenHeight() do local tx = self.Grid:CreateTexture(nil, 'BACKGROUND') tx:SetTexture(0, 1, 0, 0.8) tx:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", 0, -(height/2) + (size/2)) tx:SetPoint('BOTTOMRIGHT', self.Grid, 'TOPRIGHT', 0, -(height/2 + size/2)) end for i = 1, floor((height/2)/hStep) do local tx = self.Grid:CreateTexture(nil, 'BACKGROUND') tx:SetTexture(0, 0, 0, 0.8) tx:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", 0, -(height/2+i*hStep) + (size/2)) tx:SetPoint('BOTTOMRIGHT', self.Grid, 'TOPRIGHT', 0, -(height/2+i*hStep + size/2)) tx = self.Grid:CreateTexture(nil, 'BACKGROUND') tx:SetTexture(0, 0, 0, 0.8) tx:SetPoint("TOPLEFT", self.Grid, "TOPLEFT", 0, -(height/2-i*hStep) + (size/2)) tx:SetPoint('BOTTOMRIGHT', self.Grid, 'TOPRIGHT', 0, -(height/2-i*hStep + size/2)) end self.Grid:Hide() end function Graph:Initialize() self:UpdateDataSlots() end --[[ ########################################################## SCRIPT AND EVENT HANDLERS ########################################################## ]]-- local XML_Mentalo_OnEvent = function(self) if self:IsShown() then self:Hide() Mentalo:Toggle(true) end end local XML_MentaloGridButton_OnClick = function(self) local enabled = true if(Graph.Grid and Graph.Grid:IsShown()) then enabled = false end Graph:Toggle(enabled) end local XML_MentaloLockButton_OnClick = function(self) Graph:Toggle() Mentalo:Toggle(true) if IsAddOnLoaded(SV.ConfigID)then LibStub("AceConfigDialog-3.0"):Open(SV.NameID) end end local SVUI_MentaloPrecisionResetButton_OnClick = function(self) if(not CurrentFrameTarget) then return end local name = CurrentFrameTarget.name Mentalo:Reset(name) end local XML_MentaloPrecisionInputX_EnterPressed = function(self) local current = tonumber(self:GetText()) if(current) then if(CurrentFrameTarget) then local xOffset, yOffset, anchor = CalculateOffsets() yOffset = tonumber(SVUI_MentaloPrecisionSetY.CurrentValue) CurrentFrameTarget:ClearAllPoints() CurrentFrameTarget:SetPointToScale(anchor, SVUIParent, anchor, current, yOffset) Mentalo:SaveMovable(CurrentFrameTarget.name) end self.CurrentValue = current end self:SetText(floor((self.CurrentValue or 0) + 0.5)) EditBox_ClearFocus(self) end local XML_MentaloPrecisionInputY_EnterPressed = function(self) local current = tonumber(self:GetText()) if(current) then if(CurrentFrameTarget) then local xOffset, yOffset, anchor = CalculateOffsets() xOffset = tonumber(SVUI_MentaloPrecisionSetX.CurrentValue) CurrentFrameTarget:ClearAllPoints() CurrentFrameTarget:SetPointToScale(anchor, SVUIParent, anchor, xOffset, current) Mentalo:SaveMovable(CurrentFrameTarget.name) end self.CurrentValue = current end self:SetText(floor((self.CurrentValue or 0) + 0.5)) EditBox_ClearFocus(self) end --[[ ########################################################## Initialize ########################################################## ]]-- function Mentalo:Initialize() SV.cache.Anchors = SV.cache.Anchors or {} SVUI_Mentalo:SetStylePanel("!_Frame", "Heavy") SVUI_Mentalo:SetPanelColor("yellow") SVUI_Mentalo:RegisterForDrag("LeftButton") SVUI_Mentalo:RegisterEvent("PLAYER_REGEN_DISABLED") SVUI_Mentalo:SetScript("OnEvent", XML_Mentalo_OnEvent) SVUI_MentaloGridButton:SetScript("OnClick", XML_MentaloGridButton_OnClick) SVUI_MentaloLockButton:SetScript("OnClick", XML_MentaloLockButton_OnClick) SVUI_MentaloPrecision:SetStylePanel("Frame", "Transparent") SVUI_MentaloPrecision:EnableMouse(true) SVUI_MentaloPrecisionSetX:SetStylePanel("Editbox") SVUI_MentaloPrecisionSetX.CurrentValue = 0; SVUI_MentaloPrecisionSetX:SetScript("OnEnterPressed", XML_MentaloPrecisionInputX_EnterPressed) SVUI_MentaloPrecisionSetY:SetStylePanel("Editbox") SVUI_MentaloPrecisionSetY.CurrentValue = 0; SVUI_MentaloPrecisionSetY:SetScript("OnEnterPressed", XML_MentaloPrecisionInputY_EnterPressed) SVUI_MentaloPrecisionUpButton:SetStylePanel("Button") SVUI_MentaloPrecisionDownButton:SetStylePanel("Button") SVUI_MentaloPrecisionLeftButton:SetStylePanel("Button") SVUI_MentaloPrecisionRightButton:SetStylePanel("Button") self:SetPositions() -- PET JOURNAL TAINT FIX (STILL NEEDED?) -- local info = UIPanelWindows["PetJournalParent"]; -- for name, value in pairs(info) do -- PetJournalParent:SetAttribute("UIPanelLayout-"..name, value); -- end -- PetJournalParent:SetAttribute("UIPanelLayout-defined", true); end