vanilla-wow-addons – Rev 1
?pathlinks?
--[[
Name: Jostle-2.0
Revision: $Rev: 7569 $
Author(s): ckknight (ckknight@gmail.com)
Website: http://ckknight.wowinterface.com/
Documentation: http://wiki.wowace.com/index.php/Jostle-2.0
SVN: http://svn.wowace.com/root/trunk/JostleLib/Jostle-2.0
Description: A library to handle rearrangement of blizzard's frames when bars are added to the sides of the screen.
Dependencies: AceLibrary
]]
local MAJOR_VERSION = "Jostle-2.0"
local MINOR_VERSION = "$Revision: 7569 $"
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
local Jostle = {}
local events = {}
local blizzardFramesData = {}
function events:PLAYER_AURAS_CHANGED()
self:Refresh()
end
function events:PLAYER_ENTERING_WORLD()
self.pew = true
for k,v in pairs(blizzardFramesData) do
blizzardFramesData[k] = nil
end
self:Refresh()
self.frame:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
function Jostle:ToggleWorldMap()
if self.hooks.orig.ToggleWorldMap then
self.hooks.orig.ToggleWorldMap()
end
self:Refresh()
end
function Jostle:TicketStatusFrame_OnEvent()
if self.hooks.orig.TicketStatusFrame_OnEvent then
self.hooks.orig.TicketStatusFrame_OnEvent()
end
self:Refresh(TicketStatusFrame, TemporaryEnchantFrame)
end
function Jostle:FCF_UpdateDockPosition()
if self.hooks.orig.FCF_UpdateDockPosition then
self.hooks.orig.FCF_UpdateDockPosition()
end
self:Refresh(DEFAULT_CHAT_FRAME)
end
function Jostle:FCF_UpdateCombatLogPosition()
if self.hooks.orig.FCF_UpdateCombatLogPosition then
self.hooks.orig.FCF_UpdateCombatLogPosition()
end
self:Refresh(ChatFrame2)
end
function Jostle:UIParent_ManageFramePositions()
if self.hooks.orig.UIParent_ManageFramePositions then
self.hooks.orig.UIParent_ManageFramePositions()
end
self:Refresh(GroupLootFrame1, TutorialFrameParent, FramerateLabel, QuestTimerFrame, DurabilityFrame)
end
function Jostle:ToggleWorldMap()
if self.hooks.orig.ToggleWorldMap then
self.hooks.orig.ToggleWorldMap()
end
self:Refresh()
end
function Jostle:UIParent_ManageRightSideFrames()
for _,frame in self.blizzardFrames do
frame = getglobal(frame)
local frameData = blizzardFramesData[frame]
if frameData and not (frameData.lastX and frameData.lastY and (frameData.lastX ~= frame:GetLeft() or frameData.lastY ~= frame:GetTop())) then
frameData.lastX = nil
frameData.lastY = nil
end
end
if self.hooks.orig.UIParent_ManageRightSideFrames then
self.hooks.orig.UIParent_ManageRightSideFrames()
end
self:Refresh()
end
function Jostle:GetScreenTop()
local bottom = GetScreenHeight()
for _,frame in ipairs(self.topFrames) do
if frame.IsVisible and frame:IsVisible() and frame.GetBottom and frame:GetBottom() and frame:GetBottom() < bottom then
bottom = frame:GetBottom()
end
end
return bottom
end
function Jostle:GetScreenBottom()
local top = 0
for _,frame in ipairs(self.bottomFrames) do
if frame.IsVisible and frame:IsVisible() and frame.GetTop and frame:GetTop() and frame:GetTop() > top then
top = frame:GetTop()
end
end
return top
end
function Jostle:RegisterTop(frame)
for k,f in ipairs(self.bottomFrames) do
if f == frame then
table.remove(self.bottomFrames, k)
break
end
end
for _,f in ipairs(self.topFrames) do
if f == frame then
return
end
end
table.insert(self.topFrames, frame)
self:Refresh()
return true
end
function Jostle:RegisterBottom(frame)
for k,f in ipairs(self.topFrames) do
if f == frame then
table.remove(self.topFrames, k)
break
end
end
for _,f in ipairs(self.bottomFrames) do
if f == frame then
return
end
end
table.insert(self.bottomFrames, frame)
self:Refresh()
return true
end
function Jostle:Unregister(frame)
for k,f in ipairs(self.topFrames) do
if f == frame then
table.remove(self.topFrames, k)
self:Refresh()
return true
end
end
for k,f in ipairs(self.bottomFrames) do
if f == frame then
table.remove(self.bottomFrames, k)
self:Refresh()
return true
end
end
end
function Jostle:IsTopAdjusting()
return self.topAdjust
end
function Jostle:EnableTopAdjusting()
if not self.topAdjust then
self.topAdjust = not self.topAdjust
self:Refresh()
end
end
function Jostle:DisableTopAdjusting()
if self.topAdjust then
self.topAdjust = not self.topAdjust
self:Refresh()
end
end
function Jostle:IsBottomAdjusting()
return self.bottomAdjust
end
function Jostle:EnableBottomAdjusting()
if not self.bottomAdjust then
self.bottomAdjust = not self.bottomAdjust
self:Refresh()
end
end
function Jostle:DisableBottomAdjusting()
if self.bottomAdjust then
self.bottomAdjust = not self.bottomAdjust
self:Refresh()
end
end
local function getsecond(_, value)
return value
end
local tmp = {}
function Jostle:Refresh(f1, f2, f3, f4, f5, f6, f7, f8)
if not self.pew then
return
end
local frames
if f1 then
for k in pairs(tmp) do
tmp[k] = nil
end
tmp.n = 0
table.insert(tmp, f1)
table.insert(tmp, f2)
table.insert(tmp, f3)
table.insert(tmp, f4)
table.insert(tmp, f5)
table.insert(tmp, f6)
table.insert(tmp, f7)
table.insert(tmp, f8)
frames = tmp
else
frames = self.blizzardFrames
end
local screenHeight = GetScreenHeight()
for _,frame in ipairs(frames) do
if type(frame) == "string" then
frame = getglobal(frame)
end
if frame and not blizzardFramesData[frame] and frame.GetTop and frame:GetCenter() and getsecond(frame:GetCenter()) then
if getsecond(frame:GetCenter()) <= screenHeight / 2 or frame == MultiBarRight then
blizzardFramesData[frame] = {y = frame:GetBottom(), top = false}
else
blizzardFramesData[frame] = {y = frame:GetTop() - screenHeight, top = true}
end
end
end
local topOffset = self:IsTopAdjusting() and self:GetScreenTop() or GetScreenHeight()
local bottomOffset = self:IsBottomAdjusting() and self:GetScreenBottom() or 0
for _,frame in ipairs(frames) do
if type(frame) == "string" then
frame = getglobal(frame)
end
if ((frame and frame.IsUserPlaced and not frame:IsUserPlaced()) or ((frame == DEFAULT_CHAT_FRAME or frame == ChatFrame2) and SIMPLE_CHAT == "1") or frame == FramerateLabel) and (frame ~= ChatFrame2 or SIMPLE_CHAT == "1") then
local frameData = blizzardFramesData[frame]
if (getsecond(frame:GetPoint(1)) ~= UIParent and getsecond(frame:GetPoint(1)) ~= WorldFrame) then
-- do nothing
elseif frame == PlayerFrame and (CT_PlayerFrame_Drag or Gypsy_PlayerFrameCapsule) then
-- do nothing
elseif frame == TargetFrame and (CT_TargetFrame_Drag or Gypsy_TargetFrameCapsule) then
-- do nothing
elseif frame == PartyMemberFrame1 and (CT_MovableParty1_Drag or Gypsy_PartyFrameCapsule) then
-- do nothing
elseif frame == MainMenuBar and Gypsy_HotBarCapsule then
-- do nothing
elseif frame == DurabilityFrame and DurabilityFrame:IsShown() and (DurabilityFrame:GetLeft() > GetScreenWidth() or DurabilityFrame:GetRight() < 0 or DurabilityFrame:GetBottom() > GetScreenHeight() or DurabilityFrame:GetTop() < 0) then
DurabilityFrame:Hide()
elseif frame == FramerateLabel and ((frameData.lastX and frameData.lastX ~= frame:GetLeft()) or WorldFrame:GetHeight() ~= UIParent:GetHeight()) then
-- do nothing
elseif frame == TemporaryEnchantFrame or frame == CastingBarFrame or frame == TutorialFrameParent or frame == FramerateLabel or frame == QuestTimerFrame or frame == DurabilityFrame or frame == QuestWatchFrame or not (frameData.lastX and frameData.lastY and (frameData.lastX ~= frame:GetLeft() or frameData.lastY ~= frame:GetTop())) then
local anchor
local anchorAlt
local width, height = GetScreenWidth(), GetScreenHeight()
local x
if frame:GetRight() and frame:GetLeft() then
local anchorFrame = UIParent
if frame == MainMenuBar or frame == GroupLootFrame1 then
x = 0
anchor = ""
elseif frame:GetRight() <= width / 2 then
x = frame:GetLeft()
anchor = "LEFT"
else
x = frame:GetRight() - width
anchor = "RIGHT"
end
local y = blizzardFramesData[frame].y
local offset = 0
if blizzardFramesData[frame].top then
anchor = "TOP" .. anchor
offset = topOffset - screenHeight
else
anchor = "BOTTOM" .. anchor
offset = bottomOffset
end
if frame == MinimapCluster and not MinimapBorderTop:IsShown() then
offset = offset + MinimapBorderTop:GetHeight() * 3/5
elseif frame == TemporaryEnchantFrame and TicketStatusFrame:IsVisible() then
offset = offset - TicketStatusFrame:GetHeight()
elseif frame == DEFAULT_CHAT_FRAME then
y = MainMenuBar:GetHeight() + 32
if PetActionBarFrame:IsVisible() or ShapeshiftBarFrame:IsVisible() then
offset = offset + ShapeshiftBarFrame:GetHeight()
end
if MultiBarBottomLeft:IsVisible() then
offset = offset + MultiBarBottomLeft:GetHeight() - 21
end
elseif frame == ChatFrame2 then
y = MainMenuBar:GetHeight() + 32
if MultiBarBottomRight:IsVisible() then
offset = offset + MultiBarBottomRight:GetHeight() - 21
end
elseif frame == CastingBarFrame then
y = MainMenuBar:GetHeight() + 17
if PetActionBarFrame:IsVisible() or ShapeshiftBarFrame:IsVisible() then
offset = offset + ShapeshiftBarFrame:GetHeight()
end
if MultiBarBottomLeft:IsVisible() or MultiBarBottomRight:IsVisible() then
offset = offset + MultiBarBottomLeft:GetHeight()
end
elseif frame == GroupLootFrame1 or frame == TutorialFrameParent or frame == FramerateLabel then
if MultiBarBottomLeft:IsVisible() or MultiBarBottomRight:IsVisible() then
offset = offset + MultiBarBottomLeft:GetHeight()
end
elseif frame == QuestTimerFrame or frame == DurabilityFrame or frame == QuestWatchFrame then
anchorFrame = MinimapCluster
x = 0
y = 0
offset = 0
if frame ~= QuestTimerFrame and QuestTimerFrame:IsVisible() then
y = y - QuestTimerFrame:GetHeight()
end
if frame == QuestWatchFrame and DurabilityFrame:IsVisible() then
y = y - DurabilityFrame:GetHeight()
end
if frame == DurabilityFrame then
x = -20
end
anchor = "TOPRIGHT"
anchorAlt = "BOTTOMRIGHT"
if MultiBarRight:IsVisible() then
x = x - MultiBarRight:GetWidth()
if MultiBarLeft:IsVisible() then
x = x - MultiBarLeft:GetWidth()
end
end
end
if frame == FramerateLabel then
anchorFrame = WorldFrame
end
frame:ClearAllPoints()
frame:SetPoint(anchor, anchorFrame, anchorAlt or anchor, x, y + offset)
blizzardFramesData[frame].lastX = frame:GetLeft()
blizzardFramesData[frame].lastY = frame:GetTop()
end
end
end
end
end
local function activate(self, oldLib, oldDeactivate)
if oldLib then
self.frame = oldLib.frame
self.frame:UnregisterAllEvents()
self.hooks = oldLib.hooks
self.topFrames = oldLib.topFrames
self.bottomFrames = oldLib.bottomFrames
self.blizzardFrames = oldLib.blizzardFrames
self.topAdjust = oldLib.topAdjust
self.bottomAdjust = oldLib.bottomAdjust
for name, method in pairs(self.hooks) do
if type(method) == "function" then
self.hooks[name] = nil
end
end
for k in pairs(self.blizzardFrames) do
self.blizzardFrames[k] = nil
end
else
self.frame = CreateFrame("Frame")
self.hooks = {
orig = {}
}
self.blizzardFrames = {}
self.topFrames = {}
self.bottomFrames = {}
self.topAdjust = true
self.bottomAdjust = true
end
if not self.hooks.orig.ToggleWorldMap then
self.hooks.orig.ToggleWorldMap = ToggleWorldMap
self.hooks.ToggleWorldMap = self.ToggleWorldMap
self.ToggleWorldMap = nil
function ToggleWorldMap()
if self.hooks.ToggleWorldMap then
self.hooks.ToggleWorldMap(self)
else
self.hooks.orig.ToggleWorldMap()
end
end
end
if not self.hooks.orig.TicketStatusFrame_OnEvent then
self.hooks.orig.TicketStatusFrame_OnEvent = TicketStatusFrame_OnEvent
self.hooks.TicketStatusFrame_OnEvent = self.TicketStatusFrame_OnEvent
self.TicketStatusFrame_OnEvent = nil
function TicketStatusFrame_OnEvent()
if self.hooks.TicketStatusFrame_OnEvent then
self.hooks.TicketStatusFrame_OnEvent(self)
else
self.hooks.orig.TicketStatusFrame_OnEvent()
end
end
end
if not self.hooks.orig.FCF_UpdateDockPosition then
self.hooks.orig.FCF_UpdateDockPosition = FCF_UpdateDockPosition
self.hooks.FCF_UpdateDockPosition = self.FCF_UpdateDockPosition
self.FCF_UpdateDockPosition = nil
function FCF_UpdateDockPosition()
if self.hooks.FCF_UpdateDockPosition then
self.hooks.FCF_UpdateDockPosition(self)
else
self.hooks.orig.FCF_UpdateDockPosition()
end
end
end
if not self.hooks.orig.FCF_UpdateCombatLogPosition then
self.hooks.orig.FCF_UpdateCombatLogPosition = FCF_UpdateCombatLogPosition
self.hooks.FCF_UpdateCombatLogPosition = self.FCF_UpdateCombatLogPosition
self.FCF_UpdateCombatLogPosition = nil
function FCF_UpdateCombatLogPosition()
if self.hooks.FCF_UpdateCombatLogPosition then
self.hooks.FCF_UpdateCombatLogPosition(self)
else
self.hooks.orig.FCF_UpdateCombatLogPosition()
end
end
end
if not self.hooks.orig.UIParent_ManageFramePositions then
self.hooks.orig.UIParent_ManageFramePositions = UIParent_ManageFramePositions
self.hooks.UIParent_ManageFramePositions = self.UIParent_ManageFramePositions
self.UIParent_ManageFramePositions = nil
function UIParent_ManageFramePositions()
if self.hooks.UIParent_ManageFramePositions then
self.hooks.UIParent_ManageFramePositions(self)
else
self.hooks.orig.UIParent_ManageFramePositions()
end
end
end
if not self.hooks.orig.UIParent_ManageRightSideFrames then
self.hooks.orig.UIParent_ManageRightSideFrames = UIParent_ManageRightSideFrames
self.hooks.UIParent_ManageRightSideFrames = self.UIParent_ManageRightSideFrames
self.UIParent_ManageRightSideFrames = nil
function UIParent_ManageRightSideFrames()
if self.hooks.UIParent_ManageRightSideFrames then
self.hooks.UIParent_ManageRightSideFrames(self)
else
self.hooks.orig.UIParent_ManageRightSideFrames()
end
end
end
if not self.hooks.orig.ToggleWorldMap then
self.hooks.orig.ToggleWorldMap = ToggleWorldMap
self.hooks.ToggleWorldMap = self.ToggleWorldMap
self.ToggleWorldMap = nil
function ToggleWorldMap()
if self.hooks.ToggleWorldMap then
self.hooks.ToggleWorldMap(self)
else
self.hooks.orig.ToggleWorldMap()
end
end
end
self.frame:SetScript("OnEvent", function()
events[event](self)
end)
self.pew = DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage and true or false
if not self.pew then
self.frame:RegisterEvent("PLAYER_ENTERING_WORLD")
end
self.frame:RegisterEvent("PLAYER_AURAS_CHANGED")
table.insert(self.blizzardFrames, 'PlayerFrame')
table.insert(self.blizzardFrames, 'TargetFrame')
table.insert(self.blizzardFrames, 'MinimapCluster')
table.insert(self.blizzardFrames, 'PartyMemberFrame1')
table.insert(self.blizzardFrames, 'TicketStatusFrame')
table.insert(self.blizzardFrames, 'WorldStateAlwaysUpFrame')
table.insert(self.blizzardFrames, 'MainMenuBar')
table.insert(self.blizzardFrames, 'MultiBarRight')
table.insert(self.blizzardFrames, 'CT_PlayerFrame_Drag')
table.insert(self.blizzardFrames, 'CT_TargetFrame_Drag')
table.insert(self.blizzardFrames, 'Gypsy_PlayerFrameCapsule')
table.insert(self.blizzardFrames, 'Gypsy_TargetFrameCapsule')
table.insert(self.blizzardFrames, 'TemporaryEnchantFrame')
table.insert(self.blizzardFrames, 'DEFAULT_CHAT_FRAME')
table.insert(self.blizzardFrames, 'ChatFrame2')
table.insert(self.blizzardFrames, 'GroupLootFrame1')
table.insert(self.blizzardFrames, 'TutorialFrameParent')
table.insert(self.blizzardFrames, 'FramerateLabel')
table.insert(self.blizzardFrames, 'QuestTimerFrame')
table.insert(self.blizzardFrames, 'DurabilityFrame')
table.insert(self.blizzardFrames, 'CastingBarFrame')
if oldDeactivate then
oldDeactivate(oldLib)
end
end
AceLibrary:Register(Jostle, MAJOR_VERSION, MINOR_VERSION, activate)
Jostle = nil