Advertisement
Cokedriver

LibJostle-3.0

Apr 28th, 2014
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.52 KB | None | 0 0
  1. --[[
  2. Name: LibJostle-3.0
  3. Revision: $Rev: 57 $
  4. Author(s): ckknight (ckknight@gmail.com)
  5. Website: http://ckknight.wowinterface.com/
  6. Documentation: http://www.wowace.com/addons/libjostle-3-0/
  7. SVN: svn://svn.wowace.com/wow/libjostle-3-0/mainline/trunk
  8. Description: A library to handle rearrangement of blizzards frames when bars are added to the sides of the screen.
  9. License: LGPL v2.1
  10. --]]
  11.  
  12. local MAJOR_VERSION = "LibJostle-3.0"
  13. local MINOR_VERSION = tonumber(("$Revision: 57 $"):match("(%d+)")) + 90000
  14.  
  15. if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end
  16.  
  17. local oldLib = LibStub:GetLibrary(MAJOR_VERSION, true)
  18. local Jostle = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
  19. if not Jostle then
  20. return
  21. end
  22.  
  23. local blizzardFrames = {
  24. 'PlayerFrame',
  25. 'TargetFrame',
  26. 'MinimapCluster',
  27. 'PartyMemberFrame1',
  28. 'TicketStatusFrame',
  29. 'WorldStateAlwaysUpFrame',
  30. 'MainMenuBar',
  31. 'MultiBarRight',
  32. 'CT_PlayerFrame_Drag',
  33. 'CT_TargetFrame_Drag',
  34. 'Gypsy_PlayerFrameCapsule',
  35. 'Gypsy_TargetFrameCapsule',
  36. 'ConsolidatedBuffs',
  37. 'BuffFrame',
  38. 'DEFAULT_CHAT_FRAME',
  39. 'ChatFrame2',
  40. 'GroupLootFrame1',
  41. 'TutorialFrameParent',
  42. 'FramerateLabel',
  43. 'DurabilityFrame',
  44. 'CastingBarFrame',
  45. }
  46. local blizzardFramesData = {}
  47.  
  48. local _G = _G
  49.  
  50. Jostle.hooks = oldLib and oldLib.hooks or {}
  51. Jostle.topFrames = oldLib and oldLib.topFrames or {}
  52. Jostle.bottomFrames = oldLib and oldLib.bottomFrames or {}
  53. Jostle.topAdjust = oldLib and oldLib.topAdjust
  54. Jostle.bottomAdjust = oldLib and oldLib.bottomAdjust
  55. if Jostle.topAdjust == nil then
  56. Jostle.topAdjust = true
  57. end
  58. if Jostle.bottomAdjust == nil then
  59. Jostle.bottomAdjust = true
  60. end
  61.  
  62. if not Jostle.hooks.WorldMapFrame_Hide then
  63. Jostle.hooks.WorldMapFrame_Hide = true
  64. hooksecurefunc(WorldMapFrame, "Hide", function()
  65. if Jostle.WorldMapFrame_Hide then
  66. Jostle:WorldMapFrame_Hide()
  67. end
  68. end)
  69. end
  70.  
  71. if not Jostle.hooks.TicketStatusFrame_OnEvent then
  72. Jostle.hooks.TicketStatusFrame_OnEvent = true
  73. hooksecurefunc("TicketStatusFrame_OnEvent", function()
  74. if Jostle.TicketStatusFrame_OnEvent then
  75. Jostle:TicketStatusFrame_OnEvent()
  76. end
  77. end)
  78. end
  79.  
  80. if not Jostle.hooks.FCF_UpdateDockPosition then
  81. Jostle.hooks.FCF_UpdateDockPosition = true
  82. hooksecurefunc("FCF_UpdateDockPosition", function()
  83. if Jostle.FCF_UpdateDockPosition then
  84. Jostle:FCF_UpdateDockPosition()
  85. end
  86. end)
  87. end
  88.  
  89. if FCF_UpdateCombatLogPosition and not Jostle.hooks.FCF_UpdateCombatLogPosition then
  90. Jostle.hooks.FCF_UpdateCombatLogPosition = true
  91. hooksecurefunc("FCF_UpdateCombatLogPosition", function()
  92. if Jostle.FCF_UpdateCombatLogPosition then
  93. Jostle:FCF_UpdateCombatLogPosition()
  94. end
  95. end)
  96. end
  97.  
  98. if not Jostle.hooks.UIParent_ManageFramePositions then
  99. Jostle.hooks.UIParent_ManageFramePositions = true
  100. hooksecurefunc("UIParent_ManageFramePositions", function()
  101. if Jostle.UIParent_ManageFramePositions then
  102. Jostle:UIParent_ManageFramePositions()
  103. end
  104. end)
  105. end
  106.  
  107. if not Jostle.hooks.PlayerFrame_SequenceFinished then
  108. Jostle.hooks.PlayerFrame_SequenceFinished = true
  109. hooksecurefunc("PlayerFrame_SequenceFinished", function()
  110. if Jostle.PlayerFrame_SequenceFinished then
  111. Jostle:PlayerFrame_SequenceFinished()
  112. end
  113. end)
  114. end
  115.  
  116. Jostle.frame = oldLib and oldLib.frame or CreateFrame("Frame")
  117. local JostleFrame = Jostle.frame
  118. local start = GetTime()
  119. local nextTime = 0
  120. local fullyInitted = false
  121. JostleFrame:SetScript("OnUpdate", function(this, elapsed)
  122. local now = GetTime()
  123. if now - start >= 3 then
  124. fullyInitted = true
  125. for k,v in pairs(blizzardFramesData) do
  126. blizzardFramesData[k] = nil
  127. end
  128. this:SetScript("OnUpdate", function(this, elapsed)
  129. if GetTime() >= nextTime then
  130. Jostle:Refresh()
  131. this:Hide()
  132. end
  133. end)
  134. end
  135. end)
  136. function JostleFrame:Schedule(time)
  137. time = time or 0
  138. nextTime = GetTime() + time
  139. self:Show()
  140. end
  141. JostleFrame:UnregisterAllEvents()
  142. JostleFrame:SetScript("OnEvent", function(this, event, ...)
  143. return Jostle[event](Jostle, ...)
  144. end)
  145. JostleFrame:RegisterEvent("PLAYER_AURAS_CHANGED")
  146. JostleFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  147. JostleFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  148. JostleFrame:RegisterEvent("PLAYER_CONTROL_GAINED")
  149.  
  150. function Jostle:PLAYER_AURAS_CHANGED()
  151. JostleFrame:Schedule()
  152. end
  153.  
  154. function Jostle:WorldMapFrame_Hide()
  155. JostleFrame:Schedule()
  156. end
  157.  
  158. function Jostle:TicketStatusFrame_OnEvent()
  159. self:Refresh(TicketStatusFrame, ConsolidatedBuffs)
  160. end
  161.  
  162. function Jostle:FCF_UpdateDockPosition()
  163. self:Refresh(DEFAULT_CHAT_FRAME)
  164. end
  165.  
  166. function Jostle:FCF_UpdateCombatLogPosition()
  167. self:Refresh(ChatFrame2)
  168. end
  169.  
  170. function Jostle:UIParent_ManageFramePositions()
  171. self:Refresh(GroupLootFrame1, TutorialFrameParent, FramerateLabel, DurabilityFrame)
  172. end
  173.  
  174. function Jostle:PlayerFrame_SequenceFinished()
  175. self:Refresh(PlayerFrame)
  176. end
  177.  
  178. function Jostle:GetScreenTop()
  179. local bottom = GetScreenHeight()
  180. for _,frame in ipairs(self.topFrames) do
  181. if frame.IsShown and frame:IsShown() and frame.GetBottom and frame:GetBottom() and frame:GetBottom() < bottom then
  182. bottom = frame:GetBottom()
  183. end
  184. end
  185. return bottom
  186. end
  187.  
  188. function Jostle:GetScreenBottom()
  189. local top = 0
  190. for _,frame in ipairs(self.bottomFrames) do
  191. if frame.IsShown and frame:IsShown() and frame.GetTop and frame:GetTop() and frame:GetTop() > top then
  192. top = frame:GetTop()
  193. end
  194. end
  195. return top
  196. end
  197.  
  198. function Jostle:RegisterTop(frame)
  199. for k,f in ipairs(self.bottomFrames) do
  200. if f == frame then
  201. table.remove(self.bottomFrames, k)
  202. break
  203. end
  204. end
  205. for _,f in ipairs(self.topFrames) do
  206. if f == frame then
  207. return
  208. end
  209. end
  210. table.insert(self.topFrames, frame)
  211. JostleFrame:Schedule()
  212. return true
  213. end
  214.  
  215. function Jostle:RegisterBottom(frame)
  216. for k,f in ipairs(self.topFrames) do
  217. if f == frame then
  218. table.remove(self.topFrames, k)
  219. break
  220. end
  221. end
  222. for _,f in ipairs(self.bottomFrames) do
  223. if f == frame then
  224. return
  225. end
  226. end
  227. table.insert(self.bottomFrames, frame)
  228. JostleFrame:Schedule()
  229. return true
  230. end
  231.  
  232. function Jostle:Unregister(frame)
  233. for k,f in ipairs(self.topFrames) do
  234. if f == frame then
  235. table.remove(self.topFrames, k)
  236. JostleFrame:Schedule()
  237. return true
  238. end
  239. end
  240. for k,f in ipairs(self.bottomFrames) do
  241. if f == frame then
  242. table.remove(self.bottomFrames, k)
  243. JostleFrame:Schedule()
  244. return true
  245. end
  246. end
  247. end
  248.  
  249. function Jostle:IsTopAdjusting()
  250. return self.topAdjust
  251. end
  252.  
  253. function Jostle:EnableTopAdjusting()
  254. if not self.topAdjust then
  255. self.topAdjust = not self.topAdjust
  256. JostleFrame:Schedule()
  257. end
  258. end
  259.  
  260. function Jostle:DisableTopAdjusting()
  261. if self.topAdjust then
  262. self.topAdjust = not self.topAdjust
  263. JostleFrame:Schedule()
  264. end
  265. end
  266.  
  267. function Jostle:IsBottomAdjusting()
  268. return self.bottomAdjust
  269. end
  270.  
  271. function Jostle:EnableBottomAdjusting()
  272. if not self.bottomAdjust then
  273. self.bottomAdjust = not self.bottomAdjust
  274. JostleFrame:Schedule()
  275. end
  276. end
  277.  
  278. function Jostle:DisableBottomAdjusting()
  279. if self.bottomAdjust then
  280. self.bottomAdjust = not self.bottomAdjust
  281. JostleFrame:Schedule()
  282. end
  283. end
  284.  
  285. local tmp = {}
  286. local queue = {}
  287. local inCombat = false
  288. function Jostle:ProcessQueue()
  289. if not inCombat and HasFullControl() then
  290. for k in pairs(queue) do
  291. self:Refresh(k)
  292. queue[k] = nil
  293. end
  294. end
  295. end
  296. function Jostle:PLAYER_CONTROL_GAINED()
  297. self:ProcessQueue()
  298. end
  299.  
  300. function Jostle:PLAYER_REGEN_ENABLED()
  301. inCombat = false
  302. self:ProcessQueue()
  303. end
  304.  
  305. function Jostle:PLAYER_REGEN_DISABLED()
  306. inCombat = true
  307. end
  308.  
  309. local function isClose(alpha, bravo)
  310. return math.abs(alpha - bravo) < 0.1
  311. end
  312.  
  313. function Jostle:Refresh(...)
  314. if not fullyInitted then
  315. return
  316. end
  317.  
  318. local screenHeight = GetScreenHeight()
  319. local topOffset = self:IsTopAdjusting() and self:GetScreenTop() or screenHeight
  320. local bottomOffset = self:IsBottomAdjusting() and self:GetScreenBottom() or 0
  321. if topOffset ~= screenHeight or bottomOffset ~= 0 then
  322. JostleFrame:Schedule(10)
  323. end
  324.  
  325. local frames
  326. if select('#', ...) >= 1 then
  327. for k in pairs(tmp) do
  328. tmp[k] = nil
  329. end
  330. for i = 1, select('#', ...) do
  331. tmp[i] = select(i, ...)
  332. end
  333. frames = tmp
  334. else
  335. frames = blizzardFrames
  336. end
  337.  
  338. if inCombat or not HasFullControl() and not UnitHasVehicleUI("player") then
  339. for _,frame in ipairs(frames) do
  340. if type(frame) == "string" then
  341. frame = _G[frame]
  342. end
  343. if frame then
  344. queue[frame] = true
  345. end
  346. end
  347. return
  348. end
  349.  
  350. local screenHeight = GetScreenHeight()
  351. for _,frame in ipairs(frames) do
  352. if type(frame) == "string" then
  353. frame = _G[frame]
  354. end
  355.  
  356. local framescale = frame and frame.GetScale and frame:GetScale() or 1
  357.  
  358. if frame and not blizzardFramesData[frame] and frame.GetTop and frame:GetCenter() and select(2, frame:GetCenter()) then
  359. if select(2, frame:GetCenter()) <= screenHeight / 2 or frame == MultiBarRight then
  360. blizzardFramesData[frame] = {y = frame:GetBottom(), top = false}
  361. else
  362. blizzardFramesData[frame] = {y = frame:GetTop() - screenHeight / framescale, top = true}
  363. end
  364. if frame == MinimapCluster then
  365. blizzardFramesData[frame].lastX = GetScreenWidth() - MinimapCluster:GetWidth()
  366. blizzardFramesData[frame].lastY = GetScreenHeight()
  367. blizzardFramesData[frame].lastScale = 1
  368. end
  369. end
  370. end
  371.  
  372. for _,frame in ipairs(frames) do
  373. if type(frame) == "string" then
  374. frame = _G[frame]
  375. end
  376.  
  377. local framescale = frame and frame.GetScale and frame:GetScale() or 1
  378.  
  379. 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
  380. local frameData = blizzardFramesData[frame]
  381. if (select(2, frame:GetPoint(1)) ~= UIParent and select(2, frame:GetPoint(1)) ~= WorldFrame) then
  382. -- do nothing
  383. elseif frame == PlayerFrame and (CT_PlayerFrame_Drag or Gypsy_PlayerFrameCapsule) then
  384. -- do nothing
  385. elseif frame == TargetFrame and (CT_TargetFrame_Drag or Gypsy_TargetFrameCapsule) then
  386. -- do nothing
  387. elseif frame == PartyMemberFrame1 and (CT_MovableParty1_Drag or Gypsy_PartyFrameCapsule) then
  388. -- do nothing
  389. elseif frame == MainMenuBar and Gypsy_HotBarCapsule then
  390. -- do nothing
  391. elseif frame == MinimapCluster and select(3, frame:GetPoint(1)) ~= "TOPRIGHT" then
  392. -- do nothing
  393. elseif frame == DurabilityFrame and DurabilityFrame:IsShown() and (DurabilityFrame:GetLeft() > GetScreenWidth() or DurabilityFrame:GetRight() < 0 or DurabilityFrame:GetBottom() > GetScreenHeight() or DurabilityFrame:GetTop() < 0) then
  394. DurabilityFrame:Hide()
  395. elseif frame == FramerateLabel and ((frameData.lastX and not isClose(frameData.lastX, frame:GetLeft())) or not isClose(WorldFrame:GetHeight() * WorldFrame:GetScale(), UIParent:GetHeight() * UIParent:GetScale())) then
  396. -- do nothing
  397. elseif frame == PlayerFrame or frame == MainMenuBar or frame == ConsolidatedBuffs or frame == CastingBarFrame or frame == TutorialFrameParent or frame == FramerateLabel or frame == DurabilityFrame or frame == WatchFrame or not (frameData.lastScale and frame.GetScale and frameData.lastScale == frame:GetScale()) or not (frameData.lastX and frameData.lastY and (not isClose(frameData.lastX, frame:GetLeft()) or not isClose(frameData.lastY, frame:GetTop()))) then
  398. local anchor
  399. local anchorAlt
  400. local width, height = GetScreenWidth(), GetScreenHeight()
  401. local x
  402.  
  403. if frame:GetRight() and frame:GetLeft() then
  404. local anchorFrame = UIParent
  405. if frame == MainMenuBar or frame == GroupLootFrame1 or frame == FramerateLabel then
  406. x = 0
  407. anchor = ""
  408. elseif frame:GetRight() / framescale <= width / 2 then
  409. x = frame:GetLeft() / framescale
  410. anchor = "LEFT"
  411. else
  412. x = frame:GetRight() - width / framescale
  413. anchor = "RIGHT"
  414. end
  415. local y = blizzardFramesData[frame].y
  416. local offset = 0
  417. if blizzardFramesData[frame].top then
  418. anchor = "TOP" .. anchor
  419. offset = ( topOffset - height ) / framescale
  420. else
  421. anchor = "BOTTOM" .. anchor
  422. offset = bottomOffset / framescale
  423. end
  424. if frame == MinimapCluster and not MinimapBorderTop:IsShown() then
  425. offset = offset + MinimapBorderTop:GetHeight() * 3/5
  426. elseif frame == ConsolidatedBuffs and TicketStatusFrame:IsShown() then
  427. offset = offset - TicketStatusFrame:GetHeight() * TicketStatusFrame:GetScale()
  428. elseif frame == DEFAULT_CHAT_FRAME then
  429. y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 32
  430. if StanceBarFrame and (PetActionBarFrame:IsShown() or StanceBarFrame:IsShown()) then
  431. offset = offset + StanceBarFrame:GetHeight() * StanceBarFrame:GetScale()
  432. end
  433. if MultiBarBottomLeft:IsShown() then
  434. offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale() - 21
  435. end
  436. elseif frame == ChatFrame2 then
  437. y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 32
  438. if MultiBarBottomRight:IsShown() then
  439. offset = offset + MultiBarBottomRight:GetHeight() * MultiBarBottomRight:GetScale() - 21
  440. end
  441. elseif frame == CastingBarFrame then
  442. y = MainMenuBar:GetHeight() * MainMenuBar:GetScale() + 17
  443. if StanceBarFrame and (PetActionBarFrame:IsShown() or StanceBarFrame:IsShown()) then
  444. offset = offset + StanceBarFrame:GetHeight() * StanceBarFrame:GetScale()
  445. end
  446. if MultiBarBottomLeft:IsShown() or MultiBarBottomRight:IsShown() then
  447. offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale()
  448. end
  449. elseif frame == GroupLootFrame1 or frame == TutorialFrameParent or frame == FramerateLabel then
  450. if MultiBarBottomLeft:IsShown() or MultiBarBottomRight:IsShown() then
  451. offset = offset + MultiBarBottomLeft:GetHeight() * MultiBarBottomLeft:GetScale()
  452. end
  453. elseif frame == DurabilityFrame or frame == WatchFrame then
  454. anchorFrame = MinimapCluster
  455. x = 0
  456. y = 0
  457. offset = 0
  458. if frame == WatchFrame and DurabilityFrame:IsShown() then
  459. y = y - DurabilityFrame:GetHeight() * DurabilityFrame:GetScale()
  460. end
  461. if frame == DurabilityFrame then
  462. x = -20
  463. end
  464. anchor = "TOPRIGHT"
  465. anchorAlt = "BOTTOMRIGHT"
  466. if MultiBarRight:IsShown() then
  467. x = x - MultiBarRight:GetWidth() * MultiBarRight:GetScale()
  468. if MultiBarLeft:IsShown() then
  469. x = x - MultiBarLeft:GetWidth() * MultiBarLeft:GetScale()
  470. end
  471. end
  472. end
  473. if frame == FramerateLabel then
  474. anchorFrame = WorldFrame
  475. end
  476. frame:ClearAllPoints()
  477. frame:SetPoint(anchor, anchorFrame, anchorAlt or anchor, x, y + offset)
  478. blizzardFramesData[frame].lastX = frame:GetLeft()
  479. blizzardFramesData[frame].lastY = frame:GetTop()
  480. blizzardFramesData[frame].lastScale = framescale
  481. end
  482. end
  483. end
  484. end
  485. end
  486.  
  487. local function compat()
  488. local Jostle20 = {}
  489. function Jostle20:RegisterTop(...)
  490. Jostle:RegisterTop(...)
  491. end
  492. function Jostle20:RegisterBottom(...)
  493. Jostle:RegisterBottom(...)
  494. end
  495. function Jostle20:GetScreenTop(...)
  496. Jostle:GetScreenTop(...)
  497. end
  498. function Jostle20:GetScreenBottom(...)
  499. Jostle:GetScreenBottom(...)
  500. end
  501. function Jostle20:Unregister(...)
  502. Jostle:Unregister(...)
  503. end
  504. function Jostle20:IsTopAdjusting(...)
  505. Jostle:IsTopAdjusting(...)
  506. end
  507. function Jostle20:EnableTopAdjusting(...)
  508. Jostle:EnableTopAdjusting(...)
  509. end
  510. function Jostle20:DisableTopAdjusting(...)
  511. Jostle:DisableTopAdjusting(...)
  512. end
  513. function Jostle20:IsBottomAdjusting(...)
  514. Jostle:IsBottomAdjusting(...)
  515. end
  516. function Jostle20:EnableBottomAdjusting(...)
  517. Jostle:EnableBottomAdjusting(...)
  518. end
  519. function Jostle20:DisableBottomAdjusting(...)
  520. Jostle:DisableBottomAdjusting(...)
  521. end
  522. function Jostle20:Refresh(...)
  523. Jostle:Refresh(...)
  524. end
  525. local function activate(self, oldLib)
  526. Jostle20 = self
  527. if oldLib and oldLib.topFrames and oldLib.bottomFrames then
  528. for i,v in ipairs(oldLib.topFrames) do
  529. Jostle:RegisterTop(v)
  530. end
  531. for i,v in ipairs(oldLib.bottomFrames) do
  532. Jostle:RegisterBottom(v)
  533. end
  534. end
  535. end
  536. local function external(self, instance, major)
  537. if major == "AceEvent-2.0" then
  538. instance:embed(self)
  539.  
  540. self:UnregisterAllEvents()
  541. self:CancelAllScheduledEvents()
  542. end
  543. end
  544. AceLibrary:Register(Jostle20, "Jostle-2.0", MINOR_VERSION*1000, activate, external)
  545. Jostle20 = AceLibrary("Jostle-2.0")
  546. end
  547. if AceLibrary then
  548. compat()
  549. elseif Rock then
  550. function Jostle:OnLibraryLoad(major, version)
  551. if major == "AceLibrary" then
  552. compat()
  553. end
  554. end
  555. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement