UIParent.lua

UIParent.lua (8.3.7.35662; unchanged since 8.3.0.34601)
  1. TOOLTIP_UPDATE_TIME = 0.2;
  2. BOSS_FRAME_CASTBAR_HEIGHT = 16;
  3. -- Alpha animation stuff
  4. FADEFRAMES = {};
  5. FLASHFRAMES = {};
  6. -- Pulsing stuff
  7. PULSEBUTTONS = {};
  8. -- Shine animation
  9. SHINES_TO_ANIMATE = {};
  10. -- Macros
  11. MAX_ACCOUNT_MACROS = 120;
  12. MAX_CHARACTER_MACROS = 18;
  13. -- UIPanel Management constants
  14. UIPANEL_SKIP_SET_POINT = true;
  15. UIPANEL_DO_SET_POINT = nil;
  16. UIPANEL_VALIDATE_CURRENT_FRAME = true;
  17. -- Per panel settings
  18. UIPanelWindows = {};
  19. --Center Menu Frames
  20. UIPanelWindows["GameMenuFrame"] = { area = "center", pushable = 0, whileDead = 1 };
  21. UIPanelWindows["VideoOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 };
  22. UIPanelWindows["AudioOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 };
  23. UIPanelWindows["InterfaceOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 };
  24. UIPanelWindows["HelpFrame"] = { area = "center", pushable = 0, whileDead = 1 };
  25. -- Frames using the new Templates
  26. UIPanelWindows["CharacterFrame"] = { area = "left", pushable = 3, whileDead = 1};
  27. UIPanelWindows["SpellBookFrame"] = { area = "left", pushable = 1, whileDead = 1, width = 575, height = 545 };
  28. UIPanelWindows["TaxiFrame"] = { area = "left", pushable = 0, width = 605, height = 580, showFailedFunc = CloseTaxiMap };
  29. UIPanelWindows["PVPUIFrame"] = { area = "left", pushable = 0, whileDead = 1, width = 563};
  30. UIPanelWindows["PVPBannerFrame"] = { area = "left", pushable = 1};
  31. UIPanelWindows["PetStableFrame"] = { area = "left", pushable = 0};
  32. UIPanelWindows["PVEFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  33. UIPanelWindows["EncounterJournal"] = { area = "left", pushable = 0, whileDead = 1, width = 830};
  34. UIPanelWindows["CollectionsJournal"] = { area = "left", pushable = 0, whileDead = 1, width = 733};
  35. UIPanelWindows["TradeFrame"] = { area = "left", pushable = 1};
  36. UIPanelWindows["LootFrame"] = { area = "left", pushable = 7};
  37. UIPanelWindows["MerchantFrame"] = { area = "left", pushable = 0};
  38. UIPanelWindows["TabardFrame"] = { area = "left", pushable = 0};
  39. UIPanelWindows["PVPBannerFrame"] = { area = "left", pushable = 1};
  40. UIPanelWindows["MailFrame"] = { area = "left", pushable = 0};
  41. UIPanelWindows["BankFrame"] = { area = "left", pushable = 6, width = 425 };
  42. UIPanelWindows["QuestLogPopupDetailFrame"] = { area = "left", pushable = 0, whileDead = 1 };
  43. UIPanelWindows["QuestFrame"] = { area = "left", pushable = 0};
  44. UIPanelWindows["GuildRegistrarFrame"] = { area = "left", pushable = 0};
  45. UIPanelWindows["GossipFrame"] = { area = "left", pushable = 0};
  46. UIPanelWindows["DressUpFrame"] = { area = "left", pushable = 2};
  47. UIPanelWindows["PetitionFrame"] = { area = "left", pushable = 0};
  48. UIPanelWindows["ItemTextFrame"] = { area = "left", pushable = 0};
  49. UIPanelWindows["FriendsFrame"] = { area = "left", pushable = 0, whileDead = 1 };
  50. UIPanelWindows["RaidParentFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  51. UIPanelWindows["RaidBrowserFrame"] = { area = "left", pushable = 1, };
  52. UIPanelWindows["DeathRecapFrame"] = { area = "center", pushable = 0, whileDead = 1, allowOtherPanels = 1};
  53. UIPanelWindows["WardrobeFrame"] = { area = "left", pushable = 0, width = 965 };
  54. UIPanelWindows["AlliedRacesFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  55. UIPanelWindows["GuildControlUI"] = { area = "left", pushable = 1, whileDead = 1, yoffset = 4, };
  56. UIPanelWindows["CommunitiesFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  57. UIPanelWindows["CommunitiesGuildLogFrame"] = { area = "left", pushable = 1, whileDead = 1, yoffset = 4, };
  58. UIPanelWindows["CommunitiesGuildTextEditFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  59. UIPanelWindows["CommunitiesGuildRecruitmentFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  60. UIPanelWindows["CommunitiesGuildNewsFiltersFrame"] = { area = "left", pushable = 1, whileDead = 1 };
  61. UIPanelWindows["ClubFinderGuildRecruitmentDialog"] = { area = "left", pushable = 1, whileDead = 1 };
  62. -- Frames NOT using the new Templates
  63. UIPanelWindows["CinematicFrame"] = { area = "full", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 1 };
  64. UIPanelWindows["ChatConfigFrame"] = { area = "center", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 1 };
  65. UIPanelWindows["PVPMatchScoreboard"] = { area = "center", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 1, ignoreControlLost = true, };
  66. UIPanelWindows["PVPMatchResults"] = { area = "center", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 1, ignoreControlLost = true, };
  67. UIPanelWindows["QuestChoiceFrame"] = { area = "center", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 0, allowOtherPanels = 1 };
  68. UIPanelWindows["WarboardQuestChoiceFrame"] = { area = "center", pushable = 0, xoffset = -16, yoffset = 12, whileDead = 0, allowOtherPanels = 1 };
  69. UIPanelWindows["GarrisonBuildingFrame"] = { area = "center", pushable = 0, whileDead = 1, width = 1002, allowOtherPanels = 1};
  70. UIPanelWindows["GarrisonMissionFrame"] = { area = "center", pushable = 0, whileDead = 1, checkFit = 1, allowOtherPanels = 1, extraWidth = 20, extraHeight = 100 };
  71. UIPanelWindows["GarrisonShipyardFrame"] = { area = "center", pushable = 0, whileDead = 1, checkFit = 1, allowOtherPanels = 1, extraWidth = 20, extraHeight = 100 };
  72. UIPanelWindows["GarrisonLandingPage"] = { area = "left", pushable = 1, whileDead = 1, width = 830, yoffset = 9, allowOtherPanels = 1};
  73. UIPanelWindows["GarrisonMonumentFrame"] = { area = "center", pushable = 0, whileDead = 1, width = 333, allowOtherPanels = 1};
  74. UIPanelWindows["GarrisonRecruiterFrame"] = { area = "left", pushable = 0};
  75. UIPanelWindows["GarrisonRecruitSelectFrame"] = { area = "center", pushable = 0};
  76. UIPanelWindows["OrderHallMissionFrame"] = { area = "center", pushable = 0, whileDead = 1, checkFit = 1, allowOtherPanels = 1, extraWidth = 20, extraHeight = 100 };
  77. UIPanelWindows["OrderHallTalentFrame"] = { area = "left", pushable = 0, xoffset = 16};
  78. UIPanelWindows["ChallengesKeystoneFrame"] = { area = "center", pushable = 0};
  79. UIPanelWindows["BFAMissionFrame"] = { area = "center", pushable = 0, whileDead = 1, checkFit = 1, allowOtherPanels = 1, extraWidth = 20, extraHeight = 100 };
  80. local function GetUIPanelWindowInfo(frame, name)
  81. if ( not frame:GetAttribute("UIPanelLayout-defined") ) then
  82. local info = UIPanelWindows[frame:GetName()];
  83. if ( not info ) then
  84. return;
  85. end
  86. frame:SetAttribute("UIPanelLayout-defined", true);
  87. for name,value in pairs(info) do
  88. frame:SetAttribute("UIPanelLayout-"..name, value);
  89. end
  90. end
  91. return frame:GetAttribute("UIPanelLayout-"..name);
  92. end
  93. function SetUIPanelAttribute(frame, name, value)
  94. local info = UIPanelWindows[frame:GetName()];
  95. if ( not info ) then
  96. return;
  97. end
  98. if ( not frame:GetAttribute("UIPanelLayout-defined") ) then
  99. frame:SetAttribute("UIPanelLayout-defined", true);
  100. for name,value in pairs(info) do
  101. frame:SetAttribute("UIPanelLayout-"..name, value);
  102. end
  103. end
  104. frame:SetAttribute("UIPanelLayout-"..name, value);
  105. end
  106. -- These are windows that rely on a parent frame to be open. If the parent closes or a pushable frame overlaps them they must be hidden.
  107. UIChildWindows = {
  108. "OpenMailFrame",
  109. "GuildMemberDetailFrame",
  110. "TokenFramePopup",
  111. "GuildBankPopupFrame",
  112. "GearManagerDialog",
  113. };
  114. function UpdateUIParentRelativeToDebugMenu()
  115. local debugMenuOffset = DebugMenu and DebugMenu.IsVisible() and -DebugMenu.GetMenuHeight() or 0;
  116. local revealTimeTrackOffset = C_Reveal and C_Reveal:IsCapturing() and -C_Reveal:GetTimeTrackHeight() or 0;
  117. local topOffset = debugMenuOffset + revealTimeTrackOffset;
  118. UIParent:SetPoint("TOPLEFT", 0, topOffset);
  119. end
  120. UISpecialFrames = {
  121. "ItemRefTooltip",
  122. "ColorPickerFrame",
  123. "FloatingPetBattleAbilityTooltip",
  124. "FloatingGarrisonFollowerTooltip",
  125. "FloatingGarrisonShipyardFollowerTooltip"
  126. };
  127. UIMenus = {
  128. "ChatMenu",
  129. "EmoteMenu",
  130. "LanguageMenu",
  131. "DropDownList1",
  132. "DropDownList2",
  133. };
  134. ITEM_QUALITY_COLORS = { };
  135. for i = 0, NUM_LE_ITEM_QUALITYS - 1 do
  136. local r, g, b = GetItemQualityColor(i);
  137. local color = CreateColor(r, g, b, 1);
  138. ITEM_QUALITY_COLORS[i] = { r = r, g = g, b = b, hex = color:GenerateHexColorMarkup(), color = color };
  139. end
  140. WORLD_QUEST_QUALITY_COLORS = {
  141. [LE_WORLD_QUEST_QUALITY_COMMON] = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON];
  142. [LE_WORLD_QUEST_QUALITY_RARE] = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_RARE];
  143. [LE_WORLD_QUEST_QUALITY_EPIC] = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_EPIC];
  144. };
  145. -- Protecting from addons since we use this in GetScaledCursorDelta which is used in secure code.
  146. local _UIParentGetEffectiveScale;
  147. local _UIParentRef;
  148. function UIParent_OnLoad(self)
  149. _UIParentGetEffectiveScale = self.GetEffectiveScale;
  150. _UIParentRef = self;
  151. self:RegisterEvent("PLAYER_LOGIN");
  152. self:RegisterEvent("PLAYER_DEAD");
  153. self:RegisterEvent("SELF_RES_SPELL_CHANGED");
  154. self:RegisterEvent("PLAYER_ALIVE");
  155. self:RegisterEvent("PLAYER_UNGHOST");
  156. self:RegisterEvent("RESURRECT_REQUEST");
  157. self:RegisterEvent("PLAYER_SKINNED");
  158. self:RegisterEvent("TRADE_REQUEST");
  159. self:RegisterEvent("CHANNEL_INVITE_REQUEST");
  160. self:RegisterEvent("CHANNEL_PASSWORD_REQUEST");
  161. self:RegisterEvent("PARTY_INVITE_REQUEST");
  162. self:RegisterEvent("PARTY_INVITE_CANCEL");
  163. self:RegisterEvent("GUILD_INVITE_REQUEST");
  164. self:RegisterEvent("GUILD_INVITE_CANCEL");
  165. self:RegisterEvent("PLAYER_CAMPING");
  166. self:RegisterEvent("PLAYER_QUITING");
  167. self:RegisterEvent("LOGOUT_CANCEL");
  168. self:RegisterEvent("LOOT_BIND_CONFIRM");
  169. self:RegisterEvent("EQUIP_BIND_CONFIRM");
  170. self:RegisterEvent("EQUIP_BIND_TRADEABLE_CONFIRM");
  171. self:RegisterEvent("USE_BIND_CONFIRM");
  172. self:RegisterEvent("USE_NO_REFUND_CONFIRM");
  173. self:RegisterEvent("CONFIRM_BEFORE_USE");
  174. self:RegisterEvent("DELETE_ITEM_CONFIRM");
  175. self:RegisterEvent("QUEST_ACCEPT_CONFIRM");
  176. self:RegisterEvent("QUEST_LOG_UPDATE");
  177. self:RegisterEvent("UNIT_QUEST_LOG_CHANGED");
  178. self:RegisterEvent("CURSOR_UPDATE");
  179. self:RegisterEvent("LOCALPLAYER_PET_RENAMED");
  180. self:RegisterEvent("PLAYER_ENTERING_WORLD");
  181. self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
  182. self:RegisterEvent("MIRROR_TIMER_START");
  183. self:RegisterEvent("DUEL_REQUESTED");
  184. self:RegisterEvent("DUEL_OUTOFBOUNDS");
  185. self:RegisterEvent("DUEL_INBOUNDS");
  186. self:RegisterEvent("DUEL_FINISHED");
  187. self:RegisterEvent("PET_BATTLE_PVP_DUEL_REQUESTED");
  188. self:RegisterEvent("PET_BATTLE_QUEUE_PROPOSE_MATCH");
  189. self:RegisterEvent("PET_BATTLE_QUEUE_PROPOSAL_DECLINED");
  190. self:RegisterEvent("PET_BATTLE_QUEUE_PROPOSAL_ACCEPTED");
  191. self:RegisterEvent("PET_BATTLE_PVP_DUEL_REQUEST_CANCEL");
  192. self:RegisterEvent("TRADE_REQUEST_CANCEL");
  193. self:RegisterEvent("CONFIRM_XP_LOSS");
  194. self:RegisterEvent("CORPSE_IN_RANGE");
  195. self:RegisterEvent("CORPSE_IN_INSTANCE");
  196. self:RegisterEvent("CORPSE_OUT_OF_RANGE");
  197. self:RegisterEvent("AREA_SPIRIT_HEALER_IN_RANGE");
  198. self:RegisterEvent("AREA_SPIRIT_HEALER_OUT_OF_RANGE");
  199. self:RegisterEvent("BIND_ENCHANT");
  200. self:RegisterEvent("ACTION_WILL_BIND_ITEM");
  201. self:RegisterEvent("REPLACE_ENCHANT");
  202. self:RegisterEvent("TRADE_REPLACE_ENCHANT");
  203. self:RegisterEvent("END_BOUND_TRADEABLE");
  204. self:RegisterEvent("CURRENT_SPELL_CAST_CHANGED");
  205. self:RegisterEvent("MACRO_ACTION_BLOCKED");
  206. self:RegisterEvent("ADDON_ACTION_BLOCKED");
  207. self:RegisterEvent("MACRO_ACTION_FORBIDDEN");
  208. self:RegisterEvent("ADDON_ACTION_FORBIDDEN");
  209. self:RegisterEvent("PLAYER_CONTROL_LOST");
  210. self:RegisterEvent("PLAYER_CONTROL_GAINED");
  211. self:RegisterEvent("START_LOOT_ROLL");
  212. self:RegisterEvent("CONFIRM_LOOT_ROLL");
  213. self:RegisterEvent("CONFIRM_DISENCHANT_ROLL");
  214. self:RegisterEvent("INSTANCE_BOOT_START");
  215. self:RegisterEvent("INSTANCE_BOOT_STOP");
  216. self:RegisterEvent("INSTANCE_LOCK_START");
  217. self:RegisterEvent("INSTANCE_LOCK_STOP");
  218. self:RegisterEvent("INSTANCE_LOCK_WARNING");
  219. self:RegisterEvent("CONFIRM_TALENT_WIPE");
  220. self:RegisterEvent("CONFIRM_BINDER");
  221. self:RegisterEvent("CONFIRM_SUMMON");
  222. self:RegisterEvent("CANCEL_SUMMON");
  223. self:RegisterEvent("GOSSIP_CONFIRM");
  224. self:RegisterEvent("GOSSIP_CONFIRM_CANCEL");
  225. self:RegisterEvent("GOSSIP_ENTER_CODE");
  226. self:RegisterEvent("GOSSIP_CLOSED");
  227. self:RegisterEvent("BILLING_NAG_DIALOG");
  228. self:RegisterEvent("IGR_BILLING_NAG_DIALOG");
  229. self:RegisterEvent("VARIABLES_LOADED");
  230. self:RegisterEvent("GROUP_ROSTER_UPDATE");
  231. self:RegisterEvent("RAID_INSTANCE_WELCOME");
  232. self:RegisterEvent("RAISED_AS_GHOUL");
  233. self:RegisterEvent("SPELL_CONFIRMATION_PROMPT");
  234. self:RegisterEvent("SPELL_CONFIRMATION_TIMEOUT");
  235. self:RegisterEvent("SAVED_VARIABLES_TOO_LARGE");
  236. self:RegisterEvent("EXPERIMENTAL_CVAR_CONFIRMATION_NEEDED");
  237. self:RegisterEvent("BAG_OVERFLOW_WITH_FULL_INVENTORY");
  238. self:RegisterEvent("AUCTION_HOUSE_SCRIPT_DEPRECATED");
  239. self:RegisterEvent("LOADING_SCREEN_ENABLED");
  240. self:RegisterEvent("LOADING_SCREEN_DISABLED");
  241. -- Events for auction UI handling
  242. self:RegisterEvent("AUCTION_HOUSE_SHOW");
  243. self:RegisterEvent("AUCTION_HOUSE_CLOSED");
  244. self:RegisterEvent("AUCTION_HOUSE_DISABLED");
  245. -- Events for trainer UI handling
  246. self:RegisterEvent("TRAINER_SHOW");
  247. self:RegisterEvent("TRAINER_CLOSED");
  248. -- Events for trade skill UI handling
  249. self:RegisterEvent("TRADE_SKILL_SHOW");
  250. self:RegisterEvent("OBLITERUM_FORGE_SHOW");
  251. self:RegisterEvent("SCRAPPING_MACHINE_SHOW");
  252. -- Events for Item socketing UI
  253. self:RegisterEvent("SOCKET_INFO_UPDATE");
  254. -- Events for Artifact UI
  255. self:RegisterEvent("ARTIFACT_UPDATE");
  256. self:RegisterEvent("ARTIFACT_RESPEC_PROMPT");
  257. self:RegisterEvent("ARTIFACT_RELIC_FORGE_UPDATE");
  258. -- Events for Adventure Map UI
  259. self:RegisterEvent("ADVENTURE_MAP_OPEN");
  260. -- Events for taxi benchmarking
  261. self:RegisterEvent("ENABLE_TAXI_BENCHMARK");
  262. self:RegisterEvent("DISABLE_TAXI_BENCHMARK");
  263. -- Events for BarberShop Handling
  264. self:RegisterEvent("BARBER_SHOP_OPEN");
  265. self:RegisterEvent("BARBER_SHOP_CLOSE");
  266. -- Events for Guild bank UI
  267. self:RegisterEvent("GUILDBANKFRAME_OPENED");
  268. self:RegisterEvent("GUILDBANKFRAME_CLOSED");
  269. --Events for GMChatUI
  270. self:RegisterEvent("CHAT_MSG_WHISPER");
  271. -- Events for WoW Mouse
  272. self:RegisterEvent("WOW_MOUSE_NOT_FOUND");
  273. -- Events for talent wipes
  274. self:RegisterEvent("TALENTS_INVOLUNTARILY_RESET");
  275. -- Events for disabled specs
  276. self:RegisterEvent("SPEC_INVOLUNTARILY_CHANGED");
  277. -- Events for Archaeology
  278. self:RegisterEvent("ARCHAEOLOGY_TOGGLE");
  279. self:RegisterEvent("ARCHAEOLOGY_SURVEY_CAST");
  280. -- Events for transmogrify
  281. self:RegisterEvent("TRANSMOGRIFY_OPEN");
  282. self:RegisterEvent("TRANSMOGRIFY_CLOSE");
  283. -- Events for Adventure Journal
  284. self:RegisterEvent("AJ_OPEN");
  285. -- Events for void storage
  286. self:RegisterEvent("VOID_STORAGE_OPEN");
  287. self:RegisterEvent("VOID_STORAGE_CLOSE");
  288. -- Events for contributions
  289. self:RegisterEvent("CONTRIBUTION_COLLECTOR_OPEN");
  290. self:RegisterEvent("CONTRIBUTION_COLLECTOR_CLOSE");
  291. -- Events for Trial caps
  292. self:RegisterEvent("TRIAL_CAP_REACHED_MONEY");
  293. self:RegisterEvent("TRIAL_CAP_REACHED_LEVEL");
  294. -- Events for black market
  295. self:RegisterEvent("BLACK_MARKET_OPEN");
  296. self:RegisterEvent("BLACK_MARKET_CLOSE");
  297. -- Events for item upgrades
  298. self:RegisterEvent("ITEM_UPGRADE_MASTER_OPENED");
  299. self:RegisterEvent("ITEM_UPGRADE_MASTER_CLOSED");
  300. -- Events for Toy Box
  301. self:RegisterEvent("TOYS_UPDATED");
  302. -- Events for Heirlooms Journal
  303. self:RegisterEvent("HEIRLOOM_UPGRADE_TARGETING_CHANGED");
  304. self:RegisterEvent("HEIRLOOMS_UPDATED");
  305. -- Events for Wardrobe
  306. self:RegisterEvent("TRANSMOG_COLLECTION_UPDATED");
  307. -- Events for Quest Choice
  308. self:RegisterEvent("QUEST_CHOICE_UPDATE");
  309. -- Lua warnings
  310. self:RegisterEvent("LUA_WARNING");
  311. -- debug menu
  312. self:RegisterEvent("DEBUG_MENU_TOGGLED");
  313. -- Reveal
  314. self:RegisterEvent("REVEAL_CAPTURE_TOGGLED");
  315. -- Garrison
  316. self:RegisterEvent("GARRISON_ARCHITECT_OPENED");
  317. self:RegisterEvent("GARRISON_ARCHITECT_CLOSED");
  318. self:RegisterEvent("GARRISON_MISSION_NPC_OPENED");
  319. self:RegisterEvent("GARRISON_MISSION_NPC_CLOSED");
  320. self:RegisterEvent("GARRISON_SHIPYARD_NPC_OPENED");
  321. self:RegisterEvent("GARRISON_SHIPYARD_NPC_CLOSED");
  322. self:RegisterEvent("SHIPMENT_CRAFTER_OPENED");
  323. self:RegisterEvent("GARRISON_MONUMENT_SHOW_UI");
  324. self:RegisterEvent("GARRISON_RECRUITMENT_NPC_OPENED");
  325. self:RegisterEvent("GARRISON_TALENT_NPC_OPENED");
  326. -- Shop (for Asia promotion)
  327. self:RegisterEvent("PRODUCT_DISTRIBUTIONS_UPDATED");
  328. self:RegisterEvent("TOKEN_AUCTION_SOLD");
  329. -- Talking Head
  330. self:RegisterEvent("TALKINGHEAD_REQUESTED");
  331. -- Challenge Mode 2.0
  332. self:RegisterEvent("CHALLENGE_MODE_KEYSTONE_RECEPTABLE_OPEN");
  333. self:RegisterEvent("CHALLENGE_MODE_COMPLETED");
  334. -- Used for Order Hall UI
  335. self:RegisterUnitEvent("UNIT_AURA", "player");
  336. self:RegisterEvent("TAXIMAP_OPENED");
  337. -- Used to determine when to load BoostTutorial
  338. self:RegisterEvent("SCENARIO_UPDATE");
  339. -- Invite confirmations
  340. self:RegisterEvent("GROUP_INVITE_CONFIRMATION");
  341. self:RegisterEvent("INVITE_TO_PARTY_CONFIRMATION");
  342. -- Event(s) for the ArtifactUI
  343. self:RegisterEvent("ARTIFACT_ENDGAME_REFUND");
  344. -- Event(s) for PVP
  345. self:RegisterEvent("UPDATE_BATTLEFIELD_STATUS");
  346. self:RegisterEvent("PVP_BRAWL_INFO_UPDATED");
  347. -- Event(s) for Allied Races
  348. self:RegisterEvent("ALLIED_RACE_OPEN");
  349. -- Event(s) for Islands
  350. self:RegisterEvent("ISLAND_COMPLETED");
  351. self:RegisterEvent("ISLANDS_QUEUE_OPEN");
  352. -- Event(s) for Warfronts
  353. self:RegisterEvent("WARFRONT_COMPLETED");
  354. -- Event(s) for Azerite Empowered Items
  355. self:RegisterEvent("RESPEC_AZERITE_EMPOWERED_ITEM_OPENED");
  356. -- Event(s) for Heart of Azeroth forge
  357. self:RegisterEvent("AZERITE_ESSENCE_FORGE_OPEN");
  358. -- Events for Reporting SYSTEM
  359. self:RegisterEvent("REPORT_PLAYER_RESULT");
  360. -- Events for Global Mouse Down
  361. self:RegisterEvent("GLOBAL_MOUSE_DOWN");
  362. self:RegisterEvent("GLOBAL_MOUSE_UP");
  363. -- Event(s) for Item Interaction
  364. self:RegisterEvent("ITEM_INTERACTION_OPEN");
  365. end
  366. function UIParent_OnShow(self)
  367. if ( self.firstTimeLoaded ~= 1 ) then
  368. CloseAllWindows();
  369. self.firstTimeLoaded = nil;
  370. end
  371. if ( LowHealthFrame ) then
  372. LowHealthFrame:EvaluateVisibleState();
  373. end
  374. end
  375. function UIParent_OnHide(self)
  376. if ( LowHealthFrame ) then
  377. LowHealthFrame:EvaluateVisibleState();
  378. end
  379. end
  380. -- Addons --
  381. local FailedAddOnLoad = {};
  382. function UIParentLoadAddOn(name)
  383. local loaded, reason = LoadAddOn(name);
  384. if ( not loaded ) then
  385. if ( not FailedAddOnLoad[name] ) then
  386. message(format(ADDON_LOAD_FAILED, name, _G["ADDON_"..reason]));
  387. FailedAddOnLoad[name] = true;
  388. end
  389. end
  390. return loaded;
  391. end
  392. function ItemInteraction_LoadUI()
  393. UIParentLoadAddOn("Blizzard_ItemInteractionUI");
  394. end
  395. function IslandsQueue_LoadUI()
  396. UIParentLoadAddOn("Blizzard_IslandsQueueUI");
  397. end
  398. function PartyPose_LoadUI()
  399. UIParentLoadAddOn("Blizzard_PartyPoseUI");
  400. end
  401. function IslandsPartyPose_LoadUI()
  402. UIParentLoadAddOn("Blizzard_IslandsPartyPoseUI");
  403. end
  404. function WarfrontsPartyPose_LoadUI()
  405. UIParentLoadAddOn("Blizzard_WarfrontsPartyPoseUI");
  406. end
  407. function AlliedRaces_LoadUI()
  408. UIParentLoadAddOn("Blizzard_AlliedRacesUI");
  409. end
  410. function AuctionHouseFrame_LoadUI()
  411. UIParentLoadAddOn("Blizzard_AuctionHouseUI");
  412. end
  413. function BattlefieldMap_LoadUI()
  414. UIParentLoadAddOn("Blizzard_BattlefieldMap");
  415. end
  416. function ClassTrainerFrame_LoadUI()
  417. UIParentLoadAddOn("Blizzard_TrainerUI");
  418. end
  419. function CombatLog_LoadUI()
  420. UIParentLoadAddOn("Blizzard_CombatLog");
  421. end
  422. function Commentator_LoadUI()
  423. UIParentLoadAddOn("Blizzard_Commentator");
  424. end
  425. function GuildBankFrame_LoadUI()
  426. UIParentLoadAddOn("Blizzard_GuildBankUI");
  427. end
  428. function InspectFrame_LoadUI()
  429. UIParentLoadAddOn("Blizzard_InspectUI");
  430. end
  431. function KeyBindingFrame_LoadUI()
  432. UIParentLoadAddOn("Blizzard_BindingUI");
  433. end
  434. function MacroFrame_LoadUI()
  435. UIParentLoadAddOn("Blizzard_MacroUI");
  436. end
  437. function MacroFrame_SaveMacro()
  438. -- this will be overwritten with the real thing when the addon is loaded
  439. end
  440. function RaidFrame_LoadUI()
  441. UIParentLoadAddOn("Blizzard_RaidUI");
  442. end
  443. function SocialFrame_LoadUI()
  444. AchievementFrame_LoadUI();
  445. UIParentLoadAddOn("Blizzard_SocialUI");
  446. end
  447. function TalentFrame_LoadUI()
  448. UIParentLoadAddOn("Blizzard_TalentUI");
  449. end
  450. function TradeSkillFrame_LoadUI()
  451. UIParentLoadAddOn("Blizzard_TradeSkillUI");
  452. end
  453. function ObliterumForgeFrame_LoadUI()
  454. UIParentLoadAddOn("Blizzard_ObliterumUI");
  455. end
  456. function ScrappingMachineFrame_LoadUI()
  457. UIParentLoadAddOn("Blizzard_ScrappingMachineUI");
  458. end
  459. function GMSurveyFrame_LoadUI()
  460. UIParentLoadAddOn("Blizzard_GMSurveyUI");
  461. end
  462. function ItemSocketingFrame_LoadUI()
  463. UIParentLoadAddOn("Blizzard_ItemSocketingUI");
  464. end
  465. function ArtifactFrame_LoadUI()
  466. UIParentLoadAddOn("Blizzard_ArtifactUI");
  467. end
  468. function AdventureMapFrame_LoadUI()
  469. UIParentLoadAddOn("Blizzard_AdventureMap");
  470. end
  471. function BarberShopFrame_LoadUI()
  472. UIParentLoadAddOn("Blizzard_BarberShopUI");
  473. end
  474. function AchievementFrame_LoadUI()
  475. UIParentLoadAddOn("Blizzard_AchievementUI");
  476. end
  477. function TimeManager_LoadUI()
  478. UIParentLoadAddOn("Blizzard_TimeManager");
  479. end
  480. function TokenFrame_LoadUI()
  481. UIParentLoadAddOn("Blizzard_TokenUI");
  482. end
  483. function Calendar_LoadUI()
  484. UIParentLoadAddOn("Blizzard_Calendar");
  485. end
  486. function VoidStorage_LoadUI()
  487. UIParentLoadAddOn("Blizzard_VoidStorageUI");
  488. end
  489. function ArchaeologyFrame_LoadUI()
  490. UIParentLoadAddOn("Blizzard_ArchaeologyUI");
  491. end
  492. function GMChatFrame_LoadUI(...)
  493. if ( IsAddOnLoaded("Blizzard_GMChatUI") ) then
  494. return;
  495. else
  496. UIParentLoadAddOn("Blizzard_GMChatUI");
  497. if ( select(1, ...) ) then
  498. GMChatFrame_OnEvent(GMChatFrame, ...);
  499. end
  500. end
  501. end
  502. function Arena_LoadUI()
  503. UIParentLoadAddOn("Blizzard_ArenaUI");
  504. end
  505. function GuildFrame_LoadUI()
  506. UIParentLoadAddOn("Blizzard_GuildUI");
  507. end
  508. function LookingForGuildFrame_LoadUI()
  509. UIParentLoadAddOn("Blizzard_LookingForGuildUI");
  510. end
  511. function EncounterJournal_LoadUI()
  512. UIParentLoadAddOn("Blizzard_EncounterJournal");
  513. end
  514. function CollectionsJournal_LoadUI()
  515. UIParentLoadAddOn("Blizzard_Collections");
  516. end
  517. function BlackMarket_LoadUI()
  518. UIParentLoadAddOn("Blizzard_BlackMarketUI");
  519. end
  520. function ItemUpgrade_LoadUI()
  521. UIParentLoadAddOn("Blizzard_ItemUpgradeUI");
  522. end
  523. function QuestChoice_LoadUI()
  524. UIParentLoadAddOn("Blizzard_QuestChoice");
  525. end
  526. function WarboardQuestChoice_LoadUI()
  527. UIParentLoadAddOn("Blizzard_WarboardUI");
  528. end
  529. function Store_LoadUI()
  530. UIParentLoadAddOn("Blizzard_StoreUI");
  531. end
  532. function Garrison_LoadUI()
  533. UIParentLoadAddOn("Blizzard_GarrisonUI");
  534. end
  535. function OrderHall_LoadUI()
  536. UIParentLoadAddOn("Blizzard_OrderHallUI");
  537. end
  538. function TalkingHead_LoadUI()
  539. UIParentLoadAddOn("Blizzard_TalkingHeadUI");
  540. end
  541. function ChallengeMode_LoadUI()
  542. UIParentLoadAddOn("Blizzard_ChallengesUI");
  543. end
  544. function FlightMap_LoadUI()
  545. UIParentLoadAddOn("Blizzard_FlightMap");
  546. end
  547. function APIDocumentation_LoadUI()
  548. UIParentLoadAddOn("Blizzard_APIDocumentation");
  549. end
  550. --[[
  551. function MovePad_LoadUI()
  552. UIParentLoadAddOn("Blizzard_MovePad");
  553. end
  554. ]]
  555. function Tutorial_LoadUI()
  556. if ( GetTutorialsEnabled() and UnitLevel("player") < NPE_TUTORIAL_COMPLETE_LEVEL ) then
  557. UIParentLoadAddOn("Blizzard_Tutorial");
  558. end
  559. end
  560. function BoostTutorial_AttemptLoad()
  561. if IsBoostTutorialScenario() and not IsAddOnLoaded("Blizzard_BoostTutorial") then
  562. UIParentLoadAddOn("Blizzard_BoostTutorial");
  563. end
  564. end
  565. function ClassTrial_AttemptLoad()
  566. if C_ClassTrial.IsClassTrialCharacter() and not IsAddOnLoaded("Blizzard_ClassTrial") then
  567. UIParentLoadAddOn("Blizzard_ClassTrial");
  568. end
  569. end
  570. function ClassTrial_IsExpansionTrialUpgradeDialogShowing()
  571. return ExpansionTrialThanksForPlayingDialog and ExpansionTrialThanksForPlayingDialog:IsShowingExpansionTrialUpgrade();
  572. end
  573. function DeathRecap_LoadUI()
  574. UIParentLoadAddOn("Blizzard_DeathRecap");
  575. end
  576. function Communities_LoadUI()
  577. UIParentLoadAddOn("Blizzard_Communities");
  578. end
  579. function AzeriteRespecFrame_LoadUI()
  580. UIParentLoadAddOn("Blizzard_AzeriteRespecUI");
  581. end
  582. local playerEnteredWorld = false;
  583. local varsLoaded = false;
  584. function NPETutorial_AttemptToBegin(event)
  585. if ( NewPlayerExperience and not NewPlayerExperience.IsActive ) then
  586. NewPlayerExperience:Begin();
  587. return;
  588. end
  589. if( event == "PLAYER_ENTERING_WORLD" ) then
  590. playerEnteredWorld = true;
  591. elseif ( event == "VARIABLES_LOADED" ) then
  592. varsLoaded = true;
  593. end
  594. if ( playerEnteredWorld and varsLoaded ) then
  595. Tutorial_LoadUI();
  596. end
  597. end
  598. function OrderHall_CheckCommandBar()
  599. if (not OrderHallCommandBar or not OrderHallCommandBar:IsShown()) then
  600. if (C_Garrison.IsPlayerInGarrison(LE_GARRISON_TYPE_7_0)) then
  601. OrderHall_LoadUI();
  602. OrderHallCommandBar:Show();
  603. end
  604. end
  605. end
  606. function ShowMacroFrame()
  607. MacroFrame_LoadUI();
  608. if ( MacroFrame_Show ) then
  609. MacroFrame_Show();
  610. end
  611. end
  612. function InspectAchievements (unit)
  613. if (IsKioskModeEnabled()) then
  614. return;
  615. end
  616. AchievementFrame_LoadUI();
  617. AchievementFrame_DisplayComparison(unit);
  618. end
  619. function ToggleAchievementFrame(stats)
  620. if (IsKioskModeEnabled()) then
  621. return;
  622. end
  623. if ( ( HasCompletedAnyAchievement() or IsInGuild() ) and CanShowAchievementUI() ) then
  624. AchievementFrame_LoadUI();
  625. AchievementFrame_ToggleAchievementFrame(stats);
  626. end
  627. end
  628. function ToggleTalentFrame(suggestedTab)
  629. if (UnitLevel("player") < SHOW_SPEC_LEVEL) then
  630. return;
  631. end
  632. TalentFrame_LoadUI();
  633. if ( PlayerTalentFrame_Toggle ) then
  634. PlayerTalentFrame_Toggle(suggestedTab);
  635. end
  636. end
  637. function ToggleBattlefieldMap()
  638. BattlefieldMap_LoadUI();
  639. if ( BattlefieldMapFrame ) then
  640. BattlefieldMapFrame:Toggle();
  641. end
  642. end
  643. function ToggleTimeManager()
  644. TimeManager_LoadUI();
  645. if ( TimeManager_Toggle ) then
  646. TimeManager_Toggle();
  647. end
  648. end
  649. function ToggleCalendar()
  650. if (IsKioskModeEnabled()) then
  651. return;
  652. end
  653. Calendar_LoadUI();
  654. if ( Calendar_Toggle ) then
  655. Calendar_Toggle();
  656. end
  657. end
  658. function IsCommunitiesUIDisabledByTrialAccount()
  659. return IsTrialAccount();
  660. end
  661. function ToggleGuildFrame()
  662. if (IsKioskModeEnabled()) then
  663. return;
  664. end
  665. local factionGroup = UnitFactionGroup("player");
  666. if (factionGroup == "Neutral") then
  667. return;
  668. end
  669. if ( IsCommunitiesUIDisabledByTrialAccount() ) then
  670. UIErrorsFrame:AddMessage(ERR_RESTRICTED_ACCOUNT_TRIAL, 1.0, 0.1, 0.1, 1.0);
  671. return;
  672. elseif ( CommunitiesFrame_IsEnabled() ) then
  673. if ( not BNConnected() ) then
  674. UIErrorsFrame:AddMessage(ERR_GUILD_AND_COMMUNITIES_UNAVAILABLE, 1.0, 0.1, 0.1, 1.0);
  675. return;
  676. elseif ( C_Club.IsRestricted() ~= Enum.ClubRestrictionReason.None ) then
  677. return;
  678. end
  679. ToggleCommunitiesFrame();
  680. elseif ( IsInGuild() ) then
  681. GuildFrame_LoadUI();
  682. if ( GuildFrame_Toggle ) then
  683. GuildFrame_Toggle();
  684. end
  685. else
  686. ToggleGuildFinder();
  687. end
  688. end
  689. local function ToggleClubFinderBasedOnType(isGuildType)
  690. ToggleCommunitiesFrame();
  691. local communitiesFrame = CommunitiesFrame;
  692. if( not communitiesFrame:IsShown()) then
  693. return;
  694. end
  695. if (isGuildType) then
  696. communitiesFrame:SetDisplayMode(COMMUNITIES_FRAME_DISPLAY_MODES.GUILD_FINDER);
  697. else
  698. communitiesFrame:SetDisplayMode(COMMUNITIES_FRAME_DISPLAY_MODES.COMMUNITY_FINDER);
  699. end
  700. communitiesFrame.GuildFinderFrame.isGuildType = isGuildType;
  701. communitiesFrame.GuildFinderFrame.selectedTab = 1;
  702. communitiesFrame.GuildFinderFrame:UpdateType();
  703. communitiesFrame:SelectClub(nil);
  704. communitiesFrame.Inset:Hide();
  705. end
  706. function ToggleGuildFinder()
  707. if (IsKioskModeEnabled()) then
  708. return;
  709. end
  710. local factionGroup = UnitFactionGroup("player");
  711. if (factionGroup == "Neutral") then
  712. return;
  713. end
  714. ToggleClubFinderBasedOnType(true);
  715. end
  716. function ToggleCommunityFinder()
  717. if (IsKioskModeEnabled()) then
  718. return;
  719. end
  720. local factionGroup = UnitFactionGroup("player");
  721. if (factionGroup == "Neutral") then
  722. return;
  723. end
  724. ToggleClubFinderBasedOnType(false);
  725. end
  726. function ToggleLFDParentFrame()
  727. if (IsKioskModeEnabled()) then
  728. return;
  729. end
  730. local factionGroup = UnitFactionGroup("player");
  731. if (factionGroup == "Neutral") then
  732. return;
  733. end
  734. if ( UnitLevel("player") >= math.min(SHOW_LFD_LEVEL,SHOW_PVP_LEVEL) ) then
  735. PVEFrame_ToggleFrame("GroupFinderFrame", LFDParentFrame);
  736. end
  737. end
  738. function ToggleHelpFrame()
  739. if (IsKioskModeEnabled()) then
  740. return;
  741. end
  742. if ( HelpFrame:IsShown() ) then
  743. HideUIPanel(HelpFrame);
  744. else
  745. StaticPopup_Hide("HELP_TICKET");
  746. StaticPopup_Hide("HELP_TICKET_ABANDON_CONFIRM");
  747. StaticPopup_Hide("GM_RESPONSE_NEED_MORE_HELP");
  748. StaticPopup_Hide("GM_RESPONSE_RESOLVE_CONFIRM");
  749. StaticPopup_Hide("GM_RESPONSE_MUST_RESOLVE_RESPONSE");
  750. HelpFrame_ShowFrame();
  751. end
  752. end
  753. function ToggleRaidFrame()
  754. if (IsKioskModeEnabled()) then
  755. return;
  756. end
  757. local factionGroup = UnitFactionGroup("player");
  758. if (factionGroup == "Neutral") then
  759. return;
  760. end
  761. ToggleFriendsFrame(FRIEND_TAB_RAID);
  762. end
  763. function ToggleRaidBrowser()
  764. if (IsKioskModeEnabled()) then
  765. return;
  766. end
  767. local factionGroup = UnitFactionGroup("player");
  768. if (factionGroup == "Neutral") then
  769. return;
  770. end
  771. if ( RaidBrowserFrame:IsShown() ) then
  772. HideUIPanel(RaidBrowserFrame);
  773. else
  774. ShowUIPanel(RaidBrowserFrame);
  775. end
  776. end
  777. function CanShowEncounterJournal()
  778. if ( not C_AdventureJournal.CanBeShown() ) then
  779. return false;
  780. end
  781. return true;
  782. end
  783. function ToggleEncounterJournal()
  784. if ( not CanShowEncounterJournal() ) then
  785. return false;
  786. end
  787. if ( not EncounterJournal ) then
  788. EncounterJournal_LoadUI();
  789. end
  790. if ( EncounterJournal ) then
  791. ToggleFrame(EncounterJournal);
  792. return true;
  793. end
  794. return false;
  795. end
  796. function ToggleCommunitiesFrame()
  797. Communities_LoadUI();
  798. ToggleFrame(CommunitiesFrame);
  799. end
  800. function CommunitiesFrame_IsEnabled()
  801. return C_Club.IsEnabled();
  802. end
  803. COLLECTIONS_JOURNAL_TAB_INDEX_MOUNTS = 1;
  804. COLLECTIONS_JOURNAL_TAB_INDEX_PETS = COLLECTIONS_JOURNAL_TAB_INDEX_MOUNTS + 1;
  805. COLLECTIONS_JOURNAL_TAB_INDEX_TOYS = COLLECTIONS_JOURNAL_TAB_INDEX_PETS + 1;
  806. COLLECTIONS_JOURNAL_TAB_INDEX_HEIRLOOMS = COLLECTIONS_JOURNAL_TAB_INDEX_TOYS + 1;
  807. COLLECTIONS_JOURNAL_TAB_INDEX_APPEARANCES = COLLECTIONS_JOURNAL_TAB_INDEX_HEIRLOOMS + 1;
  808. function ToggleCollectionsJournal(tabIndex)
  809. if CollectionsJournal then
  810. local tabMatches = not tabIndex or tabIndex == PanelTemplates_GetSelectedTab(CollectionsJournal);
  811. local isShown = CollectionsJournal:IsShown() and tabMatches;
  812. SetCollectionsJournalShown(not isShown, tabIndex);
  813. else
  814. SetCollectionsJournalShown(true, tabIndex);
  815. end
  816. end
  817. function SetCollectionsJournalShown(shown, tabIndex)
  818. if not CollectionsJournal then
  819. CollectionsJournal_LoadUI();
  820. end
  821. if CollectionsJournal then
  822. if shown then
  823. ShowUIPanel(CollectionsJournal);
  824. if tabIndex then
  825. CollectionsJournal_SetTab(CollectionsJournal, tabIndex);
  826. end
  827. else
  828. HideUIPanel(CollectionsJournal);
  829. end
  830. end
  831. end
  832. function ToggleToyCollection(autoPageToCollectedToyID)
  833. CollectionsJournal_LoadUI();
  834. ToyBox.autoPageToCollectedToyID = autoPageToCollectedToyID;
  835. SetCollectionsJournalShown(true, COLLECTIONS_JOURNAL_TAB_INDEX_TOYS);
  836. end
  837. function TogglePVPUI()
  838. if (IsKioskModeEnabled()) then
  839. return;
  840. end
  841. if ( UnitLevel("player") >= math.min(SHOW_LFD_LEVEL,SHOW_PVP_LEVEL) ) then
  842. PVEFrame_ToggleFrame("PVPUIFrame", nil);
  843. end
  844. end
  845. function ToggleStoreUI()
  846. if (IsKioskModeEnabled()) then
  847. return;
  848. end
  849. Store_LoadUI();
  850. local wasShown = StoreFrame_IsShown();
  851. if ( not wasShown ) then
  852. --We weren't showing, now we are. We should hide all other panels.
  853. securecall("CloseAllWindows");
  854. end
  855. StoreFrame_SetShown(not wasShown);
  856. end
  857. function SetStoreUIShown(shown)
  858. if (IsKioskModeEnabled()) then
  859. return;
  860. end
  861. Store_LoadUI();
  862. local wasShown = StoreFrame_IsShown();
  863. if ( not wasShown and shown ) then
  864. --We weren't showing, now we are. We should hide all other panels.
  865. securecall("CloseAllWindows");
  866. end
  867. StoreFrame_SetShown(shown);
  868. end
  869. function ToggleGarrisonBuildingUI()
  870. if (not GarrisonBuildingFrame) then
  871. Garrison_LoadUI();
  872. end
  873. GarrisonBuildingUI_ToggleFrame();
  874. end
  875. function ToggleGarrisonMissionUI()
  876. if (not GarrisonMissionFrame) then
  877. Garrison_LoadUI();
  878. end
  879. GarrisonMissionFrame_ToggleFrame();
  880. end
  881. function ToggleOrderHallTalentUI()
  882. if (not OrderHallTalentFrame) then
  883. OrderHall_LoadUI();
  884. end
  885. OrderHallTalentFrame_ToggleFrame();
  886. end
  887. function OpenDeathRecapUI(id)
  888. if (not DeathRecapFrame) then
  889. DeathRecap_LoadUI();
  890. end
  891. DeathRecapFrame_OpenRecap(id);
  892. end
  893. function InspectUnit(unit)
  894. InspectFrame_LoadUI();
  895. if ( InspectFrame_Show ) then
  896. InspectFrame_Show(unit);
  897. end
  898. end
  899. function OpenAzeriteEmpoweredItemUIFromItemLocation(itemLocation)
  900. UIParentLoadAddOn("Blizzard_AzeriteUI");
  901. ShowUIPanel(AzeriteEmpoweredItemUI);
  902. if AzeriteEmpoweredItemUI:IsShown() then -- may fail to display
  903. AzeriteEmpoweredItemUI:SetToItemAtLocation(itemLocation);
  904. end
  905. end
  906. function OpenAzeriteEmpoweredItemUIFromLink(itemLink, overrideClassID, overrideSelectedPowersList)
  907. UIParentLoadAddOn("Blizzard_AzeriteUI");
  908. ShowUIPanel(AzeriteEmpoweredItemUI);
  909. if AzeriteEmpoweredItemUI:IsShown() then -- may fail to display
  910. AzeriteEmpoweredItemUI:SetToItemLink(itemLink, overrideClassID, overrideSelectedPowersList);
  911. end
  912. end
  913. function OpenAzeriteEssenceUIFromItemLocation(itemLocation)
  914. UIParentLoadAddOn("Blizzard_AzeriteEssenceUI");
  915. if AzeriteEssenceUI then
  916. AzeriteEssenceUI:TryShow();
  917. end
  918. end
  919. local function PlayBattlefieldBanner(self)
  920. -- battlefields
  921. if ( not self.battlefieldBannerShown ) then
  922. local bannerName, bannerDescription;
  923. if (C_PvP.IsInBrawl()) then
  924. local brawlInfo = C_PvP.GetActiveBrawlInfo();
  925. if (brawlInfo) then
  926. bannerName = brawlInfo.name;
  927. bannerDescription = brawlInfo.shortDescription;
  928. end
  929. else
  930. for i=1, GetMaxBattlefieldID() do
  931. local status, mapName, _, _, _, _, _, _, _, shortDescription, _ = GetBattlefieldStatus(i);
  932. if ( status and status == "active" ) then
  933. bannerName = mapName;
  934. bannerDescription = shortDescription;
  935. break;
  936. end
  937. end
  938. end
  939. if ( bannerName ) then
  940. UIParentLoadAddOn("Blizzard_PVPUI");
  941. C_Timer.After(1, function() TopBannerManager_Show(PvPObjectiveBannerFrame, { name=bannerName, description=bannerDescription }); end);
  942. self.battlefieldBannerShown = true;
  943. end
  944. end
  945. end
  946. local function HandlesGlobalMouseEvent(focus, buttonID, event)
  947. return focus and focus.HandlesGlobalMouseEvent and focus:HandlesGlobalMouseEvent(buttonID, event);
  948. end
  949. local function HasVisibleAutoCompleteBox(autoCompleteBoxList, mouseFocus)
  950. for i, box in ipairs(autoCompleteBoxList) do
  951. if box:IsShown() and DoesAncestryInclude(box, mouseFocus) then
  952. return true;
  953. end
  954. end
  955. return false;
  956. end
  957. -- UIParent_OnEvent --
  958. function UIParent_OnEvent(self, event, ...)
  959. local arg1, arg2, arg3, arg4, arg5, arg6 = ...;
  960. if ( event == "CURRENT_SPELL_CAST_CHANGED" ) then
  961. if ( SpellCanTargetGarrisonFollower(0) or SpellCanTargetGarrisonFollowerAbility(0, 0) ) then
  962. local followerTypeID = GetFollowerTypeIDFromSpell();
  963. local frame = _G[GarrisonFollowerOptions[followerTypeID].missionFrame];
  964. if (frame and frame:IsShown()) then
  965. if ( (not C_Garrison.TargetSpellHasFollowerTemporaryAbility() or not frame:HasMission()) and PanelTemplates_GetSelectedTab(frame) ~= 2 ) then
  966. frame:SelectTab(2)
  967. end
  968. else
  969. local landingPageTabIndex;
  970. local garrTypeID = GarrisonFollowerOptions[followerTypeID].garrisonType;
  971. if (C_Garrison.HasGarrison(garrTypeID)) then
  972. if (followerTypeID == LE_FOLLOWER_TYPE_SHIPYARD_6_2) then
  973. landingPageTabIndex = 3;
  974. else
  975. landingPageTabIndex = 2;
  976. end
  977. ShowGarrisonLandingPage(garrTypeID);
  978. -- switch to the followers tab
  979. if ( PanelTemplates_GetSelectedTab(GarrisonLandingPage) ~= landingPageTabIndex ) then
  980. GarrisonLandingPageTab_SetTab(_G["GarrisonLandingPageTab"..landingPageTabIndex]);
  981. end
  982. end
  983. end
  984. end
  985. if ( SpellCanTargetGarrisonMission() ) then
  986. -- TODO: Determine garrison/follower mission type for this spell
  987. if ( not GarrisonLandingPage ) then
  988. Garrison_LoadUI();
  989. end
  990. -- if the mission UI is already open, go with that
  991. if ( GarrisonMissionFrame:IsShown() ) then
  992. if ( PanelTemplates_GetSelectedTab(GarrisonMissionFrame) ~= 1 ) then
  993. GarrisonMissionFrame_SelectTab(1);
  994. end
  995. if ( PanelTemplates_GetSelectedTab(GarrisonMissionFrame.MissionTab.MissionList) ~= 2 ) then
  996. GarrisonMissionListTab_SetTab(GarrisonMissionFrame.MissionTab.MissionList.Tab2);
  997. end
  998. else
  999. if (C_Garrison.HasGarrison(LE_GARRISON_TYPE_6_0)) then
  1000. ShowGarrisonLandingPage(LE_GARRISON_TYPE_6_0);
  1001. -- switch to the mission tab
  1002. if ( PanelTemplates_GetSelectedTab(GarrisonLandingPage) ~= 1 ) then
  1003. GarrisonLandingPageTab_SetTab(GarrisonLandingPageTab1);
  1004. end
  1005. if ( PanelTemplates_GetSelectedTab(GarrisonLandingPageReport) ~= GarrisonLandingPageReport.InProgress ) then
  1006. GarrisonLandingPageReport_SetTab(GarrisonLandingPageReport.InProgress);
  1007. end
  1008. end
  1009. end
  1010. end
  1011. if ( #StaticPopup_DisplayedFrames > 0 ) then
  1012. if ( arg1 ) then
  1013. StaticPopup_Hide("BIND_ENCHANT");
  1014. StaticPopup_Hide("REPLACE_ENCHANT");
  1015. StaticPopup_Hide("ACTION_WILL_BIND_ITEM");
  1016. end
  1017. StaticPopup_Hide("TRADE_REPLACE_ENCHANT");
  1018. StaticPopup_Hide("END_BOUND_TRADEABLE");
  1019. if ( not SpellCanTargetGarrisonFollower(0) ) then
  1020. StaticPopup_Hide("CONFIRM_FOLLOWER_UPGRADE");
  1021. StaticPopup_Hide("CONFIRM_FOLLOWER_TEMPORARY_ABILITY");
  1022. end
  1023. end
  1024. ItemButtonUtil.TriggerEvent(ItemButtonUtil.Event.ItemContextChanged);
  1025. elseif ( event == "VARIABLES_LOADED" ) then
  1026. UIParent.variablesLoaded = true;
  1027. LocalizeFrames();
  1028. if ( not TimeManagerFrame and GetCVar("timeMgrAlarmEnabled") == "1" ) then
  1029. -- We have to load the time manager here if the alarm is enabled because the alarm can go off
  1030. -- even if the clock is not shown. WorldFrame_OnUpdate handles alarm checking while the clock
  1031. -- is hidden.
  1032. TimeManager_LoadUI();
  1033. end
  1034. if ( not BattlefieldMapFrame and GetCVar("showBattlefieldMinimap") == "1" ) then
  1035. BattlefieldMap_LoadUI();
  1036. end
  1037. local lastTalkedToGM = GetCVar("lastTalkedToGM");
  1038. if ( lastTalkedToGM ~= "" ) then
  1039. GMChatFrame_LoadUI();
  1040. GMChatFrame:Show()
  1041. local info = ChatTypeInfo["WHISPER"];
  1042. GMChatFrame:AddMessage(format(GM_CHAT_LAST_SESSION, "|TInterface\\ChatFrame\\UI-ChatIcon-Blizz:12:20:0:0:32:16:4:28:0:16|t "..
  1043. GetGMLink(lastTalkedToGM, "["..lastTalkedToGM.."]")), info.r, info.g, info.b, info.id);
  1044. GMChatFrameEditBox:SetAttribute("tellTarget", lastTalkedToGM);
  1045. GMChatFrameEditBox:SetAttribute("chatType", "WHISPER");
  1046. end
  1047. TargetFrame_OnVariablesLoaded();
  1048. NPETutorial_AttemptToBegin(event);
  1049. StoreFrame_CheckForFree(event);
  1050. elseif ( event == "PLAYER_LOGIN" ) then
  1051. TimeManager_LoadUI();
  1052. -- You can override this if you want a Combat Log replacement
  1053. CombatLog_LoadUI();
  1054. elseif ( event == "PLAYER_DEAD" ) then
  1055. if ( not StaticPopup_Visible("DEATH") ) then
  1056. CloseAllWindows(1);
  1057. end
  1058. if ( (GetReleaseTimeRemaining() > 0 or GetReleaseTimeRemaining() == -1) and (not ResurrectGetOfferer()) ) then
  1059. StaticPopup_Show("DEATH");
  1060. end
  1061. elseif ( event == "SELF_RES_SPELL_CHANGED" ) then
  1062. if ( StaticPopup_Visible("DEATH") ) then
  1063. StaticPopup_Show("DEATH"); --If we're already showing a death prompt, we should refresh it.
  1064. end
  1065. elseif ( event == "PLAYER_ALIVE" or event == "RAISED_AS_GHOUL" ) then
  1066. StaticPopup_Hide("DEATH");
  1067. StaticPopup_Hide("RESURRECT_NO_SICKNESS");
  1068. StaticPopup_Hide("RESURRECT_NO_TIMER");
  1069. StaticPopup_Hide("RESURRECT");
  1070. if ( UnitIsGhost("player") ) then
  1071. GhostFrame:Show();
  1072. else
  1073. GhostFrame:Hide();
  1074. end
  1075. elseif ( event == "PLAYER_UNGHOST" ) then
  1076. StaticPopup_Hide("RESURRECT");
  1077. StaticPopup_Hide("RESURRECT_NO_SICKNESS");
  1078. StaticPopup_Hide("RESURRECT_NO_TIMER");
  1079. StaticPopup_Hide("SKINNED");
  1080. StaticPopup_Hide("SKINNED_REPOP");
  1081. GhostFrame:Hide();
  1082. elseif ( event == "RESURRECT_REQUEST" ) then
  1083. ShowResurrectRequest(arg1);
  1084. elseif ( event == "PLAYER_SKINNED" ) then
  1085. StaticPopup_Hide("RESURRECT");
  1086. StaticPopup_Hide("RESURRECT_NO_SICKNESS");
  1087. StaticPopup_Hide("RESURRECT_NO_TIMER");
  1088. --[[
  1089. if (arg1 == 1) then
  1090. StaticPopup_Show("SKINNED_REPOP");
  1091. else
  1092. StaticPopup_Show("SKINNED");
  1093. end
  1094. ]]
  1095. UIErrorsFrame:AddMessage(DEATH_CORPSE_SKINNED, 1.0, 0.1, 0.1, 1.0);
  1096. elseif ( event == "TRADE_REQUEST" ) then
  1097. StaticPopup_Show("TRADE", arg1);
  1098. elseif ( event == "CHANNEL_INVITE_REQUEST" ) then
  1099. if ( GetCVarBool("blockChannelInvites") ) then
  1100. DeclineChannelInvite(arg1);
  1101. else
  1102. local dialog = StaticPopup_Show("CHAT_CHANNEL_INVITE", arg1, arg2);
  1103. if ( dialog ) then
  1104. dialog.data = arg1;
  1105. end
  1106. end
  1107. elseif ( event == "CHANNEL_PASSWORD_REQUEST" ) then
  1108. local dialog = StaticPopup_Show("CHAT_CHANNEL_PASSWORD", arg1);
  1109. if ( dialog ) then
  1110. dialog.data = arg1;
  1111. end
  1112. elseif ( event == "PARTY_INVITE_REQUEST" ) then
  1113. FlashClientIcon();
  1114. local name, tank, healer, damage, isXRealm, allowMultipleRoles, inviterGuid, isQuestSessionActive = ...;
  1115. -- Color the name by our relationship
  1116. local modifiedName, color, selfRelationship = SocialQueueUtil_GetRelationshipInfo(inviterGuid);
  1117. if ( selfRelationship ) then
  1118. name = color..name..FONT_COLOR_CODE_CLOSE;
  1119. end
  1120. -- if there's a role, it's an LFG invite
  1121. if ( tank or healer or damage ) then
  1122. StaticPopupSpecial_Show(LFGInvitePopup);
  1123. LFGInvitePopup_Update(name, tank, healer, damage, allowMultipleRoles, isQuestSessionActive);
  1124. else
  1125. local text = isXRealm and INVITATION_XREALM or INVITATION;
  1126. text = string.format(text, name);
  1127. if ( WillAcceptInviteRemoveQueues() ) then
  1128. text = text.."\n\n"..ACCEPTING_INVITE_WILL_REMOVE_QUEUE;
  1129. end
  1130. if isQuestSessionActive then
  1131. QuestSessionManager:ShowGroupInviteReceivedConfirmation(name, text);
  1132. else
  1133. StaticPopup_Show("PARTY_INVITE", text);
  1134. end
  1135. end
  1136. elseif ( event == "PARTY_INVITE_CANCEL" ) then
  1137. StaticPopup_Hide("PARTY_INVITE");
  1138. StaticPopupSpecial_Hide(LFGInvitePopup);
  1139. elseif ( event == "GUILD_INVITE_REQUEST" ) then
  1140. StaticPopup_Show("GUILD_INVITE", arg1, arg2);
  1141. elseif ( event == "GUILD_INVITE_CANCEL" ) then
  1142. StaticPopup_Hide("GUILD_INVITE");
  1143. elseif ( event == "PLAYER_CAMPING" ) then
  1144. StaticPopup_Show("CAMP");
  1145. elseif ( event == "PLAYER_QUITING" ) then
  1146. StaticPopup_Show("QUIT");
  1147. elseif ( event == "LOGOUT_CANCEL" ) then
  1148. StaticPopup_Hide("CAMP");
  1149. StaticPopup_Hide("QUIT");
  1150. elseif ( event == "LOOT_BIND_CONFIRM" ) then
  1151. local texture, item, quantity, currencyID, quality, locked = GetLootSlotInfo(arg1);
  1152. local dialog = StaticPopup_Show("LOOT_BIND", ITEM_QUALITY_COLORS[quality].hex..item.."|r");
  1153. if ( dialog ) then
  1154. dialog.data = arg1;
  1155. end
  1156. elseif ( event == "EQUIP_BIND_CONFIRM" ) then
  1157. StaticPopup_Hide("EQUIP_BIND_TRADEABLE");
  1158. local dialog = StaticPopup_Show("EQUIP_BIND");
  1159. if ( dialog ) then
  1160. dialog.data = arg1;
  1161. end
  1162. elseif ( event == "EQUIP_BIND_TRADEABLE_CONFIRM" ) then
  1163. StaticPopup_Hide("EQUIP_BIND");
  1164. local dialog = StaticPopup_Show("EQUIP_BIND_TRADEABLE");
  1165. if ( dialog ) then
  1166. dialog.data = arg1;
  1167. end
  1168. elseif ( event == "USE_BIND_CONFIRM" ) then
  1169. StaticPopup_Show("USE_BIND");
  1170. elseif( event == "USE_NO_REFUND_CONFIRM" )then
  1171. StaticPopup_Show("USE_NO_REFUND_CONFIRM");
  1172. elseif ( event == "CONFIRM_BEFORE_USE" ) then
  1173. StaticPopup_Show("CONFIM_BEFORE_USE");
  1174. elseif ( event == "DELETE_ITEM_CONFIRM" ) then
  1175. -- Check quality, ignore heirlooms
  1176. if ( arg2 >= LE_ITEM_QUALITY_RARE and arg2 ~= LE_ITEM_QUALITY_HEIRLOOM ) then
  1177. if (arg4 == 1) then -- quest item?
  1178. StaticPopup_Show("DELETE_GOOD_QUEST_ITEM", arg1);
  1179. else
  1180. StaticPopup_Show("DELETE_GOOD_ITEM", arg1);
  1181. end
  1182. else
  1183. if (arg4 == 1) then -- quest item?
  1184. StaticPopup_Show("DELETE_QUEST_ITEM", arg1);
  1185. else
  1186. StaticPopup_Show("DELETE_ITEM", arg1);
  1187. end
  1188. end
  1189. elseif ( event == "QUEST_ACCEPT_CONFIRM" ) then
  1190. local numEntries, numQuests = GetNumQuestLogEntries();
  1191. if( numQuests >= MAX_QUESTS) then
  1192. StaticPopup_Show("QUEST_ACCEPT_LOG_FULL", arg1, arg2);
  1193. else
  1194. StaticPopup_Show("QUEST_ACCEPT", arg1, arg2);
  1195. end
  1196. elseif ( event =="QUEST_LOG_UPDATE" or event == "UNIT_QUEST_LOG_CHANGED" ) then
  1197. local frameName = StaticPopup_Visible("QUEST_ACCEPT_LOG_FULL");
  1198. if( frameName ) then
  1199. local numEntries, numQuests = GetNumQuestLogEntries();
  1200. local button = _G[frameName.."Button1"];
  1201. if( numQuests < MAX_QUESTS ) then
  1202. button:Enable();
  1203. else
  1204. button:Disable();
  1205. end
  1206. end
  1207. elseif ( event == "CURSOR_UPDATE" ) then
  1208. if ( not CursorHasItem() ) then
  1209. StaticPopup_Hide("EQUIP_BIND");
  1210. StaticPopup_Hide("EQUIP_BIND_TRADEABLE");
  1211. end
  1212. elseif ( event == "PLAYER_ENTERING_WORLD" ) then
  1213. -- Get multi-actionbar states (before CloseAllWindows() since that may be hooked by AddOns)
  1214. -- We don't want to call this, as the values GetActionBarToggles() returns are incorrect if it's called before the client mirrors SetActionBarToggles values from the server.
  1215. -- SHOW_MULTI_ACTIONBAR_1, SHOW_MULTI_ACTIONBAR_2, SHOW_MULTI_ACTIONBAR_3, SHOW_MULTI_ACTIONBAR_4 = GetActionBarToggles();
  1216. MultiActionBar_Update();
  1217. -- Close any windows that were previously open
  1218. CloseAllWindows(1);
  1219. UpdateMicroButtons();
  1220. -- Fix for Bug 124392
  1221. StaticPopup_Hide("CONFIRM_LEAVE_BATTLEFIELD");
  1222. local _, instanceType = IsInInstance();
  1223. if ( instanceType == "arena" or instanceType == "pvp") then
  1224. Arena_LoadUI();
  1225. end
  1226. if ( C_Commentator.IsSpectating() ) then
  1227. Commentator_LoadUI();
  1228. end
  1229. if ( UnitIsGhost("player") ) then
  1230. GhostFrame:Show();
  1231. else
  1232. GhostFrame:Hide();
  1233. end
  1234. if ( GetReleaseTimeRemaining() > 0 or GetReleaseTimeRemaining() == -1 ) then
  1235. StaticPopup_Show("DEATH");
  1236. end
  1237. local alreadyShowingSummonPopup = StaticPopup_Visible("CONFIRM_SUMMON_STARTING_AREA") or StaticPopup_Visible("CONFIRM_SUMMON_SCENARIO") or StaticPopup_Visible("CONFIRM_SUMMON")
  1238. if ( not alreadyShowingSummonPopup and C_SummonInfo.GetSummonConfirmTimeLeft() > 0 ) then
  1239. local summonReason = C_SummonInfo.GetSummonReason();
  1240. local isSkippingStartingArea = C_SummonInfo.IsSummonSkippingStartExperience();
  1241. if ( isSkippingStartingArea ) then -- check if skiping start experience
  1242. StaticPopup_Show("CONFIRM_SUMMON_STARTING_AREA");
  1243. elseif (summonType == LE_SUMMON_REASON_SCENARIO) then
  1244. StaticPopup_Show("CONFIRM_SUMMON_SCENARIO");
  1245. else
  1246. StaticPopup_Show("CONFIRM_SUMMON");
  1247. end
  1248. end
  1249. -- display loot specialization setting
  1250. PrintLootSpecialization();
  1251. UpdateUIParentRelativeToDebugMenu();
  1252. --Bonus roll/spell confirmation.
  1253. local spellConfirmations = GetSpellConfirmationPromptsInfo();
  1254. for i, spellConfirmation in ipairs(spellConfirmations) do
  1255. if spellConfirmation.spellID then
  1256. if spellConfirmation.confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_STATIC_TEXT then
  1257. StaticPopup_Show("SPELL_CONFIRMATION_PROMPT", spellConfirmation.text, spellConfirmation.duration, spellConfirmation.spellID);
  1258. elseif spellConfirmation.confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_SIMPLE_WARNING then
  1259. StaticPopup_Show("SPELL_CONFIRMATION_WARNING", spellConfirmation.text, nil, spellConfirmation.spellID);
  1260. elseif spellConfirmation.confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_BONUS_ROLL then
  1261. BonusRollFrame_StartBonusRoll(spellConfirmation.spellID, spellConfirmation.text, spellConfirmation.duration, spellConfirmation.currencyID, spellConfirmation.currencyCost, spellConfirmation.difficultyID);
  1262. end
  1263. end
  1264. end
  1265. local resurrectOfferer = ResurrectGetOfferer();
  1266. if resurrectOfferer then
  1267. ShowResurrectRequest(resurrectOfferer);
  1268. end
  1269. --Group Loot Roll Windows.
  1270. local pendingLootRollIDs = GetActiveLootRollIDs();
  1271. for i=1, #pendingLootRollIDs do
  1272. GroupLootFrame_OpenNewFrame(pendingLootRollIDs[i], GetLootRollTimeLeft(pendingLootRollIDs[i]));
  1273. end
  1274. OrderHall_CheckCommandBar();
  1275. self.battlefieldBannerShown = nil;
  1276. NPETutorial_AttemptToBegin(event);
  1277. ClassTrial_AttemptLoad();
  1278. BoostTutorial_AttemptLoad();
  1279. elseif ( event == "UPDATE_BATTLEFIELD_STATUS" or event == "PVP_BRAWL_INFO_UPDATED" ) then
  1280. PlayBattlefieldBanner(self);
  1281. elseif ( event == "GROUP_ROSTER_UPDATE" ) then
  1282. -- Hide/Show party member frames
  1283. RaidOptionsFrame_UpdatePartyFrames();
  1284. if ( not IsInGroup(LE_PARTY_CATEGORY_INSTANCE) ) then
  1285. StaticPopup_Hide("CONFIRM_LEAVE_INSTANCE_PARTY");
  1286. end
  1287. elseif ( event == "MIRROR_TIMER_START" ) then
  1288. MirrorTimer_Show(arg1, arg2, arg3, arg4, arg5, arg6);
  1289. elseif ( event == "DUEL_REQUESTED" ) then
  1290. StaticPopup_Show("DUEL_REQUESTED", arg1);
  1291. elseif ( event == "DUEL_OUTOFBOUNDS" ) then
  1292. StaticPopup_Show("DUEL_OUTOFBOUNDS");
  1293. elseif ( event == "DUEL_INBOUNDS" ) then
  1294. StaticPopup_Hide("DUEL_OUTOFBOUNDS");
  1295. elseif ( event == "DUEL_FINISHED" ) then
  1296. StaticPopup_Hide("DUEL_REQUESTED");
  1297. StaticPopup_Hide("DUEL_OUTOFBOUNDS");
  1298. elseif ( event == "PET_BATTLE_PVP_DUEL_REQUESTED" ) then
  1299. StaticPopup_Show("PET_BATTLE_PVP_DUEL_REQUESTED", arg1);
  1300. elseif ( event == "PET_BATTLE_PVP_DUEL_REQUEST_CANCEL" ) then
  1301. StaticPopup_Hide("PET_BATTLE_PVP_DUEL_REQUESTED");
  1302. elseif ( event == "PET_BATTLE_QUEUE_PROPOSE_MATCH" ) then
  1303. PlaySound(SOUNDKIT.UI_PET_BATTLES_PVP_THROUGH_QUEUE);
  1304. StaticPopupSpecial_Show(PetBattleQueueReadyFrame);
  1305. elseif ( event == "PET_BATTLE_QUEUE_PROPOSAL_DECLINED" or event == "PET_BATTLE_QUEUE_PROPOSAL_ACCEPTED" ) then
  1306. StaticPopupSpecial_Hide(PetBattleQueueReadyFrame);
  1307. elseif ( event == "TRADE_REQUEST_CANCEL" ) then
  1308. StaticPopup_Hide("TRADE");
  1309. elseif ( event == "CONFIRM_XP_LOSS" ) then
  1310. local resSicknessTime = GetResSicknessDuration();
  1311. if ( resSicknessTime ) then
  1312. local dialog = nil;
  1313. if (UnitLevel("player") <= 10) then
  1314. dialog = StaticPopup_Show("XP_LOSS_NO_DURABILITY", resSicknessTime);
  1315. else
  1316. dialog = StaticPopup_Show("XP_LOSS", resSicknessTime);
  1317. end
  1318. if ( dialog ) then
  1319. dialog.data = resSicknessTime;
  1320. end
  1321. else
  1322. local dialog = nil;
  1323. if (UnitLevel("player") <= 10) then
  1324. dialog = StaticPopup_Show("XP_LOSS_NO_SICKNESS_NO_DURABILITY");
  1325. else
  1326. dialog = StaticPopup_Show("XP_LOSS_NO_SICKNESS");
  1327. end
  1328. if ( dialog ) then
  1329. dialog.data = 1;
  1330. end
  1331. end
  1332. HideUIPanel(GossipFrame);
  1333. elseif ( event == "CORPSE_IN_RANGE" ) then
  1334. StaticPopup_Show("RECOVER_CORPSE");
  1335. elseif ( event == "CORPSE_IN_INSTANCE" ) then
  1336. StaticPopup_Show("RECOVER_CORPSE_INSTANCE");
  1337. elseif ( event == "CORPSE_OUT_OF_RANGE" ) then
  1338. StaticPopup_Hide("RECOVER_CORPSE");
  1339. StaticPopup_Hide("RECOVER_CORPSE_INSTANCE");
  1340. StaticPopup_Hide("XP_LOSS");
  1341. elseif ( event == "AREA_SPIRIT_HEALER_IN_RANGE" ) then
  1342. AcceptAreaSpiritHeal();
  1343. StaticPopup_Show("AREA_SPIRIT_HEAL");
  1344. elseif ( event == "AREA_SPIRIT_HEALER_OUT_OF_RANGE" ) then
  1345. StaticPopup_Hide("AREA_SPIRIT_HEAL");
  1346. elseif (event == "ACTION_WILL_BIND_ITEM") then
  1347. StaticPopup_Show("ACTION_WILL_BIND_ITEM");
  1348. elseif ( event == "BIND_ENCHANT" ) then
  1349. StaticPopup_Show("BIND_ENCHANT");
  1350. elseif ( event == "REPLACE_ENCHANT" ) then
  1351. StaticPopup_Show("REPLACE_ENCHANT", arg1, arg2);
  1352. elseif ( event == "TRADE_REPLACE_ENCHANT" ) then
  1353. StaticPopup_Show("TRADE_REPLACE_ENCHANT", arg1, arg2);
  1354. elseif ( event == "END_BOUND_TRADEABLE" ) then
  1355. local dialog = StaticPopup_Show("END_BOUND_TRADEABLE", nil, nil, arg1);
  1356. elseif ( event == "MACRO_ACTION_BLOCKED" or event == "ADDON_ACTION_BLOCKED" ) then
  1357. DisplayInterfaceActionBlockedMessage();
  1358. elseif ( event == "MACRO_ACTION_FORBIDDEN" ) then
  1359. StaticPopup_Show("MACRO_ACTION_FORBIDDEN");
  1360. elseif ( event == "ADDON_ACTION_FORBIDDEN" ) then
  1361. local dialog = StaticPopup_Show("ADDON_ACTION_FORBIDDEN", arg1);
  1362. if ( dialog ) then
  1363. dialog.data = arg1;
  1364. end
  1365. elseif ( event == "PLAYER_CONTROL_LOST" ) then
  1366. if ( UnitOnTaxi("player") ) then
  1367. return;
  1368. end
  1369. CloseAllWindows_WithExceptions();
  1370. --[[
  1371. -- Disable all microbuttons except the main menu
  1372. SetDesaturation(MicroButtonPortrait, true);
  1373. Designers previously wanted these disabled when feared, they seem to have changed their minds
  1374. CharacterMicroButton:Disable();
  1375. SpellbookMicroButton:Disable();
  1376. TalentMicroButton:Disable();
  1377. QuestLogMicroButton:Disable();
  1378. GuildMicroButton:Disable();
  1379. WorldMapMicroButton:Disable();
  1380. ]]
  1381. UIParent.isOutOfControl = 1;
  1382. elseif ( event == "PLAYER_CONTROL_GAINED" ) then
  1383. --[[
  1384. -- Enable all microbuttons
  1385. SetDesaturation(MicroButtonPortrait, false);
  1386. CharacterMicroButton:Enable();
  1387. SpellbookMicroButton:Enable();
  1388. TalentMicroButton:Enable();
  1389. QuestLogMicroButton:Enable();
  1390. GuildMicroButton:Enable();
  1391. WorldMapMicroButton:Enable();
  1392. ]]
  1393. UIParent.isOutOfControl = nil;
  1394. elseif ( event == "START_LOOT_ROLL" ) then
  1395. GroupLootFrame_OpenNewFrame(arg1, arg2);
  1396. elseif ( event == "CONFIRM_LOOT_ROLL" ) then
  1397. local texture, name, count, quality, bindOnPickUp = GetLootRollItemInfo(arg1);
  1398. local dialog = StaticPopup_Show("CONFIRM_LOOT_ROLL", ITEM_QUALITY_COLORS[quality].hex..name.."|r");
  1399. if ( dialog ) then
  1400. dialog.text:SetFormattedText(arg3, ITEM_QUALITY_COLORS[quality].hex..name.."|r");
  1401. StaticPopup_Resize(dialog, "CONFIRM_LOOT_ROLL");
  1402. dialog.data = arg1;
  1403. dialog.data2 = arg2;
  1404. end
  1405. elseif ( event == "SPELL_CONFIRMATION_PROMPT" ) then
  1406. local spellID, confirmType, text, duration, currencyID, currencyCost, difficultyID = ...;
  1407. if ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_STATIC_TEXT ) then
  1408. StaticPopup_Show("SPELL_CONFIRMATION_PROMPT", text, duration, spellID);
  1409. elseif ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_SIMPLE_WARNING ) then
  1410. StaticPopup_Show("SPELL_CONFIRMATION_WARNING", text, nil, spellID);
  1411. elseif ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_BONUS_ROLL ) then
  1412. BonusRollFrame_StartBonusRoll(spellID, text, duration, currencyID, currencyCost, difficultyID);
  1413. end
  1414. elseif ( event == "SPELL_CONFIRMATION_TIMEOUT" ) then
  1415. local spellID, confirmType = ...;
  1416. if ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_STATIC_TEXT ) then
  1417. StaticPopup_Hide("SPELL_CONFIRMATION_PROMPT", spellID);
  1418. elseif ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_SIMPLE_WARNING ) then
  1419. StaticPopup_Hide("SPELL_CONFIRMATION_WARNING", spellID);
  1420. elseif ( confirmType == LE_SPELL_CONFIRMATION_PROMPT_TYPE_BONUS_ROLL ) then
  1421. BonusRollFrame_CloseBonusRoll();
  1422. end
  1423. elseif ( event == "SAVED_VARIABLES_TOO_LARGE" ) then
  1424. local addonName = ...;
  1425. StaticPopup_Show("SAVED_VARIABLES_TOO_LARGE", addonName);
  1426. elseif ( event == "CONFIRM_DISENCHANT_ROLL" ) then
  1427. local texture, name, count, quality, bindOnPickUp = GetLootRollItemInfo(arg1);
  1428. local dialog = StaticPopup_Show("CONFIRM_LOOT_ROLL", ITEM_QUALITY_COLORS[quality].hex..name.."|r");
  1429. if ( dialog ) then
  1430. dialog.text:SetFormattedText(LOOT_NO_DROP_DISENCHANT, ITEM_QUALITY_COLORS[quality].hex..name.."|r");
  1431. StaticPopup_Resize(dialog, "CONFIRM_LOOT_ROLL");
  1432. dialog.data = arg1;
  1433. dialog.data2 = arg2;
  1434. end
  1435. elseif ( event == "INSTANCE_BOOT_START" ) then
  1436. if (C_Garrison.IsOnGarrisonMap()) then
  1437. StaticPopup_Show("GARRISON_BOOT");
  1438. else
  1439. StaticPopup_Show("INSTANCE_BOOT");
  1440. end
  1441. elseif ( event == "INSTANCE_BOOT_STOP" ) then
  1442. StaticPopup_Hide("INSTANCE_BOOT");
  1443. StaticPopup_Hide("GARRISON_BOOT");
  1444. elseif ( event == "INSTANCE_LOCK_START" ) then
  1445. StaticPopup_Show("INSTANCE_LOCK", nil, nil, true);
  1446. elseif ( event == "INSTANCE_LOCK_STOP" ) then
  1447. StaticPopup_Hide("INSTANCE_LOCK");
  1448. elseif ( event == "INSTANCE_LOCK_WARNING" ) then
  1449. StaticPopup_Show("INSTANCE_LOCK", nil, nil, false);
  1450. elseif ( event == "CONFIRM_TALENT_WIPE" ) then
  1451. HideUIPanel(GossipFrame);
  1452. StaticPopupDialogs["CONFIRM_TALENT_WIPE"].text = _G["CONFIRM_TALENT_WIPE_"..arg2];
  1453. local dialog = StaticPopup_Show("CONFIRM_TALENT_WIPE");
  1454. if ( dialog ) then
  1455. MoneyFrame_Update(dialog:GetName().."MoneyFrame", arg1);
  1456. -- open the talent UI to the player's active talent group...just so the player knows
  1457. -- exactly which talent spec he is wiping
  1458. -- TalentFrame_LoadUI();
  1459. -- if ( PlayerTalentFrame_Open ) then
  1460. -- PlayerTalentFrame_Open(GetActiveSpecGroup());
  1461. -- end
  1462. end
  1463. elseif ( event == "CONFIRM_BINDER" ) then
  1464. StaticPopup_Show("CONFIRM_BINDER", arg1);
  1465. elseif ( event == "CONFIRM_SUMMON" ) then
  1466. local summonType, skipStartingArea = arg1, arg2;
  1467. if ( skipStartingArea ) then -- check if skiping start experience
  1468. StaticPopup_Show("CONFIRM_SUMMON_STARTING_AREA");
  1469. elseif (summonType == LE_SUMMON_REASON_SCENARIO) then
  1470. StaticPopup_Show("CONFIRM_SUMMON_SCENARIO");
  1471. else
  1472. StaticPopup_Show("CONFIRM_SUMMON");
  1473. end
  1474. elseif ( event == "CANCEL_SUMMON" ) then
  1475. StaticPopup_Hide("CONFIRM_SUMMON");
  1476. StaticPopup_Hide("CONFIRM_SUMMON_SCENARIO");
  1477. StaticPopup_Hide("CONFIRM_SUMMON_STARTING_AREA");
  1478. elseif ( event == "BILLING_NAG_DIALOG" ) then
  1479. StaticPopup_Show("BILLING_NAG", arg1);
  1480. elseif ( event == "IGR_BILLING_NAG_DIALOG" ) then
  1481. StaticPopup_Show("IGR_BILLING_NAG");
  1482. elseif ( event == "GOSSIP_CONFIRM" ) then
  1483. if ( arg3 > 0 ) then
  1484. StaticPopupDialogs["GOSSIP_CONFIRM"].hasMoneyFrame = 1;
  1485. else
  1486. StaticPopupDialogs["GOSSIP_CONFIRM"].hasMoneyFrame = nil;
  1487. end
  1488. local dialog = StaticPopup_Show("GOSSIP_CONFIRM", arg2);
  1489. if ( dialog ) then
  1490. dialog.data = arg1;
  1491. if ( arg3 > 0 ) then
  1492. MoneyFrame_Update(dialog:GetName().."MoneyFrame", arg3);
  1493. end
  1494. end
  1495. elseif ( event == "GOSSIP_ENTER_CODE" ) then
  1496. local dialog = StaticPopup_Show("GOSSIP_ENTER_CODE");
  1497. if ( dialog ) then
  1498. dialog.data = arg1;
  1499. end
  1500. elseif ( event == "GOSSIP_CONFIRM_CANCEL" or event == "GOSSIP_CLOSED" ) then
  1501. StaticPopup_Hide("GOSSIP_CONFIRM");
  1502. StaticPopup_Hide("GOSSIP_ENTER_CODE");
  1503. --Events for handling Auction UI
  1504. elseif ( event == "AUCTION_HOUSE_SHOW" ) then
  1505. if ( GameLimitedMode_IsActive() ) then
  1506. UIErrorsFrame:AddExternalErrorMessage(ERR_FEATURE_RESTRICTED_TRIAL);
  1507. C_AuctionHouse.CloseAuctionHouse();
  1508. else
  1509. AuctionHouseFrame_LoadUI();
  1510. ShowUIPanel(AuctionHouseFrame);
  1511. end
  1512. elseif ( event == "AUCTION_HOUSE_CLOSED" ) then
  1513. if ( AuctionHouseFrame ) then
  1514. HideUIPanel(AuctionHouseFrame);
  1515. end
  1516. elseif ( event == "AUCTION_HOUSE_DISABLED" ) then
  1517. StaticPopup_Show("AUCTION_HOUSE_DISABLED");
  1518. -- Events for trainer UI handling
  1519. elseif ( event == "TRAINER_SHOW" ) then
  1520. ClassTrainerFrame_LoadUI();
  1521. if ( ClassTrainerFrame_Show ) then
  1522. ClassTrainerFrame_Show();
  1523. end
  1524. elseif ( event == "TRAINER_CLOSED" ) then
  1525. if ( ClassTrainerFrame_Hide ) then
  1526. ClassTrainerFrame_Hide();
  1527. end
  1528. -- Events for trade skill UI handling
  1529. elseif ( event == "TRADE_SKILL_SHOW" ) then
  1530. TradeSkillFrame_LoadUI();
  1531. ShowUIPanel(TradeSkillFrame);
  1532. elseif ( event == "OBLITERUM_FORGE_SHOW" ) then
  1533. ObliterumForgeFrame_LoadUI();
  1534. ShowUIPanel(ObliterumForgeFrame);
  1535. elseif ( event == "SCRAPPING_MACHINE_SHOW" ) then
  1536. ScrappingMachineFrame_LoadUI();
  1537. ShowUIPanel(ScrappingMachineFrame);
  1538. -- Event for item socketing handling
  1539. elseif ( event == "SOCKET_INFO_UPDATE" ) then
  1540. ItemSocketingFrame_LoadUI();
  1541. ItemSocketingFrame_Update();
  1542. ShowUIPanel(ItemSocketingFrame);
  1543. elseif ( event == "ARTIFACT_UPDATE" ) then
  1544. ArtifactFrame_LoadUI();
  1545. ShowUIPanel(ArtifactFrame);
  1546. elseif ( event == "ARTIFACT_RESPEC_PROMPT" ) then
  1547. ArtifactFrame_LoadUI();
  1548. ShowUIPanel(ArtifactFrame);
  1549. if C_ArtifactUI.GetPointsRemaining() < C_ArtifactUI.GetRespecCost() then
  1550. StaticPopup_Show("NOT_ENOUGH_POWER_ARTIFACT_RESPEC", BreakUpLargeNumbers(C_ArtifactUI.GetRespecCost()));
  1551. else
  1552. StaticPopup_Show("CONFIRM_ARTIFACT_RESPEC", BreakUpLargeNumbers(C_ArtifactUI.GetRespecCost()));
  1553. end
  1554. elseif ( event == "ARTIFACT_ENDGAME_REFUND" ) then
  1555. local numRefunded, refundedTier, bagOrInventorySlot = ...;
  1556. ArtifactFrame_LoadUI();
  1557. ArtifactFrame:OnTraitsRefunded(numRefunded, refundedTier);
  1558. elseif ( event == "ARTIFACT_RELIC_FORGE_UPDATE" ) then
  1559. ArtifactFrame_LoadUI();
  1560. ShowUIPanel(ArtifactRelicForgeFrame);
  1561. elseif ( event == "AZERITE_ESSENCE_FORGE_OPEN" ) then
  1562. UIParentLoadAddOn("Blizzard_AzeriteEssenceUI");
  1563. if AzeriteEssenceUI and AzeriteEssenceUI:TryShow() and AzeriteEssenceUI:ShouldOpenBagsOnShow() then
  1564. OpenAllBags(AzeriteEssenceUI);
  1565. end
  1566. elseif ( event == "ADVENTURE_MAP_OPEN" ) then
  1567. Garrison_LoadUI();
  1568. local followerTypeID = ...;
  1569. if ( followerTypeID == LE_FOLLOWER_TYPE_GARRISON_7_0 ) then
  1570. ShowUIPanel(OrderHallMissionFrame);
  1571. else
  1572. ShowUIPanel(BFAMissionFrame);
  1573. end
  1574. -- Event for BarberShop handling
  1575. elseif ( event == "BARBER_SHOP_OPEN" ) then
  1576. BarberShopFrame_LoadUI();
  1577. if ( BarberShopFrame ) then
  1578. ShowUIPanel(BarberShopFrame);
  1579. end
  1580. elseif ( event == "BARBER_SHOP_CLOSE" ) then
  1581. if ( BarberShopFrame and BarberShopFrame:IsVisible() ) then
  1582. HideUIPanel(BarberShopFrame);
  1583. end
  1584. -- Event for guildbank handling
  1585. elseif ( event == "GUILDBANKFRAME_OPENED" ) then
  1586. GuildBankFrame_LoadUI();
  1587. if ( GuildBankFrame ) then
  1588. ShowUIPanel(GuildBankFrame);
  1589. if ( not GuildBankFrame:IsVisible() ) then
  1590. CloseGuildBankFrame();
  1591. end
  1592. end
  1593. elseif ( event == "GUILDBANKFRAME_CLOSED" ) then
  1594. if ( GuildBankFrame ) then
  1595. HideUIPanel(GuildBankFrame);
  1596. end
  1597. -- Display instance reset info
  1598. elseif ( event == "RAID_INSTANCE_WELCOME" ) then
  1599. local dungeonName = arg1;
  1600. local lockExpireTime = arg2;
  1601. local locked = arg3;
  1602. local extended = arg4;
  1603. local message;
  1604. if ( locked == 0 ) then
  1605. message = format(RAID_INSTANCE_WELCOME, dungeonName, SecondsToTime(lockExpireTime, nil, 1))
  1606. else
  1607. if ( lockExpireTime == 0 ) then
  1608. message = format(RAID_INSTANCE_WELCOME_EXTENDED, dungeonName);
  1609. else
  1610. if ( extended == 0 ) then
  1611. message = format(RAID_INSTANCE_WELCOME_LOCKED, dungeonName, SecondsToTime(lockExpireTime, nil, 1));
  1612. else
  1613. message = format(RAID_INSTANCE_WELCOME_LOCKED_EXTENDED, dungeonName, SecondsToTime(lockExpireTime, nil, 1));
  1614. end
  1615. end
  1616. end
  1617. local info = ChatTypeInfo["SYSTEM"];
  1618. DEFAULT_CHAT_FRAME:AddMessage(message, info.r, info.g, info.b, info.id);
  1619. -- Events for taxi benchmarking
  1620. elseif ( event == "ENABLE_TAXI_BENCHMARK" ) then
  1621. if ( not FramerateText:IsShown() ) then
  1622. ToggleFramerate(true);
  1623. end
  1624. local info = ChatTypeInfo["SYSTEM"];
  1625. DEFAULT_CHAT_FRAME:AddMessage(BENCHMARK_TAXI_MODE_ON, info.r, info.g, info.b, info.id);
  1626. elseif ( event == "DISABLE_TAXI_BENCHMARK" ) then
  1627. if ( FramerateText.benchmark ) then
  1628. ToggleFramerate();
  1629. end
  1630. local info = ChatTypeInfo["SYSTEM"];
  1631. DEFAULT_CHAT_FRAME:AddMessage(BENCHMARK_TAXI_MODE_OFF, info.r, info.g, info.b, info.id);
  1632. elseif ( event == "CHAT_MSG_WHISPER" and arg6 == "GM" ) then --GMChatUI
  1633. GMChatFrame_LoadUI(event, ...);
  1634. elseif ( event == "WOW_MOUSE_NOT_FOUND" ) then
  1635. StaticPopup_Show("WOW_MOUSE_NOT_FOUND");
  1636. elseif ( event == "TALENTS_INVOLUNTARILY_RESET" ) then
  1637. if ( arg1 ) then
  1638. StaticPopup_Show("TALENTS_INVOLUNTARILY_RESET_PET");
  1639. else
  1640. StaticPopup_Show("TALENTS_INVOLUNTARILY_RESET");
  1641. end
  1642. elseif (event == "SPEC_INVOLUNTARILY_CHANGED" ) then
  1643. StaticPopup_Show("SPEC_INVOLUNTARILY_CHANGED")
  1644. elseif( event == "EXPERIMENTAL_CVAR_CONFIRMATION_NEEDED" ) then
  1645. StaticPopup_Show("EXPERIMENTAL_CVAR_WARNING");
  1646. elseif ( event == "BAG_OVERFLOW_WITH_FULL_INVENTORY") then
  1647. StaticPopup_Show("CLIENT_INVENTORY_FULL_OVERFLOW");
  1648. elseif ( event == "AUCTION_HOUSE_SCRIPT_DEPRECATED") then
  1649. StaticPopup_Show("AUCTION_HOUSE_DEPRECATED");
  1650. -- Events for Archaeology
  1651. elseif ( event == "ARCHAEOLOGY_TOGGLE" ) then
  1652. ArchaeologyFrame_LoadUI();
  1653. if ( ArchaeologyFrame_Show and not ArchaeologyFrame:IsShown()) then
  1654. ArchaeologyFrame_Show();
  1655. elseif ( ArchaeologyFrame_Hide ) then
  1656. ArchaeologyFrame_Hide();
  1657. end
  1658. elseif ( event == "ARCHAEOLOGY_SURVEY_CAST" ) then
  1659. ArchaeologyFrame_LoadUI();
  1660. ArcheologyDigsiteProgressBar_OnEvent(ArcheologyDigsiteProgressBar, event, ...);
  1661. self:UnregisterEvent("ARCHAEOLOGY_SURVEY_CAST");
  1662. -- Events for Transmogrify UI handling
  1663. elseif ( event == "TRANSMOGRIFY_OPEN" ) then
  1664. CollectionsJournal_LoadUI();
  1665. if ( WardrobeFrame ) then
  1666. ShowUIPanel(WardrobeFrame);
  1667. end
  1668. elseif ( event == "TRANSMOGRIFY_CLOSE" ) then
  1669. if ( WardrobeFrame ) then
  1670. HideUIPanel(WardrobeFrame);
  1671. end
  1672. -- Events for adventure journal
  1673. elseif ( event == "AJ_OPEN" ) then
  1674. if (C_AdventureJournal.CanBeShown()) then
  1675. if ( not EncounterJournal ) then
  1676. EncounterJournal_LoadUI();
  1677. end
  1678. ShowUIPanel(EncounterJournal);
  1679. EJSuggestFrame_OpenFrame();
  1680. end
  1681. -- Events for Void Storage UI handling
  1682. elseif ( event == "VOID_STORAGE_OPEN" ) then
  1683. VoidStorage_LoadUI();
  1684. if ( VoidStorageFrame_Show ) then
  1685. VoidStorageFrame_Show();
  1686. end
  1687. elseif ( event == "VOID_STORAGE_CLOSE" ) then
  1688. if ( VoidStorageFrame_Hide ) then
  1689. VoidStorageFrame_Hide();
  1690. end
  1691. --Events for Trial caps
  1692. elseif ( event == "TRIAL_CAP_REACHED_MONEY" ) then
  1693. TrialAccountCapReached_Inform("money");
  1694. elseif ( event == "TRIAL_CAP_REACHED_LEVEL" ) then
  1695. TrialAccountCapReached_Inform("level");
  1696. -- Events for Black Market UI handling
  1697. elseif ( event == "BLACK_MARKET_OPEN" ) then
  1698. BlackMarket_LoadUI();
  1699. if ( BlackMarketFrame_Show ) then
  1700. BlackMarketFrame_Show();
  1701. end
  1702. elseif ( event == "BLACK_MARKET_CLOSE" ) then
  1703. if ( BlackMarketFrame_Hide ) then
  1704. BlackMarketFrame_Hide();
  1705. end
  1706. -- Events for Item Upgrading
  1707. elseif ( event == "ITEM_UPGRADE_MASTER_OPENED" ) then
  1708. ItemUpgrade_LoadUI();
  1709. if ( ItemUpgradeFrame_Show ) then
  1710. ItemUpgradeFrame_Show();
  1711. end
  1712. elseif ( event == "ITEM_UPGRADE_MASTER_CLOSED" ) then
  1713. if ( ItemUpgradeFrame_Hide ) then
  1714. ItemUpgradeFrame_Hide();
  1715. end
  1716. -- Events for Toy Box
  1717. elseif ( event == "TOYS_UPDATED" ) then
  1718. if ( not CollectionsJournal ) then
  1719. local itemID, new = ...;
  1720. if ( itemID and new ) then
  1721. -- Toy box isn't loaded, save that this itemid is new in this session incase the journal is opened later
  1722. if not self.newToys then
  1723. self.newToys = {};
  1724. end
  1725. self.newToys[itemID] = true;
  1726. self.autoPageToCollectedToyID = itemID;
  1727. SetCVar("petJournalTab", COLLECTIONS_JOURNAL_TAB_INDEX_TOYS);
  1728. end
  1729. end
  1730. -- Events for Heirloom Journal
  1731. elseif ( event == "HEIRLOOM_UPGRADE_TARGETING_CHANGED" ) then
  1732. local isPendingHeirloomUpgrade = ...;
  1733. if ( isPendingHeirloomUpgrade ) then
  1734. if ( not CollectionsJournal ) then
  1735. CollectionsJournal_LoadUI();
  1736. end
  1737. HeirloomsJournal:SetFindClosestUpgradeablePage(isPendingHeirloomUpgrade);
  1738. ShowUIPanel(CollectionsJournal);
  1739. CollectionsJournal_SetTab(CollectionsJournal, 4);
  1740. end
  1741. elseif ( event == "HEIRLOOMS_UPDATED" ) then
  1742. if ( not CollectionsJournal ) then
  1743. local itemID, updateReason = ...;
  1744. if ( itemID and updateReason == "NEW" ) then
  1745. -- Heirloom journal isn't loaded, save that this itemid is new in this session incase the journal is opened later
  1746. if not self.newHeirlooms then
  1747. self.newHeirlooms = {};
  1748. end
  1749. self.newHeirlooms[itemID] = true;
  1750. end
  1751. end
  1752. -- Events for Wardrobe
  1753. elseif ( event == "TRANSMOG_COLLECTION_UPDATED" ) then
  1754. if ( not CollectionsJournal ) then
  1755. local latestAppearanceID, latestAppearanceCategoryID = C_TransmogCollection.GetLatestAppearance();
  1756. if ( latestAppearanceID and latestAppearanceID ~= self.latestAppearanceID ) then
  1757. self.latestAppearanceID = latestAppearanceID;
  1758. SetCVar("petJournalTab", 5);
  1759. end
  1760. end
  1761. -- Quest Choice trigger event
  1762. elseif ( event == "QUEST_CHOICE_UPDATE" ) then
  1763. local choiceInfo = C_QuestChoice.GetQuestChoiceInfo();
  1764. if (choiceInfo.uiTextureKitID and choiceInfo.uiTextureKitID ~= 0) then
  1765. WarboardQuestChoice_LoadUI();
  1766. WarboardQuestChoiceFrame:TryShow();
  1767. else
  1768. QuestChoice_LoadUI();
  1769. QuestChoiceFrame:TryShow();
  1770. end
  1771. elseif ( event == "LUA_WARNING" ) then
  1772. HandleLuaWarning(...);
  1773. elseif ( event == "GARRISON_ARCHITECT_OPENED") then
  1774. if (not GarrisonBuildingFrame) then
  1775. Garrison_LoadUI();
  1776. end
  1777. ShowUIPanel(GarrisonBuildingFrame);
  1778. elseif ( event == "GARRISON_ARCHITECT_CLOSED" ) then
  1779. if ( GarrisonBuildingFrame ) then
  1780. HideUIPanel(GarrisonBuildingFrame);
  1781. end
  1782. elseif ( event == "GARRISON_MISSION_NPC_OPENED") then
  1783. local followerType = ...;
  1784. if followerType ~= LE_FOLLOWER_TYPE_GARRISON_7_0 then
  1785. local frameName = GarrisonFollowerOptions[followerType].missionFrame;
  1786. if (not _G[frameName]) then
  1787. Garrison_LoadUI();
  1788. end
  1789. local frame = _G[frameName];
  1790. frame.followerTypeID = followerType;
  1791. ShowUIPanel(frame);
  1792. end
  1793. elseif ( event == "GARRISON_MISSION_NPC_CLOSED" ) then
  1794. if ( GarrisonMissionFrame ) then
  1795. HideUIPanel(GarrisonMissionFrame);
  1796. end
  1797. if ( BFAMissionFrame ) then
  1798. HideUIPanel(BFAMissionFrame);
  1799. end
  1800. elseif ( event == "GARRISON_SHIPYARD_NPC_OPENED") then
  1801. if (not GarrisonShipyardFrame) then
  1802. Garrison_LoadUI();
  1803. end
  1804. GarrisonShipyardFrame.followerTypeID = ...;
  1805. ShowUIPanel(GarrisonShipyardFrame);
  1806. elseif ( event == "GARRISON_SHIPYARD_NPC_CLOSED" ) then
  1807. if ( GarrisonShipyardFrame ) then
  1808. HideUIPanel(GarrisonShipyardFrame);
  1809. end
  1810. elseif ( event == "SHIPMENT_CRAFTER_OPENED" ) then
  1811. if (not GarrisonCapacitiveDisplayFrame) then
  1812. Garrison_LoadUI();
  1813. end
  1814. elseif ( event == "GARRISON_MONUMENT_SHOW_UI") then
  1815. if(not GarrisonMonumentFrame)then
  1816. Garrison_LoadUI();
  1817. end
  1818. GarrisonMonuntmentFrame_OnEvent(GarrisonMonumentFrame, event, ...);
  1819. elseif ( event == "GARRISON_RECRUITMENT_NPC_OPENED") then
  1820. if(not GarrisonRecruiterFrame)then
  1821. Garrison_LoadUI();
  1822. end
  1823. ShowUIPanel(GarrisonRecruiterFrame);
  1824. elseif ( event == "GARRISON_TALENT_NPC_OPENED") then
  1825. OrderHall_LoadUI();
  1826. OrderHallTalentFrame:SetGarrisonType(...);
  1827. ToggleOrderHallTalentUI();
  1828. elseif ( event == "PRODUCT_DISTRIBUTIONS_UPDATED" ) then
  1829. StoreFrame_CheckForFree(event);
  1830. elseif ( event == "LOADING_SCREEN_ENABLED" ) then
  1831. TopBannerManager_LoadingScreenEnabled();
  1832. elseif ( event == "LOADING_SCREEN_DISABLED" ) then
  1833. TopBannerManager_LoadingScreenDisabled()
  1834. elseif ( event == "TOKEN_AUCTION_SOLD" ) then
  1835. local info = ChatTypeInfo["SYSTEM"];
  1836. local itemName = GetItemInfo(WOW_TOKEN_ITEM_ID);
  1837. if (itemName) then
  1838. DEFAULT_CHAT_FRAME:AddMessage(ERR_AUCTION_SOLD_S:format(itemName), info.r, info.g, info.b, info.id);
  1839. else
  1840. self:RegisterEvent("GET_ITEM_INFO_RECEIVED");
  1841. end
  1842. elseif ( event == "GET_ITEM_INFO_RECEIVED" ) then
  1843. local itemID = ...;
  1844. if (itemID == WOW_TOKEN_ITEM_ID) then
  1845. local info = ChatTypeInfo["SYSTEM"];
  1846. local itemName = GetItemInfo(WOW_TOKEN_ITEM_ID);
  1847. DEFAULT_CHAT_FRAME:AddMessage(ERR_AUCTION_SOLD_S:format(itemName), info.r, info.g, info.b, info.id);
  1848. self:UnregisterEvent("GET_ITEM_INFO_RECEIVED");
  1849. end
  1850. elseif ( event == "TALKINGHEAD_REQUESTED" ) then
  1851. if ( not TalkingHeadFrame ) then
  1852. TalkingHead_LoadUI();
  1853. TalkingHeadFrame_PlayCurrent();
  1854. end
  1855. self:UnregisterEvent("TALKINGHEAD_REQUESTED");
  1856. elseif (event == "CHALLENGE_MODE_KEYSTONE_RECEPTABLE_OPEN") then
  1857. ChallengeMode_LoadUI();
  1858. ChallengesKeystoneFrame:ShowKeystoneFrame();
  1859. elseif (event == "CHALLENGE_MODE_COMPLETED") then
  1860. if (not ChallengeModeCompleteBanner) then
  1861. ChallengeMode_LoadUI();
  1862. ChallengeModeCompleteBanner:OnEvent(event, ...);
  1863. end
  1864. self:UnregisterEvent("CHALLENGE_MODE_COMPLETED");
  1865. elseif (event == "UNIT_AURA") then
  1866. OrderHall_CheckCommandBar();
  1867. elseif (event == "TAXIMAP_OPENED") then
  1868. local uiMapSystem = ...;
  1869. if (uiMapSystem == Enum.UIMapSystem.Taxi) then
  1870. ShowUIPanel(TaxiFrame);
  1871. else
  1872. FlightMap_LoadUI();
  1873. ShowUIPanel(FlightMapFrame);
  1874. end
  1875. elseif (event == "SCENARIO_UPDATE") then
  1876. BoostTutorial_AttemptLoad();
  1877. elseif (event == "DEBUG_MENU_TOGGLED") then
  1878. UpdateUIParentRelativeToDebugMenu();
  1879. elseif (event == "REVEAL_CAPTURE_TOGGLED") then
  1880. UpdateUIParentRelativeToDebugMenu();
  1881. elseif ( event == "GROUP_INVITE_CONFIRMATION" ) then
  1882. UpdateInviteConfirmationDialogs();
  1883. elseif ( event == "INVITE_TO_PARTY_CONFIRMATION" ) then
  1884. OnInviteToPartyConfirmation(...);
  1885. elseif ( event == "CONTRIBUTION_COLLECTOR_OPEN" ) then
  1886. UIParentLoadAddOn("Blizzard_Contribution");
  1887. ContributionCollectionUI_Show();
  1888. elseif (event == "CONTRIBUTION_COLLECTOR_CLOSE" ) then
  1889. if ( ContributionCollectionUI_Hide ) then
  1890. ContributionCollectionUI_Hide();
  1891. end
  1892. elseif (event == "ALLIED_RACE_OPEN") then
  1893. AlliedRaces_LoadUI();
  1894. local raceID = ...;
  1895. AlliedRacesFrame:LoadRaceData(raceID);
  1896. ShowUIPanel(AlliedRacesFrame);
  1897. elseif (event == "ISLAND_COMPLETED") then
  1898. IslandsPartyPose_LoadUI();
  1899. local mapID, winner = ...;
  1900. IslandsPartyPoseFrame:LoadScreen(mapID, winner);
  1901. ShowUIPanel(IslandsPartyPoseFrame);
  1902. elseif (event == "WARFRONT_COMPLETED") then
  1903. WarfrontsPartyPose_LoadUI();
  1904. local mapID, winner = ...;
  1905. WarfrontsPartyPoseFrame:LoadScreen(mapID, winner);
  1906. ShowUIPanel(WarfrontsPartyPoseFrame);
  1907. -- Event(s) for Azerite Respec
  1908. elseif (event == "RESPEC_AZERITE_EMPOWERED_ITEM_OPENED") then
  1909. AzeriteRespecFrame_LoadUI();
  1910. ShowUIPanel(AzeriteRespecFrame);
  1911. elseif (event == "ISLANDS_QUEUE_OPEN") then
  1912. IslandsQueue_LoadUI();
  1913. ShowUIPanel(IslandsQueueFrame);
  1914. elseif (event == "ITEM_INTERACTION_OPEN") then
  1915. ItemInteraction_LoadUI();
  1916. ShowUIPanel(ItemInteractionFrame);
  1917. -- Events for Reporting system
  1918. elseif (event == "REPORT_PLAYER_RESULT") then
  1919. local success = ...;
  1920. if (success) then
  1921. UIErrorsFrame:AddExternalErrorMessage(GERR_REPORT_SUBMITTED_SUCCESSFULLY);
  1922. DEFAULT_CHAT_FRAME:AddMessage(COMPLAINT_ADDED);
  1923. else
  1924. UIErrorsFrame:AddExternalErrorMessage(GERR_REPORT_SUBMISSION_FAILED);
  1925. DEFAULT_CHAT_FRAME:AddMessage(ERR_REPORT_SUBMISSION_FAILED);
  1926. end
  1927. elseif (event == "GLOBAL_MOUSE_DOWN" or event == "GLOBAL_MOUSE_UP") then
  1928. local buttonID = ...;
  1929. -- Close dropdown(s).
  1930. local mouseFocus = GetMouseFocus();
  1931. if not HandlesGlobalMouseEvent(mouseFocus, buttonID, event) then
  1932. UIDropDownMenu_HandleGlobalMouseEvent(buttonID, event);
  1933. end
  1934. -- Clear keyboard focus.
  1935. local autoCompleteBoxList = { AutoCompleteBox }
  1936. if LFGListFrame and LFGListFrame.SearchPanel and LFGListFrame.SearchPanel.AutoCompleteFrame then
  1937. tinsert(autoCompleteBoxList, LFGListFrame.SearchPanel.AutoCompleteFrame);
  1938. end
  1939. if not HasVisibleAutoCompleteBox(autoCompleteBoxList, mouseFocus) then
  1940. if event == "GLOBAL_MOUSE_DOWN" and buttonID == "LeftButton" and not IsModifierKeyDown() then
  1941. local keyBoardFocus = GetCurrentKeyBoardFocus();
  1942. if keyBoardFocus then
  1943. local hasStickyFocus = keyBoardFocus.HasStickyFocus and keyBoardFocus:HasStickyFocus();
  1944. if keyBoardFocus.ClearFocus and not hasStickyFocus and keyBoardFocus ~= mouseFocus then
  1945. keyBoardFocus:ClearFocus();
  1946. end
  1947. end
  1948. end
  1949. end
  1950. end
  1951. end
  1952. -- Frame Management --
  1953. -- UIPARENT_MANAGED_FRAME_POSITIONS stores all the frames that have positioning dependencies based on other frames.
  1954. -- UIPARENT_MANAGED_FRAME_POSITIONS["FRAME"] = {
  1955. --Note: this is out of date and there are several more options now.
  1956. -- none = This value is used if no dependent frames are shown
  1957. -- watchBar = This is the offset used if the reputation or artifact watch bar is shown
  1958. -- anchorTo = This is the object that the stored frame is anchored to
  1959. -- point = This is the point on the frame used as the anchor
  1960. -- rpoint = This is the point on the "anchorTo" frame that the stored frame is anchored to
  1961. -- bottomEither = This offset is used if either bottom multibar is shown
  1962. -- bottomLeft
  1963. -- var = If this is set use _G[varName] = value instead of setpoint
  1964. -- };
  1965. -- some standard offsets
  1966. local actionBarOffset = 45;
  1967. local menuBarTop = 55;
  1968. local overrideActionBarTop = 40;
  1969. local petBattleTop = 60;
  1970. function UpdateMenuBarTop ()
  1971. --Determines the optimal magic number based on resolution and action bar status.
  1972. menuBarTop = 55;
  1973. local width = GetScreenWidth();
  1974. local height = GetScreenHeight();
  1975. if ( ( width / height ) > 4/3 ) then
  1976. --Widescreen resolution
  1977. menuBarTop = 75;
  1978. end
  1979. end
  1980. function UIParent_UpdateTopFramePositions()
  1981. local topOffset = 0;
  1982. local buffsAreaTopOffset = 0;
  1983. if (OrderHallCommandBar and OrderHallCommandBar:IsShown()) then
  1984. topOffset = 12;
  1985. buffsAreaTopOffset = OrderHallCommandBar:GetHeight();
  1986. end
  1987. if (PlayerFrame and not PlayerFrame:IsUserPlaced() and not PlayerFrame_IsAnimatedOut(PlayerFrame)) then
  1988. PlayerFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", -19, -4 - topOffset)
  1989. end
  1990. if (TargetFrame and not TargetFrame:IsUserPlaced()) then
  1991. TargetFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 250, -4 - topOffset);
  1992. end
  1993. local ticketStatusFrameShown = TicketStatusFrame and TicketStatusFrame:IsShown();
  1994. local gmChatStatusFrameShown = GMChatStatusFrame and GMChatStatusFrame:IsShown();
  1995. if (ticketStatusFrameShown) then
  1996. TicketStatusFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -180, 0 - buffsAreaTopOffset);
  1997. buffsAreaTopOffset = buffsAreaTopOffset + TicketStatusFrame:GetHeight();
  1998. end
  1999. if (gmChatStatusFrameShown) then
  2000. GMChatStatusFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -170, -5 - buffsAreaTopOffset);
  2001. buffsAreaTopOffset = buffsAreaTopOffset + GMChatStatusFrame:GetHeight() + 5;
  2002. end
  2003. if (not ticketStatusFrameShown and not gmChatStatusFrameShown) then
  2004. buffsAreaTopOffset = buffsAreaTopOffset + 13;
  2005. end
  2006. BuffFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -205, 0 - buffsAreaTopOffset);
  2007. end
  2008. UIPARENT_ALTERNATE_FRAME_POSITIONS = {
  2009. ["PlayerPowerBarAlt_Bottom"] = {baseY = true, yOffset = 20, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, reputation = 1, tutorialAlert = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1};
  2010. ["PlayerPowerBarAlt_Top"] = {baseY = -30, anchorTo = "UIParent", point = "TOP", rpoint = "TOP"};
  2011. }
  2012. UIPARENT_MANAGED_FRAME_POSITIONS = {
  2013. --Items with baseY set to "true" are positioned based on the value of menuBarTop and their offset needs to be repeatedly evaluated as menuBarTop can change.
  2014. --"yOffset" gets added to the value of "baseY", which is used for values based on menuBarTop.
  2015. ["MultiBarBottomLeft"] = {baseY = 13, watchBar = 1, maxLevel = 1, anchorTo = "ActionButton1", point = "BOTTOMLEFT", rpoint = "TOPLEFT"};
  2016. ["MultiBarBottomRight"] = {baseY = 2, watchBar = 1, maxLevel = 1, anchorTo = "ActionButton12", point = "TOPLEFT", rpoint = "TOPRIGHT", xOffset = 45};
  2017. ["GroupLootContainer"] = {baseY = true, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1};
  2018. ["TutorialFrameAlertButton"] = {baseY = true, yOffset = -10, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, watchBar = 1};
  2019. ["FramerateLabel"] = {baseY = true, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, playerPowerBarAlt = 1, powerBarWidgets = 1, extraActionBarFrame = 1, anchorTo="WorldFrame" };
  2020. ["ArcheologyDigsiteProgressBar"] = {baseY = true, yOffset = 40, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, playerPowerBarAlt = 1, powerBarWidgets = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1, castingBar = 1};
  2021. ["CastingBarFrame"] = {baseY = true, yOffset = 40, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, playerPowerBarAlt = 1, powerBarWidgets = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1, talkingHeadFrame = 1, classResourceOverlayFrame = 1, classResourceOverlayOffset = 1};
  2022. ["UIWidgetPowerBarContainerFrame"] = {baseY = true, yOffset = 20, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, playerPowerBarAlt = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1, talkingHeadFrame = 1, classResourceOverlayFrame = 1, classResourceOverlayOffset = 1};
  2023. ["ClassResourceOverlayParentFrame"] = {baseY = true, yOffset = 0, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, playerPowerBarAlt = 1, powerBarWidgets = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1 };
  2024. ["PlayerPowerBarAlt"] = UIPARENT_ALTERNATE_FRAME_POSITIONS["PlayerPowerBarAlt_Bottom"];
  2025. ["ExtraActionBarFrame"] = {baseY = true, yOffset = 0, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1};
  2026. ["ZoneAbilityFrame"] = {baseY = true, yOffset = 0, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, extraActionBarFrame = 1};
  2027. ["ChatFrame1"] = {baseY = true, yOffset = 40, bottomLeft = actionBarOffset-8, justBottomRightAndStance = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, maxLevel = 1, point = "BOTTOMLEFT", rpoint = "BOTTOMLEFT", xOffset = 32};
  2028. ["ChatFrame2"] = {baseY = true, yOffset = 40, bottomRight = actionBarOffset-8, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, rightLeft = -2*actionBarOffset, rightRight = -actionBarOffset, watchBar = 1, maxLevel = 1, point = "BOTTOMRIGHT", rpoint = "BOTTOMRIGHT", xOffset = -32};
  2029. ["StanceBarFrame"] = {baseY = 0, bottomLeft = actionBarOffset, watchBar = 1, maxLevel = 1, anchorTo = "MainMenuBar", point = "BOTTOMLEFT", rpoint = "TOPLEFT", xOffset = 30};
  2030. ["PossessBarFrame"] = {baseY = 0, bottomLeft = actionBarOffset, watchBar = 1, maxLevel = 1, anchorTo = "MainMenuBar", point = "BOTTOMLEFT", rpoint = "TOPLEFT", xOffset = 30};
  2031. ["MultiCastActionBarFrame"] = {baseY = 8, bottomLeft = actionBarOffset, watchBar = 1, maxLevel = 1, anchorTo = "MainMenuBar", point = "BOTTOMLEFT", rpoint = "TOPLEFT", xOffset = 30};
  2032. ["AuctionHouseMultisellProgressFrame"] = {baseY = true, yOffset = 18, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1};
  2033. ["TalkingHeadFrame"] = {baseY = true, yOffset = 0, bottomEither = actionBarOffset, overrideActionBar = overrideActionBarTop, petBattleFrame = petBattleTop, bonusActionBar = 1, pet = 1, watchBar = 1, tutorialAlert = 1, playerPowerBarAlt = 1, powerBarWidgets = 1, extraActionBarFrame = 1, ZoneAbilityFrame = 1, classResourceOverlayFrame = 1};
  2034. -- Vars
  2035. -- These indexes require global variables of the same name to be declared. For example, if I have an index ["FOO"] then I need to make sure the global variable
  2036. -- FOO exists before this table is constructed. The function UIParent_ManageFramePosition will use the "FOO" table index to change the value of the FOO global
  2037. -- variable so that other modules can use the most up-to-date value of FOO without having knowledge of the UIPARENT_MANAGED_FRAME_POSITIONS table.
  2038. ["CONTAINER_OFFSET_X"] = {baseX = 0, rightActionBarsX = "variable", isVar = "xAxis"};
  2039. ["CONTAINER_OFFSET_Y"] = {baseY = true, yOffset = 10, bottomEither = actionBarOffset, watchBar = 1, isVar = "yAxis"};
  2040. ["PETACTIONBAR_YPOS"] = {baseY = 89, bottomLeft = actionBarOffset + 3, justBottomRightAndStance = actionBarOffset, watchBar = 1, maxLevel = 1, isVar = "yAxis"};
  2041. ["MULTICASTACTIONBAR_YPOS"] = {baseY = 0, bottomLeft = actionBarOffset, watchBar = 1, maxLevel = 1, isVar = "yAxis"};
  2042. ["OBJTRACKER_OFFSET_X"] = {baseX = 12, rightActionBarsX = "variable", isVar = "xAxis"};
  2043. ["BATTLEFIELD_TAB_OFFSET_Y"] = {baseY = 260, bottomRight = actionBarOffset, watchBar = 1, isVar = "yAxis"};
  2044. };
  2045. local UIPARENT_VARIABLE_OFFSETS = {
  2046. ["rightActionBarsX"] = 0,
  2047. };
  2048. -- If any Var entries in UIPARENT_MANAGED_FRAME_POSITIONS are used exclusively by addons, they should be declared here and not in one of the addon's files.
  2049. -- The reason why is that it is possible for UIParent_ManageFramePosition to be run before the addon loads.
  2050. OBJTRACKER_OFFSET_X = 0;
  2051. BATTLEFIELD_TAB_OFFSET_Y = 0;
  2052. -- constant offsets
  2053. for _, data in pairs(UIPARENT_MANAGED_FRAME_POSITIONS) do
  2054. for flag, value in pairs(data) do
  2055. if ( flag == "watchBar" ) then
  2056. data[flag] = value * -2;
  2057. elseif ( flag == "maxLevel" ) then
  2058. data[flag] = value * -5;
  2059. elseif ( flag == "pet" ) then
  2060. data[flag] = value * 35;
  2061. elseif ( flag == "tutorialAlert" ) then
  2062. data[flag] = value * 35;
  2063. end
  2064. end
  2065. end
  2066. function UIParent_ManageFramePosition(index, value, yOffsetFrames, xOffsetFrames, hasBottomLeft, hasBottomRight, hasPetBar)
  2067. local frame, xOffset, yOffset, anchorTo, point, rpoint;
  2068. frame = _G[index];
  2069. if ( not frame or (type(frame)=="table" and frame.ignoreFramePositionManager)) then
  2070. return;
  2071. end
  2072. -- Always start with base as the base offset or default to zero if no "none" specified
  2073. xOffset = 0;
  2074. if ( value["baseX"] ) then
  2075. xOffset = value["baseX"];
  2076. elseif ( value["xOffset"] ) then
  2077. xOffset = value["xOffset"];
  2078. end
  2079. yOffset = 0;
  2080. if ( tonumber(value["baseY"]) ) then
  2081. --tonumber(nil) and tonumber(boolean) evaluate as nil, tonumber(number) evaluates as a number, which evaluates as true.
  2082. --This allows us to use the true value in baseY for flagging a frame's positioning as dependent upon the value of menuBarTop.
  2083. yOffset = value["baseY"];
  2084. elseif ( value["baseY"] ) then
  2085. --value["baseY"] is true, use menuBarTop.
  2086. yOffset = menuBarTop;
  2087. end
  2088. if ( value["yOffset"] ) then
  2089. --This is so things based on menuBarTop can still have an offset. Otherwise you'd just use put the offset value in baseY.
  2090. yOffset = yOffset + value["yOffset"];
  2091. end
  2092. -- Iterate through frames that affect y offsets
  2093. local hasBottomEitherFlag;
  2094. for _, flag in pairs(yOffsetFrames) do
  2095. local flagValue = value[flag];
  2096. if ( flagValue ) then
  2097. if ( flagValue == "variable" ) then
  2098. yOffset = yOffset + UIPARENT_VARIABLE_OFFSETS[flag];
  2099. else
  2100. if ( flag == "bottomEither" ) then
  2101. hasBottomEitherFlag = 1;
  2102. end
  2103. yOffset = yOffset + flagValue;
  2104. end
  2105. end
  2106. end
  2107. -- don't offset for the pet bar and bottomEither if the player has
  2108. -- the bottom right bar shown and not the bottom left
  2109. if ( hasBottomEitherFlag and hasBottomRight and hasPetBar and not hasBottomLeft ) then
  2110. yOffset = yOffset - (value["pet"] or 0);
  2111. end
  2112. -- Iterate through frames that affect x offsets
  2113. for _, flag in pairs(xOffsetFrames) do
  2114. local flagValue = value[flag];
  2115. if ( flagValue ) then
  2116. if ( flagValue == "variable" ) then
  2117. xOffset = xOffset + UIPARENT_VARIABLE_OFFSETS[flag];
  2118. else
  2119. xOffset = xOffset + flagValue;
  2120. end
  2121. end
  2122. end
  2123. -- Set up anchoring info
  2124. anchorTo = value["anchorTo"];
  2125. point = value["point"];
  2126. rpoint = value["rpoint"];
  2127. if ( not anchorTo ) then
  2128. anchorTo = "UIParent";
  2129. end
  2130. if ( not point ) then
  2131. point = "BOTTOM";
  2132. end
  2133. if ( not rpoint ) then
  2134. rpoint = "BOTTOM";
  2135. end
  2136. -- Anchor frame
  2137. if ( value["isVar"] ) then
  2138. if ( value["isVar"] == "xAxis" ) then
  2139. _G[index] = xOffset;
  2140. else
  2141. _G[index] = yOffset;
  2142. end
  2143. else
  2144. if ( frame ~= ChatFrame2 and not(frame:IsObjectType("frame") and frame:IsUserPlaced()) ) then
  2145. frame:SetPoint(point, anchorTo, rpoint, xOffset, yOffset);
  2146. end
  2147. end
  2148. end
  2149. local function FramePositionDelegate_OnAttributeChanged(self, attribute)
  2150. if ( attribute == "panel-show" ) then
  2151. local force = self:GetAttribute("panel-force");
  2152. local frame = self:GetAttribute("panel-frame");
  2153. self:ShowUIPanel(frame, force);
  2154. elseif ( attribute == "panel-hide" ) then
  2155. local frame = self:GetAttribute("panel-frame");
  2156. local skipSetPoint = self:GetAttribute("panel-skipSetPoint");
  2157. self:HideUIPanel(frame, skipSetPoint);
  2158. elseif ( attribute == "panel-update" ) then
  2159. local frame = self:GetAttribute("panel-frame");
  2160. self:UpdateUIPanelPositions(frame);
  2161. elseif ( attribute == "uiparent-manage" ) then
  2162. self:UIParentManageFramePositions();
  2163. elseif ( attribute == "panel-maximize" ) then
  2164. local frame = self:GetAttribute("panel-frame");
  2165. self:MoveUIPanel(GetUIPanelWindowInfo(frame, "area"), "fullscreen", UIPANEL_DO_SET_POINT, UIPANEL_VALIDATE_CURRENT_FRAME);
  2166. frame:ClearAllPoints();
  2167. frame:SetPoint(GetUIPanelWindowInfo(frame, "maximizePoint"));
  2168. elseif ( attribute == "panel-restore" ) then
  2169. local frame = self:GetAttribute("panel-frame");
  2170. self:MoveUIPanel("fullscreen", GetUIPanelWindowInfo(frame, "area"), UIPANEL_DO_SET_POINT, UIPANEL_VALIDATE_CURRENT_FRAME);
  2171. end
  2172. end
  2173. local FramePositionDelegate = CreateFrame("FRAME");
  2174. FramePositionDelegate:SetScript("OnAttributeChanged", FramePositionDelegate_OnAttributeChanged);
  2175. function FramePositionDelegate:ShowUIPanel(frame, force)
  2176. local frameArea, framePushable;
  2177. frameArea = GetUIPanelWindowInfo(frame, "area");
  2178. if ( not CanOpenPanels() and frameArea ~= "center" and frameArea ~= "full" ) then
  2179. self:ShowUIPanelFailed(frame);
  2180. return;
  2181. end
  2182. framePushable = GetUIPanelWindowInfo(frame, "pushable") or 0;
  2183. if ( UnitIsDead("player") and not GetUIPanelWindowInfo(frame, "whileDead") ) then
  2184. self:ShowUIPanelFailed(frame);
  2185. NotWhileDeadError();
  2186. return;
  2187. end
  2188. -- If the store-frame is open, we don't let people open up any other panels (just as if it were full-screened)
  2189. if ( StoreFrame_IsShown and StoreFrame_IsShown() ) then
  2190. self:ShowUIPanelFailed(frame);
  2191. return;
  2192. end
  2193. -- If we have a full-screen frame open, ignore other non-fullscreen open requests
  2194. if ( self:GetUIPanel("fullscreen") and (frameArea ~= "full") ) then
  2195. if ( force ) then
  2196. self:SetUIPanel("fullscreen", nil, 1);
  2197. else
  2198. self:ShowUIPanelFailed(frame);
  2199. return;
  2200. end
  2201. end
  2202. if ( GetUIPanelWindowInfo(frame, "checkFit") == 1 ) then
  2203. self:UpdateScaleForFit(frame);
  2204. end
  2205. -- If we have a "center" frame open, only listen to other "center" open requests
  2206. local centerFrame = self:GetUIPanel("center");
  2207. local centerArea, centerPushable;
  2208. if ( centerFrame ) then
  2209. if ( GetUIPanelWindowInfo(centerFrame, "allowOtherPanels") ) then
  2210. HideUIPanel(centerFrame);
  2211. centerFrame = nil;
  2212. else
  2213. centerArea = GetUIPanelWindowInfo(centerFrame, "area");
  2214. if ( centerArea and (centerArea == "center") and (frameArea ~= "center") and (frameArea ~= "full") ) then
  2215. if ( force ) then
  2216. self:SetUIPanel("center", nil, 1);
  2217. else
  2218. self:ShowUIPanelFailed(frame);
  2219. return;
  2220. end
  2221. end
  2222. centerPushable = GetUIPanelWindowInfo(centerFrame, "pushable") or 0;
  2223. end
  2224. end
  2225. -- Full-screen frames just replace each other
  2226. if ( frameArea == "full" ) then
  2227. securecall("CloseAllWindows");
  2228. self:SetUIPanel("fullscreen", frame);
  2229. return;
  2230. end
  2231. -- Native "center" frames just replace each other, and they take priority over pushed frames
  2232. if ( frameArea == "center" ) then
  2233. securecall("CloseWindows");
  2234. if ( not GetUIPanelWindowInfo(frame, "allowOtherPanels") ) then
  2235. securecall("CloseAllBags");
  2236. end
  2237. self:SetUIPanel("center", frame, 1);
  2238. return;
  2239. end
  2240. -- Doublewide frames take up the left and center spots
  2241. if ( frameArea == "doublewide" ) then
  2242. local leftFrame = self:GetUIPanel("left");
  2243. if ( leftFrame ) then
  2244. local leftPushable = GetUIPanelWindowInfo(leftFrame, "pushable") or 0;
  2245. if ( leftPushable > 0 and CanShowRightUIPanel(leftFrame) ) then
  2246. -- Push left to right
  2247. self:MoveUIPanel("left", "right", UIPANEL_SKIP_SET_POINT);
  2248. elseif ( centerFrame and CanShowRightUIPanel(centerFrame) ) then
  2249. self:MoveUIPanel("center", "right", UIPANEL_SKIP_SET_POINT);
  2250. end
  2251. end
  2252. self:SetUIPanel("doublewide", frame);
  2253. return;
  2254. end
  2255. -- If not pushable, close any doublewide frames
  2256. local doublewideFrame = self:GetUIPanel("doublewide");
  2257. if ( doublewideFrame ) then
  2258. if ( framePushable == 0 ) then
  2259. -- Set as left (closes doublewide) and slide over the right frame
  2260. self:SetUIPanel("left", frame, 1);
  2261. self:MoveUIPanel("right", "center");
  2262. elseif ( CanShowRightUIPanel(frame) ) then
  2263. -- Set as right
  2264. self:SetUIPanel("right", frame);
  2265. else
  2266. self:SetUIPanel("left", frame);
  2267. end
  2268. return;
  2269. end
  2270. -- Try to put it on the left
  2271. local leftFrame = self:GetUIPanel("left");
  2272. if ( not leftFrame ) then
  2273. self:SetUIPanel("left", frame);
  2274. return;
  2275. end
  2276. local leftPushable = GetUIPanelWindowInfo(leftFrame, "pushable") or 0;
  2277. -- Two open already
  2278. local rightFrame = self:GetUIPanel("right");
  2279. if ( centerFrame and not rightFrame ) then
  2280. -- If not pushable and left isn't pushable
  2281. if ( leftPushable == 0 and framePushable == 0 ) then
  2282. -- Replace left
  2283. self:SetUIPanel("left", frame);
  2284. elseif ( ( framePushable > centerPushable or centerArea == "center" ) and CanShowRightUIPanel(frame) ) then
  2285. -- This one is highest priority, show as right
  2286. self:SetUIPanel("right", frame);
  2287. elseif ( framePushable < leftPushable ) then
  2288. if ( centerArea == "center" ) then
  2289. if ( CanShowRightUIPanel(leftFrame) ) then
  2290. -- Skip center
  2291. self:MoveUIPanel("left", "right", UIPANEL_SKIP_SET_POINT);
  2292. self:SetUIPanel("left", frame);
  2293. else
  2294. -- Replace left
  2295. self:SetUIPanel("left", frame);
  2296. end
  2297. else
  2298. if ( CanShowUIPanels(frame, leftFrame, centerFrame) ) then
  2299. -- Shift both
  2300. self:MoveUIPanel("center", "right", UIPANEL_SKIP_SET_POINT);
  2301. self:MoveUIPanel("left", "center", UIPANEL_SKIP_SET_POINT);
  2302. self:SetUIPanel("left", frame);
  2303. else
  2304. -- Replace left
  2305. self:SetUIPanel("left", frame);
  2306. end
  2307. end
  2308. elseif ( framePushable <= centerPushable and centerArea ~= "center" and CanShowUIPanels(leftFrame, frame, centerFrame) ) then
  2309. -- Push center
  2310. self:MoveUIPanel("center", "right", UIPANEL_SKIP_SET_POINT);
  2311. self:SetUIPanel("center", frame);
  2312. elseif ( framePushable <= centerPushable and centerArea ~= "center" ) then
  2313. -- Replace left
  2314. self:SetUIPanel("left", frame);
  2315. else
  2316. -- Replace center
  2317. self:SetUIPanel("center", frame);
  2318. end
  2319. return;
  2320. end
  2321. -- If there's only one open...
  2322. if ( not centerFrame ) then
  2323. -- If neither is pushable, replace
  2324. if ( (leftPushable == 0) and (framePushable == 0) ) then
  2325. self:SetUIPanel("left", frame);
  2326. return;
  2327. end
  2328. -- Highest priority goes to center
  2329. if ( leftPushable > framePushable ) then
  2330. self:MoveUIPanel("left", "center", UIPANEL_SKIP_SET_POINT);
  2331. self:SetUIPanel("left", frame);
  2332. else
  2333. self:SetUIPanel("center", frame);
  2334. end
  2335. return;
  2336. end
  2337. -- Three are shown
  2338. local rightPushable = GetUIPanelWindowInfo(rightFrame, "pushable") or 0;
  2339. if ( framePushable > rightPushable ) then
  2340. -- This one is highest priority, slide the other two over
  2341. if ( CanShowUIPanels(centerFrame, rightFrame, frame) ) then
  2342. self:MoveUIPanel("center", "left", UIPANEL_SKIP_SET_POINT);
  2343. self:MoveUIPanel("right", "center", UIPANEL_SKIP_SET_POINT);
  2344. self:SetUIPanel("right", frame);
  2345. else
  2346. self:MoveUIPanel("right", "left", UIPANEL_SKIP_SET_POINT);
  2347. self:SetUIPanel("center", frame);
  2348. end
  2349. elseif ( framePushable > centerPushable ) then
  2350. -- This one is middle priority, so move the center frame to the left
  2351. self:MoveUIPanel("center", "left", UIPANEL_SKIP_SET_POINT);
  2352. self:SetUIPanel("center", frame);
  2353. else
  2354. self:SetUIPanel("left", frame);
  2355. end
  2356. end
  2357. function FramePositionDelegate:ShowUIPanelFailed(frame)
  2358. if GetUIPanelWindowInfo(frame, "showFailedFunc") then
  2359. frame:ExecuteAttribute("UIPanelLayout-showFailedFunc");
  2360. end
  2361. end
  2362. function FramePositionDelegate:SetUIPanel(key, frame, skipSetPoint)
  2363. if ( key == "fullscreen" ) then
  2364. local oldFrame = self.fullscreen;
  2365. self.fullscreen = frame;
  2366. if ( oldFrame ) then
  2367. oldFrame:Hide();
  2368. end
  2369. if ( frame ) then
  2370. UIParent:Hide();
  2371. frame:Show();
  2372. else
  2373. UIParent:Show();
  2374. SetUIVisibility(true);
  2375. end
  2376. return;
  2377. elseif ( key == "doublewide" ) then
  2378. local oldLeft = self.left;
  2379. local oldCenter = self.center;
  2380. local oldDoubleWide = self.doublewide;
  2381. self.doublewide = frame;
  2382. self.left = nil;
  2383. self.center = nil;
  2384. if ( oldDoubleWide ) then
  2385. oldDoubleWide:Hide();
  2386. end
  2387. if ( oldLeft ) then
  2388. oldLeft:Hide();
  2389. end
  2390. if ( oldCenter ) then
  2391. oldCenter:Hide();
  2392. end
  2393. elseif ( key ~= "left" and key ~= "center" and key ~= "right" ) then
  2394. return;
  2395. else
  2396. local oldFrame = self[key];
  2397. self[key] = frame;
  2398. if ( oldFrame ) then
  2399. oldFrame:Hide();
  2400. else
  2401. if ( self.doublewide ) then
  2402. if ( key == "left" or key == "center" ) then
  2403. self.doublewide:Hide();
  2404. self.doublewide = nil;
  2405. end
  2406. end
  2407. end
  2408. end
  2409. if ( not skipSetPoint ) then
  2410. securecall("UpdateUIPanelPositions", frame);
  2411. end
  2412. if ( frame ) then
  2413. frame:Show();
  2414. -- Hide all child windows
  2415. securecall("CloseChildWindows");
  2416. end
  2417. end
  2418. function FramePositionDelegate:MoveUIPanel(current, new, skipSetPoint, skipOperationUnlessCurrentIsValid)
  2419. if ( current ~= "left" and current ~= "center" and current ~= "right" and new ~= "left" and new ~= "center" and new ~= "right" ) then
  2420. return;
  2421. end
  2422. if skipOperationUnlessCurrentIsValid and not self[current] then
  2423. return;
  2424. end
  2425. self:SetUIPanel(new, nil, skipSetPoint);
  2426. if ( self[current] ) then
  2427. self[current]:Raise();
  2428. self[new] = self[current];
  2429. self[current] = nil;
  2430. if ( not skipSetPoint ) then
  2431. securecall("UpdateUIPanelPositions", self[new]);
  2432. end
  2433. end
  2434. end
  2435. function FramePositionDelegate:HideUIPanel(frame, skipSetPoint)
  2436. -- If we're hiding the full-screen frame, just hide it
  2437. if ( frame == self:GetUIPanel("fullscreen") ) then
  2438. self:SetUIPanel("fullscreen", nil);
  2439. return;
  2440. end
  2441. -- If we're hiding the right frame, just hide it
  2442. if ( frame == self:GetUIPanel("right") ) then
  2443. self:SetUIPanel("right", nil, skipSetPoint);
  2444. return;
  2445. elseif ( frame == self:GetUIPanel("doublewide") ) then
  2446. -- Slide over any right frame (hides the doublewide)
  2447. self:MoveUIPanel("right", "left", skipSetPoint);
  2448. return;
  2449. end
  2450. -- If we're hiding the center frame, slide over any right frame
  2451. local centerFrame = self:GetUIPanel("center");
  2452. if ( frame == centerFrame ) then
  2453. self:MoveUIPanel("right", "center", skipSetPoint);
  2454. elseif ( frame == self:GetUIPanel("left") ) then
  2455. -- If we're hiding the left frame, move the other frames left, unless the center is a native center frame
  2456. if ( centerFrame ) then
  2457. local area = GetUIPanelWindowInfo(centerFrame, "area");
  2458. if ( area ) then
  2459. if ( area == "center" ) then
  2460. -- Slide left, skip the center
  2461. self:MoveUIPanel("right", "left", skipSetPoint);
  2462. return;
  2463. else
  2464. -- Slide everything left
  2465. self:MoveUIPanel("center", "left", UIPANEL_SKIP_SET_POINT);
  2466. self:MoveUIPanel("right", "center", skipSetPoint);
  2467. return;
  2468. end
  2469. end
  2470. end
  2471. self:SetUIPanel("left", nil, skipSetPoint);
  2472. else
  2473. frame:Hide();
  2474. end
  2475. end
  2476. function FramePositionDelegate:GetUIPanel(key)
  2477. if ( key ~= "left" and key ~= "center" and key ~= "right" and key ~= "doublewide" and key ~= "fullscreen" ) then
  2478. return nil;
  2479. end
  2480. return self[key];
  2481. end
  2482. function FramePositionDelegate:UpdateUIPanelPositions(currentFrame)
  2483. if ( self.updatingPanels ) then
  2484. return;
  2485. end
  2486. self.updatingPanels = true;
  2487. local topOffset = UIParent:GetAttribute("TOP_OFFSET");
  2488. local leftOffset = UIParent:GetAttribute("LEFT_OFFSET");
  2489. local centerOffset = UIParent:GetAttribute("CENTER_OFFSET");
  2490. local rightOffset = UIParent:GetAttribute("RIGHT_OFFSET");
  2491. local xSpacing = UIParent:GetAttribute("PANEl_SPACING_X");
  2492. local info;
  2493. local frame = self:GetUIPanel("left");
  2494. if ( frame ) then
  2495. local xOff = GetUIPanelWindowInfo(frame,"xoffset") or 0;
  2496. local yOff = GetUIPanelWindowInfo(frame,"yoffset") or 0;
  2497. local bottomClampOverride = GetUIPanelWindowInfo(frame,"bottomClampOverride");
  2498. local minYOffset = GetUIPanelWindowInfo(frame,"minYOffset");
  2499. local yPos = ClampUIPanelY(frame, yOff + topOffset, minYOffset, bottomClampOverride);
  2500. frame:ClearAllPoints();
  2501. frame:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", leftOffset + xOff, yPos);
  2502. centerOffset = leftOffset + GetUIPanelWidth(frame) + xOff;
  2503. UIParent:SetAttribute("CENTER_OFFSET", centerOffset);
  2504. frame:Raise();
  2505. else
  2506. centerOffset = leftOffset;
  2507. UIParent:SetAttribute("CENTER_OFFSET", centerOffset);
  2508. frame = self:GetUIPanel("doublewide");
  2509. if ( frame ) then
  2510. local xOff = GetUIPanelWindowInfo(frame,"xoffset") or 0;
  2511. local yOff = GetUIPanelWindowInfo(frame,"yoffset") or 0;
  2512. local bottomClampOverride = GetUIPanelWindowInfo(frame,"bottomClampOverride");
  2513. local minYOffset = GetUIPanelWindowInfo(frame,"minYOffset");
  2514. local yPos = ClampUIPanelY(frame, yOff + topOffset, minYOffset, bottomClampOverride);
  2515. frame:ClearAllPoints();
  2516. frame:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", leftOffset + xOff, yPos);
  2517. rightOffset = leftOffset + GetUIPanelWidth(frame) + xOff;
  2518. UIParent:SetAttribute("RIGHT_OFFSET", rightOffset);
  2519. frame:Raise();
  2520. end
  2521. end
  2522. frame = self:GetUIPanel("center");
  2523. if ( frame ) then
  2524. if ( CanShowCenterUIPanel(frame) ) then
  2525. local area = GetUIPanelWindowInfo(frame, "area");
  2526. local xOff = GetUIPanelWindowInfo(frame,"xoffset") or 0;
  2527. local yOff = GetUIPanelWindowInfo(frame,"yoffset") or 0;
  2528. local bottomClampOverride = GetUIPanelWindowInfo(frame,"bottomClampOverride");
  2529. local minYOffset = GetUIPanelWindowInfo(frame,"minYOffset");
  2530. local yPos = ClampUIPanelY(frame, yOff + topOffset, minYOffset, bottomClampOverride);
  2531. if ( area ~= "center" ) then
  2532. frame:ClearAllPoints();
  2533. xOff = xOff + xSpacing; -- add separating space
  2534. frame:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", centerOffset + xOff, yPos);
  2535. end
  2536. rightOffset = centerOffset + GetUIPanelWidth(frame) + xOff;
  2537. else
  2538. if ( frame == currentFrame ) then
  2539. frame = self:GetUIPanel("left") or self:GetUIPanel("doublewide");
  2540. if ( frame ) then
  2541. self:HideUIPanel(frame);
  2542. self.updatingPanels = nil;
  2543. self:UpdateUIPanelPositions(currentFrame);
  2544. return;
  2545. end
  2546. end
  2547. self:SetUIPanel("center", nil, 1);
  2548. rightOffset = centerOffset + UIParent:GetAttribute("DEFAULT_FRAME_WIDTH");
  2549. end
  2550. frame:Raise();
  2551. elseif ( not self:GetUIPanel("doublewide") ) then
  2552. if ( self:GetUIPanel("left") ) then
  2553. rightOffset = centerOffset + UIParent:GetAttribute("DEFAULT_FRAME_WIDTH");
  2554. else
  2555. rightOffset = leftOffset + UIParent:GetAttribute("DEFAULT_FRAME_WIDTH") * 2
  2556. end
  2557. end
  2558. UIParent:SetAttribute("RIGHT_OFFSET", rightOffset);
  2559. frame = self:GetUIPanel("right");
  2560. if ( frame ) then
  2561. if ( CanShowRightUIPanel(frame) ) then
  2562. local xOff = GetUIPanelWindowInfo(frame,"xoffset") or 0;
  2563. local yOff = GetUIPanelWindowInfo(frame,"yoffset") or 0;
  2564. local bottomClampOverride = GetUIPanelWindowInfo(frame,"bottomClampOverride");
  2565. local minYOffset = GetUIPanelWindowInfo(frame,"minYOffset");
  2566. local yPos = ClampUIPanelY(frame, yOff + topOffset, minYOffset, bottomClampOverride);
  2567. xOff = xOff + xSpacing; -- add separating space
  2568. frame:ClearAllPoints();
  2569. frame:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", rightOffset + xOff, yPos);
  2570. else
  2571. if ( frame == currentFrame ) then
  2572. frame = GetUIPanel("center") or GetUIPanel("left") or GetUIPanel("doublewide");
  2573. if ( frame ) then
  2574. self:HideUIPanel(frame);
  2575. self.updatingPanels = nil;
  2576. self:UpdateUIPanelPositions(currentFrame);
  2577. return;
  2578. end
  2579. end
  2580. self:SetUIPanel("right", nil, 1);
  2581. end
  2582. frame:Raise();
  2583. end
  2584. if ( currentFrame and GetUIPanelWindowInfo(currentFrame, "checkFit") == 1 ) then
  2585. self:UpdateScaleForFit(currentFrame);
  2586. end
  2587. self.updatingPanels = nil;
  2588. end
  2589. function FramePositionDelegate:UpdateScaleForFit(frame)
  2590. local horizRatio = UIParent:GetWidth() / GetUIPanelWidth(frame);
  2591. local vertRatio = UIParent:GetHeight() / GetUIPanelHeight(frame);
  2592. if ( horizRatio < 1 or vertRatio < 1 ) then
  2593. frame:SetScale(min(horizRatio, vertRatio));
  2594. else
  2595. frame:SetScale(1);
  2596. end
  2597. end
  2598. function FramePositionDelegate:UIParentManageFramePositions()
  2599. UIPARENT_VARIABLE_OFFSETS["rightActionBarsX"] = VerticalMultiBarsContainer:GetWidth();
  2600. -- Update the variable with the happy magic number.
  2601. UpdateMenuBarTop();
  2602. -- Frames that affect offsets in y axis
  2603. local yOffsetFrames = {};
  2604. -- Frames that affect offsets in x axis
  2605. local xOffsetFrames = {};
  2606. -- Set up flags
  2607. local hasBottomLeft, hasBottomRight, hasPetBar;
  2608. if ( not PlayerPowerBarAlt:IsUserPlaced() ) then
  2609. local barInfo = GetUnitPowerBarInfo(PlayerPowerBarAlt.unit);
  2610. if ( PlayerPowerBarAlt:IsShown() and barInfo and barInfo.anchorTop ) then
  2611. PlayerPowerBarAlt:ClearAllPoints();
  2612. UIPARENT_MANAGED_FRAME_POSITIONS["PlayerPowerBarAlt"] = UIPARENT_ALTERNATE_FRAME_POSITIONS["PlayerPowerBarAlt_Top"];
  2613. else
  2614. PlayerPowerBarAlt:ClearAllPoints();
  2615. UIPARENT_MANAGED_FRAME_POSITIONS["PlayerPowerBarAlt"] = UIPARENT_ALTERNATE_FRAME_POSITIONS["PlayerPowerBarAlt_Bottom"];
  2616. end
  2617. end
  2618. if ( OverrideActionBar and OverrideActionBar:IsShown() ) then
  2619. tinsert(yOffsetFrames, "overrideActionBar");
  2620. elseif ( PetBattleFrame and PetBattleFrame:IsShown() ) then
  2621. tinsert(yOffsetFrames, "petBattleFrame");
  2622. else
  2623. if ( MultiBarBottomLeft:IsShown() or MultiBarBottomRight:IsShown() ) then
  2624. tinsert(yOffsetFrames, "bottomEither");
  2625. end
  2626. if ( MultiBarBottomRight:IsShown() ) then
  2627. tinsert(yOffsetFrames, "bottomRight");
  2628. hasBottomRight = 1;
  2629. end
  2630. if ( MultiBarBottomLeft:IsShown() ) then
  2631. tinsert(yOffsetFrames, "bottomLeft");
  2632. hasBottomLeft = 1;
  2633. end
  2634. -- TODO: Leaving this here for now since ChatFrame2 references it. Do we still need ChatFrame2 to be managed?
  2635. if ( MultiBarRight:IsShown() ) then
  2636. tinsert(xOffsetFrames, "rightRight");
  2637. end
  2638. if ( MultiBarRight:IsShown() ) then
  2639. tinsert(xOffsetFrames, "rightActionBarsX");
  2640. end
  2641. if (PetActionBarFrame_IsAboveStance and PetActionBarFrame_IsAboveStance()) then
  2642. tinsert(yOffsetFrames, "justBottomRightAndStance");
  2643. end
  2644. if ( ( PetActionBarFrame and PetActionBarFrame:IsShown() ) or ( StanceBarFrame and StanceBarFrame:IsShown() ) or
  2645. ( MultiCastActionBarFrame and MultiCastActionBarFrame:IsShown() ) or ( PossessBarFrame and PossessBarFrame:IsShown() ) or
  2646. ( MainMenuBarVehicleLeaveButton and MainMenuBarVehicleLeaveButton:IsShown() ) ) then
  2647. tinsert(yOffsetFrames, "pet");
  2648. hasPetBar = 1;
  2649. end
  2650. if ( TutorialFrameAlertButton:IsShown() ) then
  2651. tinsert(yOffsetFrames, "tutorialAlert");
  2652. end
  2653. if ( PlayerPowerBarAlt:IsShown() and not PlayerPowerBarAlt:IsUserPlaced() ) then
  2654. local barInfo = GetUnitPowerBarInfo(PlayerPowerBarAlt.unit);
  2655. if ( not barInfo or not barInfo.anchorTop ) then
  2656. tinsert(yOffsetFrames, "playerPowerBarAlt");
  2657. end
  2658. end
  2659. if UIWidgetPowerBarContainerFrame and UIWidgetPowerBarContainerFrame:GetNumWidgetsShowing() > 0 then
  2660. tinsert(yOffsetFrames, "powerBarWidgets");
  2661. end
  2662. if (ExtraActionBarFrame and ExtraActionBarFrame:IsShown() ) then
  2663. tinsert(yOffsetFrames, "extraActionBarFrame");
  2664. end
  2665. if (ZoneAbilityFrame and ZoneAbilityFrame:IsShown()) then
  2666. tinsert(yOffsetFrames, "ZoneAbilityFrame");
  2667. end
  2668. if ( TalkingHeadFrame and TalkingHeadFrame:IsShown() ) then
  2669. tinsert(yOffsetFrames, "talkingHeadFrame");
  2670. end
  2671. if ( ClassResourceOverlayParentFrame and ClassResourceOverlayParentFrame:IsShown() ) then
  2672. tinsert(yOffsetFrames, "classResourceOverlayFrame");
  2673. tinsert(yOffsetFrames, "classResourceOverlayOffset");
  2674. end
  2675. if ( CastingBarFrame and not CastingBarFrame:GetAttribute("ignoreFramePositionManager") ) then
  2676. tinsert(yOffsetFrames, "castingBar");
  2677. end
  2678. end
  2679. if ( menuBarTop == 55 ) then
  2680. UIPARENT_MANAGED_FRAME_POSITIONS["TutorialFrameAlertButton"].yOffset = -10;
  2681. else
  2682. UIPARENT_MANAGED_FRAME_POSITIONS["TutorialFrameAlertButton"].yOffset = -30;
  2683. end
  2684. -- Iterate through frames and set anchors according to the flags set
  2685. for index, value in pairs(UIPARENT_MANAGED_FRAME_POSITIONS) do
  2686. if ( value.playerPowerBarAlt and PlayerPowerBarAlt and not PlayerPowerBarAlt:IsUserPlaced()) then
  2687. value.playerPowerBarAlt = PlayerPowerBarAlt:GetHeight() + 10;
  2688. end
  2689. if ( value.powerBarWidgets and UIWidgetPowerBarContainerFrame ) then
  2690. value.powerBarWidgets = UIWidgetPowerBarContainerFrame:GetHeight() + 10;
  2691. end
  2692. if ( value.extraActionBarFrame and ExtraActionBarFrame ) then
  2693. value.extraActionBarFrame = ExtraActionBarFrame:GetHeight() + 10;
  2694. end
  2695. if ( value.ZoneAbilityFrame and ZoneAbilityFrame ) then
  2696. value.ZoneAbilityFrame = ZoneAbilityFrame:GetHeight() + 10;
  2697. end
  2698. if ( value.bonusActionBar and BonusActionBarFrame ) then
  2699. value.bonusActionBar = BonusActionBarFrame:GetHeight() - MainMenuBar:GetHeight();
  2700. end
  2701. if ( value.castingBar ) then
  2702. value.castingBar = CastingBarFrame:GetHeight() + 14;
  2703. end
  2704. if ( value.talkingHeadFrame and TalkingHeadFrame and TalkingHeadFrame:IsShown() ) then
  2705. value.talkingHeadFrame = TalkingHeadFrame:GetHeight() - 10;
  2706. end
  2707. if ( ClassResourceOverlayParentFrame and ClassResourceOverlayParentFrame:IsShown() ) then
  2708. if ( value.classResourceOverlayFrame ) then
  2709. value.classResourceOverlayFrame = ClassResourceOverlayParentFrame:GetHeight() + 10;
  2710. end
  2711. if ( value.classResourceOverlayOffset ) then
  2712. value.classResourceOverlayOffset = -20;
  2713. end
  2714. end
  2715. securecall("UIParent_ManageFramePosition", index, value, yOffsetFrames, xOffsetFrames, hasBottomLeft, hasBottomRight, hasPetBar);
  2716. end
  2717. -- Custom positioning not handled by the loop
  2718. -- MainMenuBar
  2719. if not MainMenuBar:IsUserPlaced() and not MicroButtonAndBagsBar:IsUserPlaced() then
  2720. local screenWidth = UIParent:GetWidth();
  2721. local barScale = 1;
  2722. local barWidth = MainMenuBar:GetWidth();
  2723. local barMargin = MAIN_MENU_BAR_MARGIN;
  2724. local bagsWidth = MicroButtonAndBagsBar:GetWidth();
  2725. local contentsWidth = barWidth + bagsWidth;
  2726. if contentsWidth > screenWidth then
  2727. barScale = screenWidth / contentsWidth;
  2728. barWidth = barWidth * barScale;
  2729. bagsWidth = bagsWidth * barScale;
  2730. barMargin = barMargin * barScale;
  2731. end
  2732. MainMenuBar:SetScale(barScale);
  2733. MainMenuBar:ClearAllPoints();
  2734. -- if there's no overlap with between action bar and bag bar while it's in the center, use center anchor
  2735. local roomLeft = screenWidth - barWidth - barMargin * 2;
  2736. if roomLeft >= bagsWidth * 2 then
  2737. MainMenuBar:SetPoint("BOTTOM", UIParent, 0, MainMenuBar:GetYOffset());
  2738. else
  2739. local xOffset = 0;
  2740. -- if both bars can fit without overlap, move the action bar to the left
  2741. -- otherwise sacrifice the art for more room
  2742. if roomLeft >= bagsWidth then
  2743. xOffset = roomLeft - bagsWidth + barMargin;
  2744. else
  2745. xOffset = math.max((roomLeft - bagsWidth) / 2 + barMargin, 0);
  2746. end
  2747. MainMenuBar:SetPoint("BOTTOMLEFT", UIParent, xOffset / barScale, MainMenuBar:GetYOffset());
  2748. end
  2749. end
  2750. -- Update Stance bar appearance
  2751. if ( MultiBarBottomLeft:IsShown() ) then
  2752. SlidingActionBarTexture0:Hide();
  2753. SlidingActionBarTexture1:Hide();
  2754. if ( StanceBarFrame ) then
  2755. StanceBarLeft:Hide();
  2756. StanceBarRight:Hide();
  2757. StanceBarMiddle:Hide();
  2758. for i=1, NUM_STANCE_SLOTS do
  2759. _G["StanceButton"..i]:GetNormalTexture():SetWidth(52);
  2760. _G["StanceButton"..i]:GetNormalTexture():SetHeight(52);
  2761. end
  2762. end
  2763. else
  2764. if (PetActionBarFrame_IsAboveStance and PetActionBarFrame_IsAboveStance()) then
  2765. SlidingActionBarTexture0:Hide();
  2766. SlidingActionBarTexture1:Hide();
  2767. else
  2768. SlidingActionBarTexture0:Show();
  2769. SlidingActionBarTexture1:Show();
  2770. end
  2771. if ( StanceBarFrame ) then
  2772. if ( GetNumShapeshiftForms() > 2 ) then
  2773. StanceBarMiddle:Show();
  2774. end
  2775. StanceBarLeft:Show();
  2776. StanceBarRight:Show();
  2777. for i=1, NUM_STANCE_SLOTS do
  2778. _G["StanceButton"..i]:GetNormalTexture():SetWidth(64);
  2779. _G["StanceButton"..i]:GetNormalTexture():SetHeight(64);
  2780. end
  2781. end
  2782. end
  2783. -- HACK: we have too many bars in this game now...
  2784. -- if the Stance bar is shown then hide the multi-cast bar
  2785. -- we'll have to figure out what we should do in this case if it ever really becomes a problem
  2786. -- HACK 2: if the possession bar is shown then hide the multi-cast bar
  2787. -- yeah, way too many bars...
  2788. if ( ( StanceBarFrame and StanceBarFrame:IsShown() ) or
  2789. ( PossessBarFrame and PossessBarFrame:IsShown() ) ) then
  2790. HideMultiCastActionBar();
  2791. elseif ( HasMultiCastActionBar and HasMultiCastActionBar() ) then
  2792. ShowMultiCastActionBar();
  2793. end
  2794. -- If petactionbar is already shown, set its point in addition to changing its y target
  2795. if ( PetActionBarFrame:IsShown() ) then
  2796. PetActionBar_UpdatePositionValues();
  2797. PetActionBarFrame:SetPoint("TOPLEFT", MainMenuBar, "BOTTOMLEFT", PETACTIONBAR_XPOS, PETACTIONBAR_YPOS);
  2798. end
  2799. -- Set battlefield minimap position
  2800. if ( BattlefieldMapTab and not BattlefieldMapTab:IsUserPlaced() ) then
  2801. BattlefieldMapTab:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMRIGHT", -BATTLEFIELD_MAP_WIDTH-CONTAINER_OFFSET_X, BATTLEFIELD_TAB_OFFSET_Y);
  2802. end
  2803. -- Setup y anchors
  2804. local anchorY = 0
  2805. local buffsAnchorY = min(0, (MINIMAP_BOTTOM_EDGE_EXTENT or 0) - BuffFrame.bottomEdgeExtent);
  2806. -- Count right action bars
  2807. local rightActionBars = 0;
  2808. if ( IsNormalActionBarState() ) then
  2809. if ( SHOW_MULTI_ACTIONBAR_3 ) then
  2810. rightActionBars = 1;
  2811. if ( SHOW_MULTI_ACTIONBAR_4 ) then
  2812. rightActionBars = 2;
  2813. end
  2814. end
  2815. end
  2816. -- BelowMinimap Widgets - need to move below buffs/debuffs if at least 1 right action bar is showing
  2817. if UIWidgetBelowMinimapContainerFrame and UIWidgetBelowMinimapContainerFrame:GetNumWidgetsShowing() > 0 then
  2818. if rightActionBars > 0 then
  2819. anchorY = min(anchorY, buffsAnchorY);
  2820. end
  2821. UIWidgetBelowMinimapContainerFrame:ClearAllPoints();
  2822. UIWidgetBelowMinimapContainerFrame:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
  2823. anchorY = anchorY - UIWidgetBelowMinimapContainerFrame:GetHeight() - 4;
  2824. end
  2825. --Setup Vehicle seat indicator offset - needs to move below buffs/debuffs if both right action bars are showing
  2826. if ( VehicleSeatIndicator and VehicleSeatIndicator:IsShown() ) then
  2827. if ( rightActionBars == 2 ) then
  2828. anchorY = min(anchorY, buffsAnchorY);
  2829. VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -100, anchorY);
  2830. elseif ( rightActionBars == 1 ) then
  2831. VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -62, anchorY);
  2832. else
  2833. VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", 0, anchorY);
  2834. end
  2835. anchorY = anchorY - VehicleSeatIndicator:GetHeight() - 4; --The -4 is there to give a small buffer for things like the QuestTimeFrame below the Seat Indicator
  2836. end
  2837. -- Boss frames - need to move below buffs/debuffs if both right action bars are showing
  2838. local numBossFrames = 0;
  2839. for i = 1, MAX_BOSS_FRAMES do
  2840. if ( _G["Boss"..i.."TargetFrame"]:IsShown() ) then
  2841. numBossFrames = i;
  2842. end
  2843. end
  2844. if ( numBossFrames > 0 ) then
  2845. if ( rightActionBars > 1 ) then
  2846. anchorY = min(anchorY, buffsAnchorY);
  2847. end
  2848. Boss1TargetFrame:SetPoint("TOPRIGHT", "MinimapCluster", "BOTTOMRIGHT", -(CONTAINER_OFFSET_X * 1.3) + 60, anchorY * 1.333); -- by 1.333 because it's 0.75 scale
  2849. anchorY = anchorY - (numBossFrames * (68 + BOSS_FRAME_CASTBAR_HEIGHT) + BOSS_FRAME_CASTBAR_HEIGHT);
  2850. end
  2851. -- Setup durability offset
  2852. if ( DurabilityFrame ) then
  2853. DurabilityFrame:SetPoint("TOPRIGHT", "MinimapCluster", "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
  2854. if ( DurabilityFrame:IsShown() ) then
  2855. anchorY = anchorY - DurabilityFrame:GetHeight();
  2856. end
  2857. end
  2858. if ( ArenaEnemyFrames ) then
  2859. ArenaEnemyFrames:ClearAllPoints();
  2860. ArenaEnemyFrames:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
  2861. end
  2862. if ( ArenaPrepFrames ) then
  2863. ArenaPrepFrames:ClearAllPoints();
  2864. ArenaPrepFrames:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
  2865. end
  2866. -- ObjectiveTracker - needs to move below buffs/debuffs if at least 1 right action bar is showing
  2867. if ( rightActionBars > 0 ) then
  2868. anchorY = min(anchorY, buffsAnchorY);
  2869. end
  2870. if ( ObjectiveTrackerFrame and not ObjectiveTrackerFrame:IsUserPlaced() ) then
  2871. local numArenaOpponents = GetNumArenaOpponents();
  2872. if ( ArenaEnemyFrames and ArenaEnemyFrames:IsShown() and (numArenaOpponents > 0) ) then
  2873. ObjectiveTrackerFrame:ClearAllPoints();
  2874. ObjectiveTrackerFrame:SetPoint("TOPRIGHT", ArenaEnemyFrames_GetBestAnchorUnitFrameForOppponent(numArenaOpponents), "BOTTOMRIGHT", 2, -35);
  2875. elseif ( ArenaPrepFrames and ArenaPrepFrames:IsShown() and (numArenaOpponents > 0) ) then
  2876. ObjectiveTrackerFrame:ClearAllPoints();
  2877. ObjectiveTrackerFrame:SetPoint("TOPRIGHT", ArenaPrepFrames_GetBestAnchorUnitFrameForOppponent(numArenaOpponents), "BOTTOMRIGHT", 2, -35);
  2878. else
  2879. -- We're using Simple Quest Tracking, automagically size and position!
  2880. ObjectiveTrackerFrame:ClearAllPoints();
  2881. -- move up if only the minimap cluster is above, move down a little otherwise
  2882. ObjectiveTrackerFrame:SetPoint("TOPRIGHT", "MinimapCluster", "BOTTOMRIGHT", -OBJTRACKER_OFFSET_X, anchorY);
  2883. end
  2884. ObjectiveTrackerFrame:SetPoint("BOTTOMRIGHT", "UIParent", "BOTTOMRIGHT", -OBJTRACKER_OFFSET_X, CONTAINER_OFFSET_Y);
  2885. end
  2886. -- Update chat dock since the dock could have moved
  2887. FCF_DockUpdate();
  2888. UpdateContainerFrameAnchors();
  2889. end
  2890. -- Call this function to update the positions of all frames that can appear on the right side of the screen
  2891. function UIParent_ManageFramePositions()
  2892. --Dispatch to secure code
  2893. FramePositionDelegate:SetAttribute("uiparent-manage", true);
  2894. end
  2895. function ToggleFrame(frame)
  2896. if ( frame:IsShown() ) then
  2897. HideUIPanel(frame);
  2898. else
  2899. ShowUIPanel(frame);
  2900. end
  2901. end
  2902. -- We keep direct references to protect against replacement.
  2903. local InCombatLockdown = InCombatLockdown;
  2904. local issecure = issecure;
  2905. -- We no longer allow addons to show or hide UI panels in combat.
  2906. local function CheckProtectedFunctionsAllowed()
  2907. if ( InCombatLockdown() and not issecure() ) then
  2908. DisplayInterfaceActionBlockedMessage();
  2909. return false;
  2910. end
  2911. return true;
  2912. end
  2913. function ShowUIPanel(frame, force)
  2914. if ( not frame or frame:IsShown() ) then
  2915. return;
  2916. end
  2917. if ( not CheckProtectedFunctionsAllowed() ) then
  2918. return;
  2919. end
  2920. if ( not GetUIPanelWindowInfo(frame, "area") ) then
  2921. frame:Show();
  2922. return;
  2923. end
  2924. -- Dispatch to secure code
  2925. FramePositionDelegate:SetAttribute("panel-force", force);
  2926. FramePositionDelegate:SetAttribute("panel-frame", frame);
  2927. FramePositionDelegate:SetAttribute("panel-show", true);
  2928. end
  2929. function HideUIPanel(frame, skipSetPoint)
  2930. if ( not frame or not frame:IsShown() ) then
  2931. return;
  2932. end
  2933. if ( not CheckProtectedFunctionsAllowed() ) then
  2934. return;
  2935. end
  2936. if ( not GetUIPanelWindowInfo(frame, "area") ) then
  2937. frame:Hide();
  2938. return;
  2939. end
  2940. --Dispatch to secure code
  2941. FramePositionDelegate:SetAttribute("panel-frame", frame);
  2942. FramePositionDelegate:SetAttribute("panel-skipSetPoint", skipSetPoint);
  2943. FramePositionDelegate:SetAttribute("panel-hide", true);
  2944. end
  2945. function ShowOptionsPanel(optionsFrame, lastFrame, categoryToSelect)
  2946. -- NOTE: Toggle isn't currently necessary because showing an options panel hides everything else.
  2947. ShowUIPanel(optionsFrame);
  2948. optionsFrame.lastFrame = lastFrame;
  2949. if categoryToSelect then
  2950. OptionsFrame_OpenToCategory(optionsFrame, categoryToSelect);
  2951. end
  2952. end
  2953. function GetUIPanel(key)
  2954. return FramePositionDelegate:GetUIPanel(key);
  2955. end
  2956. function GetUIPanelWidth(frame)
  2957. return GetUIPanelWindowInfo(frame, "width") or frame:GetWidth() + (GetUIPanelWindowInfo(frame, "extraWidth") or 0);
  2958. end
  2959. function GetUIPanelHeight(frame)
  2960. return GetUIPanelWindowInfo(frame, "height") or frame:GetHeight() + (GetUIPanelWindowInfo(frame, "extraHeight") or 0);
  2961. end
  2962. --Allow a bit of overlap because there are built-in transparencies and buffers already
  2963. local MINIMAP_OVERLAP_ALLOWED = 60;
  2964. function GetMaxUIPanelsWidth()
  2965. --[[ local bufferBoundry = UIParent:GetRight() - UIParent:GetAttribute("RIGHT_OFFSET_BUFFER");
  2966. if ( Minimap:IsShown() and not MinimapCluster:IsUserPlaced() ) then
  2967. -- If the Minimap is in the default place, make sure you wont overlap it either
  2968. return min(MinimapCluster:GetLeft()+MINIMAP_OVERLAP_ALLOWED, bufferBoundry);
  2969. else
  2970. -- If the minimap has been moved, make sure not to overlap the right side bars
  2971. return bufferBoundry;
  2972. end
  2973. ]]
  2974. return UIParent:GetRight() - UIParent:GetAttribute("RIGHT_OFFSET_BUFFER");
  2975. end
  2976. function ClampUIPanelY(frame, yOffset, minYOffset, bottomClampOverride)
  2977. local bottomPos = UIParent:GetTop() + yOffset - GetUIPanelHeight(frame);
  2978. local bottomClamp = bottomClampOverride or 140;
  2979. if (bottomPos < bottomClamp) then
  2980. yOffset = yOffset + (bottomClamp - bottomPos);
  2981. end
  2982. if (yOffset > -10) then
  2983. yOffset = minYOffset or -10;
  2984. end
  2985. return yOffset;
  2986. end
  2987. function CanShowRightUIPanel(frame)
  2988. local width = frame and GetUIPanelWidth(frame) or UIParent:GetAttribute("DEFAULT_FRAME_WIDTH");
  2989. local rightSide = UIParent:GetAttribute("RIGHT_OFFSET") + width;
  2990. return rightSide < GetMaxUIPanelsWidth();
  2991. end
  2992. function CanShowCenterUIPanel(frame)
  2993. local width = frame and GetUIPanelWidth(frame) or UIParent:GetAttribute("DEFAULT_FRAME_WIDTH");
  2994. local rightSide = UIParent:GetAttribute("CENTER_OFFSET") + width;
  2995. return rightSide < GetMaxUIPanelsWidth();
  2996. end
  2997. function CanShowUIPanels(leftFrame, centerFrame, rightFrame)
  2998. local offset = UIParent:GetAttribute("LEFT_OFFSET");
  2999. if ( leftFrame ) then
  3000. offset = offset + GetUIPanelWidth(leftFrame);
  3001. if ( centerFrame ) then
  3002. local area = GetUIPanelWindowInfo(centerFrame, "area");
  3003. if ( area ~= "center" ) then
  3004. offset = offset + ( GetUIPanelWindowInfo(centerFrame, "width") or UIParent:GetAttribute("DEFAULT_FRAME_WIDTH") );
  3005. else
  3006. offset = offset + GetUIPanelWidth(centerFrame);
  3007. end
  3008. if ( rightFrame ) then
  3009. offset = offset + GetUIPanelWidth(rightFrame);
  3010. end
  3011. end
  3012. elseif ( centerFrame ) then
  3013. offset = GetUIPanelWidth(centerFrame);
  3014. end
  3015. if ( offset < GetMaxUIPanelsWidth() ) then
  3016. return 1;
  3017. end
  3018. end
  3019. function CanOpenPanels()
  3020. --[[
  3021. if ( UnitIsDead("player") ) then
  3022. return nil;
  3023. end
  3024. Previously couldn't open frames if player was out of control i.e. feared
  3025. if ( UnitIsDead("player") or UIParent.isOutOfControl ) then
  3026. return nil;
  3027. end
  3028. ]]
  3029. local centerFrame = GetUIPanel("center");
  3030. if ( not centerFrame ) then
  3031. return 1;
  3032. end
  3033. local area = GetUIPanelWindowInfo(centerFrame, "area");
  3034. local allowOtherPanels = GetUIPanelWindowInfo(centerFrame, "allowOtherPanels");
  3035. if ( area and (area == "center") and not allowOtherPanels ) then
  3036. return nil;
  3037. end
  3038. return 1;
  3039. end
  3040. -- this function handles possibly tainted values and so
  3041. -- should always be called from secure code using securecall()
  3042. function CloseChildWindows()
  3043. local childWindow;
  3044. for index, value in pairs(UIChildWindows) do
  3045. childWindow = _G[value];
  3046. if ( childWindow ) then
  3047. childWindow:Hide();
  3048. end
  3049. end
  3050. end
  3051. -- this function handles possibly tainted values and so
  3052. -- should always be called from secure code using securecall()
  3053. function CloseSpecialWindows()
  3054. local found;
  3055. for index, value in pairs(UISpecialFrames) do
  3056. local frame = _G[value];
  3057. if ( frame and frame:IsShown() ) then
  3058. frame:Hide();
  3059. found = 1;
  3060. end
  3061. end
  3062. return found;
  3063. end
  3064. function CloseWindows(ignoreCenter, frameToIgnore)
  3065. -- This function will close all frames that are not the current frame
  3066. local leftFrame = GetUIPanel("left");
  3067. local centerFrame = GetUIPanel("center");
  3068. local rightFrame = GetUIPanel("right");
  3069. local doublewideFrame = GetUIPanel("doublewide");
  3070. local fullScreenFrame = GetUIPanel("fullscreen");
  3071. local found = leftFrame or centerFrame or rightFrame or doublewideFrame or fullScreenFrame;
  3072. if ( not frameToIgnore or frameToIgnore ~= leftFrame ) then
  3073. HideUIPanel(leftFrame, UIPANEL_SKIP_SET_POINT);
  3074. end
  3075. HideUIPanel(fullScreenFrame, UIPANEL_SKIP_SET_POINT);
  3076. HideUIPanel(doublewideFrame, UIPANEL_SKIP_SET_POINT);
  3077. if ( not frameToIgnore or frameToIgnore ~= centerFrame ) then
  3078. if ( centerFrame ) then
  3079. local area = GetUIPanelWindowInfo(centerFrame, "area");
  3080. if ( area ~= "center" or not ignoreCenter ) then
  3081. HideUIPanel(centerFrame, UIPANEL_SKIP_SET_POINT);
  3082. end
  3083. end
  3084. end
  3085. if ( not frameToIgnore or frameToIgnore ~= rightFrame ) then
  3086. if ( rightFrame ) then
  3087. HideUIPanel(rightFrame, UIPANEL_SKIP_SET_POINT);
  3088. end
  3089. end
  3090. found = securecall("CloseSpecialWindows") or found;
  3091. UpdateUIPanelPositions();
  3092. return found;
  3093. end
  3094. function CloseAllWindows_WithExceptions()
  3095. -- When the player loses control we close all UIs, unless they're handled below
  3096. local centerFrame = GetUIPanel("center");
  3097. local ignoreCenter = (centerFrame and GetUIPanelWindowInfo(centerFrame, "ignoreControlLost")) or IsOptionFrameOpen();
  3098. CloseAllWindows(ignoreCenter);
  3099. end
  3100. function CloseAllWindows(ignoreCenter)
  3101. local bagsVisible = nil;
  3102. local windowsVisible = nil;
  3103. for i=1, NUM_CONTAINER_FRAMES, 1 do
  3104. local containerFrame = _G["ContainerFrame"..i];
  3105. if ( containerFrame:IsShown() ) then
  3106. containerFrame:Hide();
  3107. bagsVisible = 1;
  3108. end
  3109. end
  3110. windowsVisible = CloseWindows(ignoreCenter);
  3111. return (bagsVisible or windowsVisible);
  3112. end
  3113. -- this function handles possibly tainted values and so
  3114. -- should always be called from secure code using securecall()
  3115. function CloseMenus()
  3116. local menusVisible = nil;
  3117. local menu
  3118. for index, value in pairs(UIMenus) do
  3119. menu = _G[value];
  3120. if ( menu and menu:IsShown() ) then
  3121. menu:Hide();
  3122. menusVisible = 1;
  3123. end
  3124. end
  3125. return menusVisible;
  3126. end
  3127. function UpdateUIPanelPositions(currentFrame)
  3128. FramePositionDelegate:SetAttribute("panel-frame", currentFrame)
  3129. FramePositionDelegate:SetAttribute("panel-update", true);
  3130. end
  3131. function MaximizeUIPanel(currentFrame, maximizePoint)
  3132. FramePositionDelegate:SetAttribute("panel-frame", currentFrame)
  3133. FramePositionDelegate:SetAttribute("panel-maximize", true);
  3134. end
  3135. function RestoreUIPanelArea(currentFrame)
  3136. FramePositionDelegate:SetAttribute("panel-frame", currentFrame)
  3137. FramePositionDelegate:SetAttribute("panel-restore", true);
  3138. end
  3139. function IsOptionFrameOpen()
  3140. if ( GameMenuFrame:IsShown() or InterfaceOptionsFrame:IsShown() or (KeyBindingFrame and KeyBindingFrame:IsShown()) ) then
  3141. return 1;
  3142. else
  3143. return nil;
  3144. end
  3145. end
  3146. function LowerFrameLevel(frame)
  3147. frame:SetFrameLevel(frame:GetFrameLevel()-1);
  3148. end
  3149. function RaiseFrameLevel(frame)
  3150. frame:SetFrameLevel(frame:GetFrameLevel()+1);
  3151. end
  3152. function PassClickToParent(self, ...)
  3153. self:GetParent():Click(...);
  3154. end
  3155. -- Function to reposition frames if they get dragged off screen
  3156. function ValidateFramePosition(frame, offscreenPadding, returnOffscreen)
  3157. if ( not frame ) then
  3158. return;
  3159. end
  3160. local left = frame:GetLeft();
  3161. local right = frame:GetRight();
  3162. local top = frame:GetTop();
  3163. local bottom = frame:GetBottom();
  3164. local newAnchorX, newAnchorY;
  3165. if ( not offscreenPadding ) then
  3166. offscreenPadding = 15;
  3167. end
  3168. if ( bottom < (0 + MainMenuBar:GetHeight() + offscreenPadding)) then
  3169. -- Off the bottom of the screen
  3170. newAnchorY = MainMenuBar:GetHeight() + frame:GetHeight() - GetScreenHeight();
  3171. elseif ( top > GetScreenHeight() ) then
  3172. -- Off the top of the screen
  3173. newAnchorY = 0;
  3174. end
  3175. if ( left < 0 ) then
  3176. -- Off the left of the screen
  3177. newAnchorX = 0;
  3178. elseif ( right > GetScreenWidth() ) then
  3179. -- Off the right of the screen
  3180. newAnchorX = GetScreenWidth() - frame:GetWidth();
  3181. end
  3182. if ( newAnchorX or newAnchorY ) then
  3183. if ( returnOffscreen ) then
  3184. return 1;
  3185. else
  3186. if ( not newAnchorX ) then
  3187. newAnchorX = left;
  3188. elseif ( not newAnchorY ) then
  3189. newAnchorY = top - GetScreenHeight();
  3190. end
  3191. frame:ClearAllPoints();
  3192. frame:SetPoint("TOPLEFT", nil, "TOPLEFT", newAnchorX, newAnchorY);
  3193. end
  3194. else
  3195. if ( returnOffscreen ) then
  3196. return nil;
  3197. end
  3198. end
  3199. end
  3200. -- Time --
  3201. function RecentTimeDate(year, month, day, hour)
  3202. local lastOnline;
  3203. if ( (year == 0) or (year == nil) ) then
  3204. if ( (month == 0) or (month == nil) ) then
  3205. if ( (day == 0) or (day == nil) ) then
  3206. if ( (hour == 0) or (hour == nil) ) then
  3207. lastOnline = LASTONLINE_MINS;
  3208. else
  3209. lastOnline = format(LASTONLINE_HOURS, hour);
  3210. end
  3211. else
  3212. lastOnline = format(LASTONLINE_DAYS, day);
  3213. end
  3214. else
  3215. lastOnline = format(LASTONLINE_MONTHS, month);
  3216. end
  3217. else
  3218. lastOnline = format(LASTONLINE_YEARS, year);
  3219. end
  3220. return lastOnline;
  3221. end
  3222. -- Frame fading and flashing --
  3223. local frameFadeManager = CreateFrame("FRAME");
  3224. -- Generic fade function
  3225. function UIFrameFade(frame, fadeInfo)
  3226. if (not frame) then
  3227. return;
  3228. end
  3229. if ( not fadeInfo.mode ) then
  3230. fadeInfo.mode = "IN";
  3231. end
  3232. local alpha;
  3233. if ( fadeInfo.mode == "IN" ) then
  3234. if ( not fadeInfo.startAlpha ) then
  3235. fadeInfo.startAlpha = 0;
  3236. end
  3237. if ( not fadeInfo.endAlpha ) then
  3238. fadeInfo.endAlpha = 1.0;
  3239. end
  3240. alpha = 0;
  3241. elseif ( fadeInfo.mode == "OUT" ) then
  3242. if ( not fadeInfo.startAlpha ) then
  3243. fadeInfo.startAlpha = 1.0;
  3244. end
  3245. if ( not fadeInfo.endAlpha ) then
  3246. fadeInfo.endAlpha = 0;
  3247. end
  3248. alpha = 1.0;
  3249. end
  3250. frame:SetAlpha(fadeInfo.startAlpha);
  3251. frame.fadeInfo = fadeInfo;
  3252. frame:Show();
  3253. local index = 1;
  3254. while FADEFRAMES[index] do
  3255. -- If frame is already set to fade then return
  3256. if ( FADEFRAMES[index] == frame ) then
  3257. return;
  3258. end
  3259. index = index + 1;
  3260. end
  3261. tinsert(FADEFRAMES, frame);
  3262. frameFadeManager:SetScript("OnUpdate", UIFrameFade_OnUpdate);
  3263. end
  3264. -- Convenience function to do a simple fade in
  3265. function UIFrameFadeIn(frame, timeToFade, startAlpha, endAlpha)
  3266. local fadeInfo = {};
  3267. fadeInfo.mode = "IN";
  3268. fadeInfo.timeToFade = timeToFade;
  3269. fadeInfo.startAlpha = startAlpha;
  3270. fadeInfo.endAlpha = endAlpha;
  3271. UIFrameFade(frame, fadeInfo);
  3272. end
  3273. -- Convenience function to do a simple fade out
  3274. function UIFrameFadeOut(frame, timeToFade, startAlpha, endAlpha)
  3275. local fadeInfo = {};
  3276. fadeInfo.mode = "OUT";
  3277. fadeInfo.timeToFade = timeToFade;
  3278. fadeInfo.startAlpha = startAlpha;
  3279. fadeInfo.endAlpha = endAlpha;
  3280. UIFrameFade(frame, fadeInfo);
  3281. end
  3282. function UIFrameFadeRemoveFrame(frame)
  3283. tDeleteItem(FADEFRAMES, frame);
  3284. end
  3285. -- Function that actually performs the alpha change
  3286. --[[
  3287. Fading frame attribute listing
  3288. ============================================================
  3289. frame.timeToFade [Num] Time it takes to fade the frame in or out
  3290. frame.mode ["IN", "OUT"] Fade mode
  3291. frame.finishedFunc [func()] Function that is called when fading is finished
  3292. frame.finishedArg1 [ANYTHING] Argument to the finishedFunc
  3293. frame.finishedArg2 [ANYTHING] Argument to the finishedFunc
  3294. frame.finishedArg3 [ANYTHING] Argument to the finishedFunc
  3295. frame.finishedArg4 [ANYTHING] Argument to the finishedFunc
  3296. frame.fadeHoldTime [Num] Time to hold the faded state
  3297. ]]
  3298. function UIFrameFade_OnUpdate(self, elapsed)
  3299. local index = 1;
  3300. local frame, fadeInfo;
  3301. while FADEFRAMES[index] do
  3302. frame = FADEFRAMES[index];
  3303. fadeInfo = FADEFRAMES[index].fadeInfo;
  3304. -- Reset the timer if there isn't one, this is just an internal counter
  3305. if ( not fadeInfo.fadeTimer ) then
  3306. fadeInfo.fadeTimer = 0;
  3307. end
  3308. fadeInfo.fadeTimer = fadeInfo.fadeTimer + elapsed;
  3309. -- If the fadeTimer is less then the desired fade time then set the alpha otherwise hold the fade state, call the finished function, or just finish the fade
  3310. if ( fadeInfo.fadeTimer < fadeInfo.timeToFade ) then
  3311. if ( fadeInfo.mode == "IN" ) then
  3312. frame:SetAlpha((fadeInfo.fadeTimer / fadeInfo.timeToFade) * (fadeInfo.endAlpha - fadeInfo.startAlpha) + fadeInfo.startAlpha);
  3313. elseif ( fadeInfo.mode == "OUT" ) then
  3314. frame:SetAlpha(((fadeInfo.timeToFade - fadeInfo.fadeTimer) / fadeInfo.timeToFade) * (fadeInfo.startAlpha - fadeInfo.endAlpha) + fadeInfo.endAlpha);
  3315. end
  3316. else
  3317. frame:SetAlpha(fadeInfo.endAlpha);
  3318. -- If there is a fadeHoldTime then wait until its passed to continue on
  3319. if ( fadeInfo.fadeHoldTime and fadeInfo.fadeHoldTime > 0 ) then
  3320. fadeInfo.fadeHoldTime = fadeInfo.fadeHoldTime - elapsed;
  3321. else
  3322. -- Complete the fade and call the finished function if there is one
  3323. UIFrameFadeRemoveFrame(frame);
  3324. if ( fadeInfo.finishedFunc ) then
  3325. fadeInfo.finishedFunc(fadeInfo.finishedArg1, fadeInfo.finishedArg2, fadeInfo.finishedArg3, fadeInfo.finishedArg4);
  3326. fadeInfo.finishedFunc = nil;
  3327. end
  3328. end
  3329. end
  3330. index = index + 1;
  3331. end
  3332. if ( #FADEFRAMES == 0 ) then
  3333. self:SetScript("OnUpdate", nil);
  3334. end
  3335. end
  3336. function UIFrameIsFading(frame)
  3337. for index, value in pairs(FADEFRAMES) do
  3338. if ( value == frame ) then
  3339. return 1;
  3340. end
  3341. end
  3342. return nil;
  3343. end
  3344. local frameFlashManager = CreateFrame("FRAME");
  3345. local UIFrameFlashTimers = {};
  3346. local UIFrameFlashTimerRefCount = {};
  3347. -- Function to start a frame flashing
  3348. function UIFrameFlash(frame, fadeInTime, fadeOutTime, flashDuration, showWhenDone, flashInHoldTime, flashOutHoldTime, syncId)
  3349. if ( frame ) then
  3350. local index = 1;
  3351. -- If frame is already set to flash then return
  3352. while FLASHFRAMES[index] do
  3353. if ( FLASHFRAMES[index] == frame ) then
  3354. return;
  3355. end
  3356. index = index + 1;
  3357. end
  3358. if (syncId) then
  3359. frame.syncId = syncId;
  3360. if (UIFrameFlashTimers[syncId] == nil) then
  3361. UIFrameFlashTimers[syncId] = 0;
  3362. UIFrameFlashTimerRefCount[syncId] = 0;
  3363. end
  3364. UIFrameFlashTimerRefCount[syncId] = UIFrameFlashTimerRefCount[syncId]+1;
  3365. else
  3366. frame.syncId = nil;
  3367. end
  3368. -- Time it takes to fade in a flashing frame
  3369. frame.fadeInTime = fadeInTime;
  3370. -- Time it takes to fade out a flashing frame
  3371. frame.fadeOutTime = fadeOutTime;
  3372. -- How long to keep the frame flashing, -1 means forever
  3373. frame.flashDuration = flashDuration;
  3374. -- Show the flashing frame when the fadeOutTime has passed
  3375. frame.showWhenDone = showWhenDone;
  3376. -- Internal timer
  3377. frame.flashTimer = 0;
  3378. -- How long to hold the faded in state
  3379. frame.flashInHoldTime = flashInHoldTime;
  3380. -- How long to hold the faded out state
  3381. frame.flashOutHoldTime = flashOutHoldTime;
  3382. tinsert(FLASHFRAMES, frame);
  3383. frameFlashManager:SetScript("OnUpdate", UIFrameFlash_OnUpdate);
  3384. end
  3385. end
  3386. -- Called every frame to update flashing frames
  3387. function UIFrameFlash_OnUpdate(self, elapsed)
  3388. local frame;
  3389. local index = #FLASHFRAMES;
  3390. -- Update timers for all synced frames
  3391. for syncId, timer in pairs(UIFrameFlashTimers) do
  3392. UIFrameFlashTimers[syncId] = timer + elapsed;
  3393. end
  3394. while FLASHFRAMES[index] do
  3395. frame = FLASHFRAMES[index];
  3396. frame.flashTimer = frame.flashTimer + elapsed;
  3397. if ( (frame.flashTimer > frame.flashDuration) and frame.flashDuration ~= -1 ) then
  3398. UIFrameFlashStop(frame);
  3399. else
  3400. local flashTime = frame.flashTimer;
  3401. local alpha;
  3402. if (frame.syncId) then
  3403. flashTime = UIFrameFlashTimers[frame.syncId];
  3404. end
  3405. flashTime = flashTime%(frame.fadeInTime+frame.fadeOutTime+(frame.flashInHoldTime or 0)+(frame.flashOutHoldTime or 0));
  3406. if (flashTime < frame.fadeInTime) then
  3407. alpha = flashTime/frame.fadeInTime;
  3408. elseif (flashTime < frame.fadeInTime+(frame.flashInHoldTime or 0)) then
  3409. alpha = 1;
  3410. elseif (flashTime < frame.fadeInTime+(frame.flashInHoldTime or 0)+frame.fadeOutTime) then
  3411. alpha = 1 - ((flashTime - frame.fadeInTime - (frame.flashInHoldTime or 0))/frame.fadeOutTime);
  3412. else
  3413. alpha = 0;
  3414. end
  3415. frame:SetAlpha(alpha);
  3416. frame:Show();
  3417. end
  3418. -- Loop in reverse so that removing frames is safe
  3419. index = index - 1;
  3420. end
  3421. if ( #FLASHFRAMES == 0 ) then
  3422. self:SetScript("OnUpdate", nil);
  3423. end
  3424. end
  3425. -- Function to see if a frame is already flashing
  3426. function UIFrameIsFlashing(frame)
  3427. for index, value in pairs(FLASHFRAMES) do
  3428. if ( value == frame ) then
  3429. return 1;
  3430. end
  3431. end
  3432. return nil;
  3433. end
  3434. -- Function to stop flashing
  3435. function UIFrameFlashStop(frame)
  3436. tDeleteItem(FLASHFRAMES, frame);
  3437. frame:SetAlpha(1.0);
  3438. frame.flashTimer = nil;
  3439. if (frame.syncId) then
  3440. UIFrameFlashTimerRefCount[frame.syncId] = UIFrameFlashTimerRefCount[frame.syncId]-1;
  3441. if (UIFrameFlashTimerRefCount[frame.syncId] == 0) then
  3442. UIFrameFlashTimers[frame.syncId] = nil;
  3443. UIFrameFlashTimerRefCount[frame.syncId] = nil;
  3444. end
  3445. frame.syncId = nil;
  3446. end
  3447. if ( frame.showWhenDone ) then
  3448. frame:Show();
  3449. else
  3450. frame:Hide();
  3451. end
  3452. end
  3453. -- Functions to handle button pulsing (Highlight, Unhighlight)
  3454. function SetButtonPulse(button, duration, pulseRate)
  3455. button.pulseDuration = pulseRate;
  3456. button.pulseTimeLeft = duration
  3457. -- pulseRate is actually seconds per pulse state
  3458. button.pulseRate = pulseRate;
  3459. button.pulseOn = 0;
  3460. tinsert(PULSEBUTTONS, button);
  3461. end
  3462. -- Update the button pulsing
  3463. function ButtonPulse_OnUpdate(elapsed)
  3464. for index, button in pairs(PULSEBUTTONS) do
  3465. if ( button.pulseTimeLeft > 0 ) then
  3466. if ( button.pulseDuration < 0 ) then
  3467. if ( button.pulseOn == 1 ) then
  3468. button:UnlockHighlight();
  3469. button.pulseOn = 0;
  3470. else
  3471. button:LockHighlight();
  3472. button.pulseOn = 1;
  3473. end
  3474. button.pulseDuration = button.pulseRate;
  3475. end
  3476. button.pulseDuration = button.pulseDuration - elapsed;
  3477. button.pulseTimeLeft = button.pulseTimeLeft - elapsed;
  3478. else
  3479. button:UnlockHighlight();
  3480. button.pulseOn = 0;
  3481. tDeleteItem(PULSEBUTTONS, button);
  3482. end
  3483. end
  3484. end
  3485. function ButtonPulse_StopPulse(button)
  3486. for index, pulseButton in pairs(PULSEBUTTONS) do
  3487. if ( pulseButton == button ) then
  3488. tDeleteItem(PULSEBUTTONS, button);
  3489. end
  3490. end
  3491. end
  3492. function UIDoFramesIntersect(frame1, frame2)
  3493. if ( ( frame1:GetLeft() < frame2:GetRight() ) and ( frame1:GetRight() > frame2:GetLeft() ) and
  3494. ( frame1:GetBottom() < frame2:GetTop() ) and ( frame1:GetTop() > frame2:GetBottom() ) ) then
  3495. return true;
  3496. else
  3497. return false;
  3498. end
  3499. end
  3500. -- Lua Helper functions --
  3501. function BuildListString(...)
  3502. local text = ...;
  3503. if ( not text ) then
  3504. return nil;
  3505. end
  3506. local string = text;
  3507. for i=2, select("#", ...) do
  3508. text = select(i, ...);
  3509. if ( text ) then
  3510. string = string..", "..text;
  3511. end
  3512. end
  3513. return string;
  3514. end
  3515. function BuildColoredListString(...)
  3516. if ( select("#", ...) == 0 ) then
  3517. return nil;
  3518. end
  3519. -- Takes input where odd items are the text and even items determine whether the arg should be colored or not
  3520. local text, normal = ...;
  3521. local string;
  3522. if ( normal ) then
  3523. string = text;
  3524. else
  3525. string = RED_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
  3526. end
  3527. for i=3, select("#", ...), 2 do
  3528. text, normal = select(i, ...);
  3529. if ( normal ) then
  3530. -- If meets the condition
  3531. string = string..", "..text;
  3532. else
  3533. -- If doesn't meet the condition
  3534. string = string..", "..RED_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
  3535. end
  3536. end
  3537. return string;
  3538. end
  3539. function BuildNewLineListString(...)
  3540. local text;
  3541. local index = 1;
  3542. for i=1, select("#", ...) do
  3543. text = select(i, ...);
  3544. index = index + 1;
  3545. if ( text ) then
  3546. break;
  3547. end
  3548. end
  3549. if ( not text ) then
  3550. return nil;
  3551. end
  3552. local string = text;
  3553. for i=index, select("#", ...) do
  3554. text = select(i, ...);
  3555. if ( text ) then
  3556. string = string.."\n"..text;
  3557. end
  3558. end
  3559. return string;
  3560. end
  3561. function BuildMultilineTooltip(globalStringName, tooltip, r, g, b)
  3562. if ( not tooltip ) then
  3563. tooltip = GameTooltip;
  3564. end
  3565. if ( not r ) then
  3566. r = 1.0;
  3567. g = 1.0;
  3568. b = 1.0;
  3569. end
  3570. local i = 1;
  3571. local string = _G[globalStringName..i];
  3572. while (string) do
  3573. tooltip:AddLine(string, "", r, g, b);
  3574. i = i + 1;
  3575. string = _G[globalStringName..i];
  3576. end
  3577. end
  3578. function GetScaledCursorPosition()
  3579. local uiScale = UIParent:GetEffectiveScale();
  3580. local x, y = GetCursorPosition();
  3581. return x / uiScale, y / uiScale;
  3582. end
  3583. function GetScaledCursorDelta()
  3584. local uiScale = _UIParentGetEffectiveScale(_UIParentRef);
  3585. local x, y = GetCursorDelta();
  3586. return x / uiScale, y / uiScale;
  3587. end
  3588. function MouseIsOver(region, topOffset, bottomOffset, leftOffset, rightOffset)
  3589. return region:IsMouseOver(topOffset, bottomOffset, leftOffset, rightOffset);
  3590. end
  3591. -- replace the C functions with local lua versions
  3592. function getglobal(varr)
  3593. return _G[varr];
  3594. end
  3595. function setglobal(varr,value)
  3596. _G[varr] = value;
  3597. end
  3598. -- Wrapper for the desaturation function
  3599. function SetDesaturation(texture, desaturation)
  3600. texture:SetDesaturated(desaturation);
  3601. end
  3602. function GetMaterialTextColors(material)
  3603. local textColor = MATERIAL_TEXT_COLOR_TABLE[material];
  3604. local titleColor = MATERIAL_TITLETEXT_COLOR_TABLE[material];
  3605. if ( not(textColor and titleColor) ) then
  3606. textColor = MATERIAL_TEXT_COLOR_TABLE["Default"];
  3607. titleColor = MATERIAL_TITLETEXT_COLOR_TABLE["Default"];
  3608. end
  3609. return textColor, titleColor;
  3610. end
  3611. function OrderHallMissionFrame_EscapePressed()
  3612. return OrderHallMissionFrame and OrderHallMissionFrame.EscapePressed and OrderHallMissionFrame:EscapePressed();
  3613. end
  3614. function OrderHallTalentFrame_EscapePressed()
  3615. return OrderHallTalentFrame and OrderHallTalentFrame.EscapePressed and OrderHallTalentFrame:EscapePressed();
  3616. end
  3617. function BFAMissionFrame_EscapePressed()
  3618. return BFAMissionFrame and BFAMissionFrame.EscapePressed and BFAMissionFrame:EscapePressed();
  3619. end
  3620. -- Function that handles the escape key functions
  3621. function ToggleGameMenu()
  3622. if ( not UIParent:IsShown() ) then
  3623. UIParent:Show();
  3624. SetUIVisibility(true);
  3625. elseif ( C_Commentator.IsSpectating() and IsFrameLockActive("COMMENTATOR_SPECTATING_MODE") ) then
  3626. PvPCommentator:SetFrameLock(false);
  3627. elseif ( ModelPreviewFrame:IsShown() ) then
  3628. ModelPreviewFrame:Hide();
  3629. elseif ( StoreFrame_EscapePressed and StoreFrame_EscapePressed() ) then
  3630. elseif ( WowTokenRedemptionFrame_EscapePressed and WowTokenRedemptionFrame_EscapePressed() ) then
  3631. elseif ( securecall("StaticPopup_EscapePressed") ) then
  3632. elseif ( GameMenuFrame:IsShown() ) then
  3633. PlaySound(SOUNDKIT.IG_MAINMENU_QUIT);
  3634. HideUIPanel(GameMenuFrame);
  3635. elseif ( HelpFrame:IsShown() ) then
  3636. ToggleHelpFrame();
  3637. elseif ( VideoOptionsFrame:IsShown() ) then
  3638. VideoOptionsFrameCancel:Click();
  3639. elseif ( AudioOptionsFrame:IsShown() ) then
  3640. AudioOptionsFrameCancel:Click();
  3641. elseif ( SocialBrowserFrame and SocialBrowserFrame:IsShown() ) then
  3642. SocialBrowserFrame:Hide();
  3643. elseif ( InterfaceOptionsFrame:IsShown() ) then
  3644. InterfaceOptionsFrameCancel:Click();
  3645. elseif ( SocialPostFrame and Social_IsShown() ) then
  3646. Social_SetShown(false);
  3647. elseif ( TimeManagerFrame and TimeManagerFrame:IsShown() ) then
  3648. TimeManagerFrameCloseButton:Click();
  3649. elseif ( MultiCastFlyoutFrame:IsShown() ) then
  3650. MultiCastFlyoutFrame_Hide(MultiCastFlyoutFrame, true);
  3651. elseif (SpellFlyout:IsShown() ) then
  3652. SpellFlyout:Hide();
  3653. elseif ( securecall("FCFDockOverflow_CloseLists") ) then
  3654. elseif ( securecall("CloseMenus") ) then
  3655. elseif ( CloseCalendarMenus and securecall("CloseCalendarMenus") ) then
  3656. elseif ( CloseGuildMenus and securecall("CloseGuildMenus") ) then
  3657. elseif ( GarrisonMissionFrame_ClearMouse and securecall("GarrisonMissionFrame_ClearMouse") ) then
  3658. elseif ( GarrisonMissionFrame and GarrisonMissionFrame.MissionTab and GarrisonMissionFrame.MissionTab.MissionPage and GarrisonMissionFrame.MissionTab.MissionPage:IsVisible() ) then
  3659. GarrisonMissionFrame.MissionTab.MissionPage.CloseButton:Click();
  3660. elseif ( GarrisonShipyardFrame_ClearMouse and securecall("GarrisonShipyardFrame_ClearMouse") ) then
  3661. elseif ( GarrisonShipyardFrame and GarrisonShipyardFrame.MissionTab and GarrisonShipyardFrame.MissionTab.MissionPage and GarrisonShipyardFrame.MissionTab.MissionPage:IsVisible() ) then
  3662. GarrisonShipyardFrame.MissionTab.MissionPage.CloseButton:Click();
  3663. elseif ( securecall("OrderHallMissionFrame_EscapePressed") ) then
  3664. elseif ( securecall("OrderHallTalentFrame_EscapePressed") ) then
  3665. elseif ( securecall("BFAMissionFrame_EscapePressed") ) then
  3666. elseif ( SpellStopCasting() ) then
  3667. elseif ( SpellStopTargeting() ) then
  3668. elseif ( securecall("CloseAllWindows") ) then
  3669. elseif ( LootFrame:IsShown() ) then
  3670. -- if we're here, LootFrame was opened under the mouse (cvar "lootUnderMouse") so it didn't get closed by CloseAllWindows
  3671. LootFrame:Hide();
  3672. elseif ( ClearTarget() and (not UnitIsCharmed("player")) ) then
  3673. elseif ( OpacityFrame:IsShown() ) then
  3674. OpacityFrame:Hide();
  3675. elseif ( SplashFrame:IsShown() ) then
  3676. SplashFrame_Close();
  3677. elseif ( ChallengesKeystoneFrame and ChallengesKeystoneFrame:IsShown() ) then
  3678. ChallengesKeystoneFrame:Hide();
  3679. else
  3680. PlaySound(SOUNDKIT.IG_MAINMENU_OPEN);
  3681. ShowUIPanel(GameMenuFrame);
  3682. end
  3683. end
  3684. -- Visual Misc --
  3685. function GetScreenHeightScale()
  3686. local screenHeight = 768;
  3687. return GetScreenHeight()/screenHeight;
  3688. end
  3689. function GetScreenWidthScale()
  3690. local screenWidth = 1024;
  3691. return GetScreenWidth()/screenWidth;
  3692. end
  3693. function ShowInspectCursor()
  3694. SetCursor("INSPECT_CURSOR");
  3695. end
  3696. -- Helper function to show the inspect cursor if the ctrl key is down
  3697. function CursorUpdate(self)
  3698. if ( IsModifiedClick("DRESSUP") and self.hasItem ) then
  3699. ShowInspectCursor();
  3700. else
  3701. ResetCursor();
  3702. end
  3703. end
  3704. function CursorOnUpdate(self)
  3705. if ( GameTooltip:IsOwned(self) ) then
  3706. CursorUpdate(self);
  3707. end
  3708. end
  3709. function AnimateTexCoords(texture, textureWidth, textureHeight, frameWidth, frameHeight, numFrames, elapsed, throttle)
  3710. if ( not texture.frame ) then
  3711. -- initialize everything
  3712. texture.frame = 1;
  3713. texture.throttle = throttle;
  3714. texture.numColumns = floor(textureWidth/frameWidth);
  3715. texture.numRows = floor(textureHeight/frameHeight);
  3716. texture.columnWidth = frameWidth/textureWidth;
  3717. texture.rowHeight = frameHeight/textureHeight;
  3718. end
  3719. local frame = texture.frame;
  3720. if ( not texture.throttle or texture.throttle > throttle ) then
  3721. local framesToAdvance = floor(texture.throttle / throttle);
  3722. while ( frame + framesToAdvance > numFrames ) do
  3723. frame = frame - numFrames;
  3724. end
  3725. frame = frame + framesToAdvance;
  3726. texture.throttle = 0;
  3727. local left = mod(frame-1, texture.numColumns)*texture.columnWidth;
  3728. local right = left + texture.columnWidth;
  3729. local bottom = ceil(frame/texture.numColumns)*texture.rowHeight;
  3730. local top = bottom - texture.rowHeight;
  3731. texture:SetTexCoord(left, right, top, bottom);
  3732. texture.frame = frame;
  3733. else
  3734. texture.throttle = texture.throttle + elapsed;
  3735. end
  3736. end
  3737. -- Bindings --
  3738. function GetBindingFromClick(input)
  3739. local fullInput = "";
  3740. -- MUST BE IN THIS ORDER (ALT, CTRL, SHIFT)
  3741. if ( IsAltKeyDown() ) then
  3742. fullInput = fullInput.."ALT-";
  3743. end
  3744. if ( IsControlKeyDown() ) then
  3745. fullInput = fullInput.."CTRL-"
  3746. end
  3747. if ( IsShiftKeyDown() ) then
  3748. fullInput = fullInput.."SHIFT-"
  3749. end
  3750. if ( input == "LeftButton" ) then
  3751. fullInput = fullInput.."BUTTON1";
  3752. elseif ( input == "RightButton" ) then
  3753. fullInput = fullInput.."BUTTON2";
  3754. elseif ( input == "MiddleButton" ) then
  3755. fullInput = fullInput.."BUTTON3";
  3756. elseif ( input == "Button4" ) then
  3757. fullInput = fullInput.."BUTTON4";
  3758. elseif ( input == "Button5" ) then
  3759. fullInput = fullInput.."BUTTON5";
  3760. elseif ( input == "Button6" ) then
  3761. fullInput = fullInput.."BUTTON6";
  3762. elseif ( input == "Button7" ) then
  3763. fullInput = fullInput.."BUTTON7";
  3764. elseif ( input == "Button8" ) then
  3765. fullInput = fullInput.."BUTTON8";
  3766. elseif ( input == "Button9" ) then
  3767. fullInput = fullInput.."BUTTON9";
  3768. elseif ( input == "Button10" ) then
  3769. fullInput = fullInput.."BUTTON10";
  3770. elseif ( input == "Button11" ) then
  3771. fullInput = fullInput.."BUTTON11";
  3772. elseif ( input == "Button12" ) then
  3773. fullInput = fullInput.."BUTTON12";
  3774. elseif ( input == "Button13" ) then
  3775. fullInput = fullInput.."BUTTON13";
  3776. elseif ( input == "Button14" ) then
  3777. fullInput = fullInput.."BUTTON14";
  3778. elseif ( input == "Button15" ) then
  3779. fullInput = fullInput.."BUTTON15";
  3780. elseif ( input == "Button16" ) then
  3781. fullInput = fullInput.."BUTTON16";
  3782. elseif ( input == "Button17" ) then
  3783. fullInput = fullInput.."BUTTON17";
  3784. elseif ( input == "Button18" ) then
  3785. fullInput = fullInput.."BUTTON18";
  3786. elseif ( input == "Button19" ) then
  3787. fullInput = fullInput.."BUTTON19";
  3788. elseif ( input == "Button20" ) then
  3789. fullInput = fullInput.."BUTTON20";
  3790. elseif ( input == "Button21" ) then
  3791. fullInput = fullInput.."BUTTON21";
  3792. elseif ( input == "Button22" ) then
  3793. fullInput = fullInput.."BUTTON22";
  3794. elseif ( input == "Button23" ) then
  3795. fullInput = fullInput.."BUTTON23";
  3796. elseif ( input == "Button24" ) then
  3797. fullInput = fullInput.."BUTTON24";
  3798. elseif ( input == "Button25" ) then
  3799. fullInput = fullInput.."BUTTON25";
  3800. elseif ( input == "Button26" ) then
  3801. fullInput = fullInput.."BUTTON26";
  3802. elseif ( input == "Button27" ) then
  3803. fullInput = fullInput.."BUTTON27";
  3804. elseif ( input == "Button28" ) then
  3805. fullInput = fullInput.."BUTTON28";
  3806. elseif ( input == "Button29" ) then
  3807. fullInput = fullInput.."BUTTON29";
  3808. elseif ( input == "Button30" ) then
  3809. fullInput = fullInput.."BUTTON30";
  3810. elseif ( input == "Button31" ) then
  3811. fullInput = fullInput.."BUTTON31";
  3812. else
  3813. fullInput = fullInput..input;
  3814. end
  3815. return GetBindingByKey(fullInput);
  3816. end
  3817. -- Game Logic --
  3818. function OnInviteToPartyConfirmation(name, willConvertToRaid, questSessionActive)
  3819. if questSessionActive then
  3820. QuestSessionManager:OnInviteToPartyConfirmation(name, willConvertToRaid);
  3821. elseif willConvertToRaid then
  3822. local dialog = StaticPopup_Show("CONVERT_TO_RAID");
  3823. if ( dialog ) then
  3824. dialog.data = name;
  3825. end
  3826. else
  3827. C_PartyInfo.ConfirmInviteUnit(name);
  3828. end
  3829. end
  3830. function GetSocialColoredName(displayName, guid)
  3831. local _, color, relationship = SocialQueueUtil_GetRelationshipInfo(guid);
  3832. if ( relationship ) then
  3833. return color..displayName..FONT_COLOR_CODE_CLOSE;
  3834. end
  3835. return displayName;
  3836. end
  3837. local function AllowAutoAcceptInviteConfirmation(isQuickJoin, isSelfRelationship)
  3838. return isQuickJoin and isSelfRelationship and GetCVarBool("autoAcceptQuickJoinRequests") and not C_QuestSession.Exists();
  3839. end
  3840. local function ShouldAutoAcceptInviteConfirmation(invite)
  3841. local confirmationType, name, guid, rolesInvalid, willConvertToRaid = GetInviteConfirmationInfo(invite);
  3842. local _, _, _, isQuickJoin, clubID = C_PartyInfo.GetInviteReferralInfo(invite);
  3843. local _, _, selfRelationship = SocialQueueUtil_GetRelationshipInfo(guid, name, clubID);
  3844. return AllowAutoAcceptInviteConfirmation(isQuickJoin, selfRelationship);
  3845. end
  3846. function UpdateInviteConfirmationDialogs()
  3847. local invite = GetNextPendingInviteConfirmation();
  3848. if invite then
  3849. HandlePendingInviteConfirmation(invite);
  3850. end
  3851. end
  3852. function HandlePendingInviteConfirmation(invite)
  3853. if C_QuestSession.HasJoined() then
  3854. HandlePendingInviteConfirmation_QuestSession(invite);
  3855. else
  3856. HandlePendingInviteConfirmation_StaticPopup(invite);
  3857. end
  3858. end
  3859. function HandlePendingInviteConfirmation_StaticPopup(invite)
  3860. if not StaticPopup_FindVisible("GROUP_INVITE_CONFIRMATION") then
  3861. if ShouldAutoAcceptInviteConfirmation(invite) then
  3862. RespondToInviteConfirmation(invite, true);
  3863. else
  3864. local text = CreatePendingInviteConfirmationText(invite);
  3865. StaticPopup_Show("GROUP_INVITE_CONFIRMATION", text, nil, invite);
  3866. end
  3867. end
  3868. end
  3869. function HandlePendingInviteConfirmation_QuestSession(invite)
  3870. -- Chances are that we never want to auto-accept in a quest session,
  3871. -- so always show the dialog.
  3872. local text = CreatePendingInviteConfirmationText(invite);
  3873. QuestSessionManager:ShowGroupInviteConfirmation(invite, text);
  3874. end
  3875. function CreatePendingInviteConfirmationText(invite)
  3876. local confirmationType, name, guid, rolesInvalid, willConvertToRaid = GetInviteConfirmationInfo(invite);
  3877. if confirmationType == LE_INVITE_CONFIRMATION_REQUEST then
  3878. return CreatePendingInviteConfirmationText_Request(invite, name, guid, rolesInvalid, willConvertToRaid);
  3879. elseif confirmationType == LE_INVITE_CONFIRMATION_SUGGEST then
  3880. return CreatePendingInviteConfirmationText_Suggest(invite, name, guid, rolesInvalid, willConvertToRaid);
  3881. else
  3882. return CreatePendingInviteConfirmationText_AppendWarnings("", invite, name, guid, rolesInvalid, willConvertToRaid);
  3883. end
  3884. end
  3885. function CreatePendingInviteConfirmationText_Request(invite, name, guid, rolesInvalid, willConvertToRaid)
  3886. local coloredName, coloredSuggesterName = CreatePendingInviteConfirmationNames(invite, name, guid, rolesInvalid, willConvertToRaid);
  3887. local suggesterGuid, _, relationship, isQuickJoin, clubId = C_PartyInfo.GetInviteReferralInfo(invite);
  3888. --If we ourselves have a relationship with this player, we'll just act as if they asked through us.
  3889. local _, _, selfRelationship = SocialQueueUtil_GetRelationshipInfo(guid, name, clubId);
  3890. local text;
  3891. if selfRelationship then
  3892. local clubLink = clubId and GetCommunityLink(clubId) or nil;
  3893. if ( clubLink and selfRelationship == "club" ) then
  3894. if isQuickJoin then
  3895. text = INVITE_CONFIRMATION_REQUEST_FROM_COMMUNITY_QUICKJOIN:format(coloredName, clubLink);
  3896. else
  3897. text = INVITE_CONFIRMATION_REQUEST_FROM_COMMUNITY:format(coloredName, clubLink);
  3898. end
  3899. elseif isQuickJoin then
  3900. text = INVITE_CONFIRMATION_REQUEST_QUICKJOIN:format(coloredName);
  3901. else
  3902. text = INVITE_CONFIRMATION_REQUEST:format(coloredName);
  3903. end
  3904. elseif suggesterGuid then
  3905. if relationship == Enum.PartyRequestJoinRelation.Friend then
  3906. text = (isQuickJoin and INVITE_CONFIRMATION_REQUEST_FRIEND_QUICKJOIN or INVITE_CONFIRMATION_REQUEST_FRIEND):format(coloredSuggesterName, coloredName);
  3907. elseif relationship == Enum.PartyRequestJoinRelation.Guild then
  3908. text = (isQuickJoin and INVITE_CONFIRMATION_REQUEST_GUILD_QUICKJOIN or INVITE_CONFIRMATION_REQUEST_GUILD):format(coloredSuggesterName, coloredName);
  3909. elseif relationship == Enum.PartyRequestJoinRelation.Club then
  3910. text = (isQuickJoin and INVITE_CONFIRMATION_REQUEST_COMMUNITY_QUICKJOIN or INVITE_CONFIRMATION_REQUEST_COMMUNITY):format(coloredSuggesterName, coloredName);
  3911. else
  3912. text = INVITE_CONFIRMATION_REQUEST:format(coloredName);
  3913. end
  3914. else
  3915. text = (isQuickJoin and INVITE_CONFIRMATION_REQUEST_QUICKJOIN or INVITE_CONFIRMATION_REQUEST):format(coloredName);
  3916. end
  3917. return CreatePendingInviteConfirmationText_AppendWarnings(text, invite, name, guid, rolesInvalid, willConvertToRaid);
  3918. end
  3919. function CreatePendingInviteConfirmationNames(invite, name, guid, rolesInvalid, willConvertToRaid)
  3920. local suggesterGuid, suggesterName, relationship, isQuickJoin, clubId = C_PartyInfo.GetInviteReferralInfo(invite);
  3921. --If we ourselves have a relationship with this player, we'll just act as if they asked through us.
  3922. local _, color, selfRelationship, playerLink = SocialQueueUtil_GetRelationshipInfo(guid, name, clubId);
  3923. name = (playerLink and isQuickJoin) and ("["..playerLink.."]") or name;
  3924. if selfRelationship or isQuickJoin then
  3925. name = color .. name .. FONT_COLOR_CODE_CLOSE;
  3926. end
  3927. if selfRelationship then
  3928. return name;
  3929. elseif suggesterGuid then
  3930. suggesterName = GetSocialColoredName(suggesterName, suggesterGuid);
  3931. if relationship == Enum.PartyRequestJoinRelation.Friend or relationship == Enum.PartyRequestJoinRelation.Guild or relationship == Enum.PartyRequestJoinRelation.Club then
  3932. return name, suggesterName;
  3933. else
  3934. return name;
  3935. end
  3936. else
  3937. return name;
  3938. end
  3939. end
  3940. function CreatePendingInviteConfirmationText_Suggest(invite, name, guid, rolesInvalid, willConvertToRaid)
  3941. local suggesterGuid, suggesterName, relationship, isQuickJoin = C_PartyInfo.GetInviteReferralInfo(invite);
  3942. suggesterName = GetSocialColoredName(suggesterName, suggesterGuid);
  3943. name = GetSocialColoredName(name, guid);
  3944. -- Only using a single string here, if somebody is suggesting a person to join the group, QuickJoin text doesn't apply.
  3945. local text = INVITE_CONFIRMATION_SUGGEST:format(suggesterName, name);
  3946. return CreatePendingInviteConfirmationText_AppendWarnings(text, invite, name, guid, rolesInvalid, willConvertToRaid)
  3947. end
  3948. function CreatePendingInviteConfirmationText_AppendWarnings(text, invite, name, guid, rolesInvalid, willConvertToRaid)
  3949. local warnings = CreatePendingInviteConfirmationText_GetWarnings(invite, name, guid, rolesInvalid, willConvertToRaid);
  3950. if warnings ~= "" then
  3951. if text ~= "" then
  3952. return text.."\n\n"..warnings;
  3953. else
  3954. return warnings;
  3955. end
  3956. end
  3957. return text;
  3958. end
  3959. function CreatePendingInviteConfirmationText_GetWarnings(invite, name, guid, rolesInvalid, willConvertToRaid)
  3960. local warnings = {};
  3961. local invalidQueues = C_PartyInfo.GetInviteConfirmationInvalidQueues(invite);
  3962. if invalidQueues and #invalidQueues > 0 then
  3963. if rolesInvalid then
  3964. table.insert(warnings, INSTANCE_UNAVAILABLE_OTHER_NO_VALID_ROLES:format(name));
  3965. end
  3966. table.insert(warnings, INVITE_CONFIRMATION_QUEUE_WARNING:format(name));
  3967. for i=1, #invalidQueues do
  3968. local queueName = SocialQueueUtil_GetQueueName(invalidQueues[i]);
  3969. table.insert(warnings, NORMAL_FONT_COLOR:WrapTextInColorCode(queueName));
  3970. end
  3971. end
  3972. if willConvertToRaid then
  3973. table.insert(warnings, RED_FONT_COLOR:WrapTextInColorCode(LFG_LIST_CONVERT_TO_RAID_WARNING));
  3974. end
  3975. return table.concat(warnings, "\n");
  3976. end
  3977. function UnitHasMana(unit)
  3978. if ( UnitPowerMax(unit, Enum.PowerType.Mana) > 0 ) then
  3979. return 1;
  3980. end
  3981. return nil;
  3982. end
  3983. function RaiseFrameLevelByTwo(frame)
  3984. -- We do this enough that it saves closures.
  3985. frame:SetFrameLevel(frame:GetFrameLevel()+2);
  3986. end
  3987. function ShowResurrectRequest(offerer)
  3988. if ( ResurrectHasSickness() ) then
  3989. StaticPopup_Show("RESURRECT", offerer);
  3990. elseif ( ResurrectHasTimer() ) then
  3991. StaticPopup_Show("RESURRECT_NO_SICKNESS", offerer);
  3992. else
  3993. StaticPopup_Show("RESURRECT_NO_TIMER", offerer);
  3994. end
  3995. end
  3996. function RefreshAuras(frame, unit, numAuras, suffix, checkCVar, showBuffs)
  3997. if ( showBuffs ) then
  3998. RefreshBuffs(frame, unit, numAuras, suffix, checkCVar);
  3999. else
  4000. RefreshDebuffs(frame, unit, numAuras, suffix, checkCVar);
  4001. end
  4002. end
  4003. function RefreshBuffs(frame, unit, numBuffs, suffix, checkCVar)
  4004. local frameName = frame:GetName();
  4005. frame.hasDispellable = nil;
  4006. numBuffs = numBuffs or MAX_PARTY_BUFFS;
  4007. suffix = suffix or "Buff";
  4008. local unitStatus, statusColor;
  4009. local debuffTotal = 0;
  4010. local filter = ( checkCVar and SHOW_CASTABLE_BUFFS == "1" and UnitCanAssist("player", unit) ) and "HELPFUL|RAID" or "HELPFUL";
  4011. local numFrames = 0;
  4012. AuraUtil.ForEachAura(unit, filter, numBuffs, function(...)
  4013. local name, icon, count, debuffType, duration, expirationTime = ...;
  4014. -- if we have an icon to show then proceed with setting up the aura
  4015. if ( icon ) then
  4016. numFrames = numFrames + 1;
  4017. local buffName = frameName..suffix..numFrames;
  4018. -- set the icon
  4019. local buffIcon = _G[buffName.."Icon"];
  4020. buffIcon:SetTexture(icon);
  4021. -- setup the cooldown
  4022. local coolDown = _G[buffName.."Cooldown"];
  4023. if ( coolDown ) then
  4024. CooldownFrame_Set(coolDown, expirationTime - duration, duration, true);
  4025. end
  4026. -- show the aura
  4027. _G[buffName]:Show();
  4028. end
  4029. return numFrames >= numBuffs;
  4030. end);
  4031. for i=numFrames + 1,numBuffs do
  4032. local buffName = frameName..suffix..i;
  4033. local frame = _G[buffName];
  4034. if frame then
  4035. frame:Hide();
  4036. else
  4037. break;
  4038. end
  4039. end
  4040. end
  4041. function RefreshDebuffs(frame, unit, numDebuffs, suffix, checkCVar)
  4042. local frameName = frame:GetName();
  4043. suffix = suffix or "Debuff";
  4044. local frameNameWithSuffix = frameName..suffix;
  4045. frame.hasDispellable = nil;
  4046. numDebuffs = numDebuffs or MAX_PARTY_DEBUFFS;
  4047. local unitStatus, statusColor;
  4048. local debuffTotal = 0;
  4049. local isEnemy = UnitCanAttack("player", unit);
  4050. local filter = ( checkCVar and SHOW_DISPELLABLE_DEBUFFS == "1" and UnitCanAssist("player", unit) ) and "HARMFUL|RAID" or "HARMFUL";
  4051. if strsub(unit, 1, 5) == "party" then
  4052. unitStatus = _G[frameName.."Status"];
  4053. end
  4054. AuraUtil.ForEachAura(unit, filter, numDebuffs, function(...)
  4055. local name, icon, count, debuffType, duration, expirationTime, caster = ...;
  4056. if ( icon and ( SHOW_CASTABLE_DEBUFFS == "0" or not isEnemy or caster == "player" ) ) then
  4057. debuffTotal = debuffTotal + 1;
  4058. local debuffName = frameNameWithSuffix..debuffTotal;
  4059. -- if we have an icon to show then proceed with setting up the aura
  4060. -- set the icon
  4061. local debuffIcon = _G[debuffName.."Icon"];
  4062. debuffIcon:SetTexture(icon);
  4063. -- setup the border
  4064. local debuffBorder = _G[debuffName.."Border"];
  4065. local debuffColor = DebuffTypeColor[debuffType] or DebuffTypeColor["none"];
  4066. debuffBorder:SetVertexColor(debuffColor.r, debuffColor.g, debuffColor.b);
  4067. -- record interesting data for the aura button
  4068. statusColor = debuffColor;
  4069. frame.hasDispellable = 1;
  4070. -- setup the cooldown
  4071. local coolDown = _G[debuffName.."Cooldown"];
  4072. if ( coolDown ) then
  4073. CooldownFrame_Set(coolDown, expirationTime - duration, duration, true);
  4074. end
  4075. -- show the aura
  4076. _G[debuffName]:Show();
  4077. end
  4078. return debuffTotal >= numDebuffs;
  4079. end);
  4080. for i=debuffTotal+1,numDebuffs do
  4081. local debuffName = frameNameWithSuffix..i;
  4082. _G[debuffName]:Hide();
  4083. end
  4084. frame.debuffTotal = debuffTotal;
  4085. -- Reset unitStatus overlay graphic timer
  4086. if ( frame.numDebuffs and debuffTotal >= frame.numDebuffs ) then
  4087. frame.debuffCountdown = 30;
  4088. end
  4089. if ( unitStatus and statusColor ) then
  4090. unitStatus:SetVertexColor(statusColor.r, statusColor.g, statusColor.b);
  4091. end
  4092. end
  4093. function GetQuestDifficultyColor(level, isScaling, optQuestID)
  4094. if optQuestID and C_QuestLog.IsQuestDisabledForSession(optQuestID) then
  4095. return QuestDifficultyColors["disabled"], QuestDifficultyHighlightColors["disabled"];
  4096. end
  4097. if (isScaling) then
  4098. return GetScalingQuestDifficultyColor(level);
  4099. end
  4100. return GetRelativeDifficultyColor(UnitEffectiveLevel("player"), level);
  4101. end
  4102. function GetCreatureDifficultyColor(level)
  4103. return GetRelativeDifficultyColor(UnitEffectiveLevel("player"), level);
  4104. end
  4105. --How difficult is this challenge for this unit?
  4106. function GetRelativeDifficultyColor(unitLevel, challengeLevel)
  4107. local levelDiff = challengeLevel - unitLevel;
  4108. local color;
  4109. if ( levelDiff >= 5 ) then
  4110. return QuestDifficultyColors["impossible"], QuestDifficultyHighlightColors["impossible"];
  4111. elseif ( levelDiff >= 3 ) then
  4112. return QuestDifficultyColors["verydifficult"], QuestDifficultyHighlightColors["verydifficult"];
  4113. elseif ( levelDiff >= -4 ) then
  4114. return QuestDifficultyColors["difficult"], QuestDifficultyHighlightColors["difficult"];
  4115. elseif ( -levelDiff <= GetQuestGreenRange() ) then
  4116. return QuestDifficultyColors["standard"], QuestDifficultyHighlightColors["standard"];
  4117. else
  4118. return QuestDifficultyColors["trivial"], QuestDifficultyHighlightColors["trivial"];
  4119. end
  4120. end
  4121. function GetScalingQuestDifficultyColor(questLevel)
  4122. local playerLevel = UnitEffectiveLevel("player");
  4123. local levelDiff = questLevel - playerLevel;
  4124. if ( levelDiff >= 5 ) then
  4125. return QuestDifficultyColors["impossible"], QuestDifficultyHighlightColors["impossible"];
  4126. elseif ( levelDiff >= 3 ) then
  4127. return QuestDifficultyColors["verydifficult"], QuestDifficultyHighlightColors["verydifficult"];
  4128. elseif ( levelDiff >= 0 ) then
  4129. return QuestDifficultyColors["difficult"], QuestDifficultyHighlightColors["difficult"];
  4130. elseif ( -levelDiff <= GetScalingQuestGreenRange() ) then
  4131. return QuestDifficultyColors["standard"], QuestDifficultyHighlightColors["standard"];
  4132. else
  4133. return QuestDifficultyColors["trivial"], QuestDifficultyHighlightColors["trivial"];
  4134. end
  4135. end
  4136. -- takes in a table with r, g, and b entries and converts it to a color string
  4137. function ConvertRGBtoColorString(color)
  4138. local colorString = "|cff";
  4139. local r = color.r * 255;
  4140. local g = color.g * 255;
  4141. local b = color.b * 255;
  4142. colorString = colorString..string.format("%2x%2x%2x", r, g, b);
  4143. return colorString;
  4144. end
  4145. function GetDungeonNameWithDifficulty(name, difficultyName)
  4146. name = name or "";
  4147. if ( difficultyName == "" ) then
  4148. name = NORMAL_FONT_COLOR_CODE..name..FONT_COLOR_CODE_CLOSE;
  4149. else
  4150. name = NORMAL_FONT_COLOR_CODE..format(DUNGEON_NAME_WITH_DIFFICULTY, name, difficultyName)..FONT_COLOR_CODE_CLOSE;
  4151. end
  4152. return name;
  4153. end
  4154. -- Animated shine stuff --
  4155. function AnimatedShine_Start(shine, r, g, b)
  4156. if ( not tContains(SHINES_TO_ANIMATE, shine) ) then
  4157. shine.timer = 0;
  4158. tinsert(SHINES_TO_ANIMATE, shine);
  4159. end
  4160. local shineName = shine:GetName();
  4161. _G[shineName.."Shine1"]:Show();
  4162. _G[shineName.."Shine2"]:Show();
  4163. _G[shineName.."Shine3"]:Show();
  4164. _G[shineName.."Shine4"]:Show();
  4165. if ( r ) then
  4166. _G[shineName.."Shine1"]:SetVertexColor(r, g, b);
  4167. _G[shineName.."Shine2"]:SetVertexColor(r, g, b);
  4168. _G[shineName.."Shine3"]:SetVertexColor(r, g, b);
  4169. _G[shineName.."Shine4"]:SetVertexColor(r, g, b);
  4170. end
  4171. end
  4172. function AnimatedShine_Stop(shine)
  4173. tDeleteItem(SHINES_TO_ANIMATE, shine);
  4174. local shineName = shine:GetName();
  4175. _G[shineName.."Shine1"]:Hide();
  4176. _G[shineName.."Shine2"]:Hide();
  4177. _G[shineName.."Shine3"]:Hide();
  4178. _G[shineName.."Shine4"]:Hide();
  4179. end
  4180. function AnimatedShine_OnUpdate(elapsed)
  4181. local shine1, shine2, shine3, shine4;
  4182. local speed = 2.5;
  4183. local parent, distance;
  4184. for index, value in pairs(SHINES_TO_ANIMATE) do
  4185. shine1 = _G[value:GetName().."Shine1"];
  4186. shine2 = _G[value:GetName().."Shine2"];
  4187. shine3 = _G[value:GetName().."Shine3"];
  4188. shine4 = _G[value:GetName().."Shine4"];
  4189. value.timer = value.timer+elapsed;
  4190. if ( value.timer > speed*4 ) then
  4191. value.timer = 0;
  4192. end
  4193. parent = _G[value:GetName().."Shine"];
  4194. distance = parent:GetWidth();
  4195. if ( value.timer <= speed ) then
  4196. shine1:SetPoint("CENTER", parent, "TOPLEFT", value.timer/speed*distance, 0);
  4197. shine2:SetPoint("CENTER", parent, "BOTTOMRIGHT", -value.timer/speed*distance, 0);
  4198. shine3:SetPoint("CENTER", parent, "TOPRIGHT", 0, -value.timer/speed*distance);
  4199. shine4:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, value.timer/speed*distance);
  4200. elseif ( value.timer <= speed*2 ) then
  4201. shine1:SetPoint("CENTER", parent, "TOPRIGHT", 0, -(value.timer-speed)/speed*distance);
  4202. shine2:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, (value.timer-speed)/speed*distance);
  4203. shine3:SetPoint("CENTER", parent, "BOTTOMRIGHT", -(value.timer-speed)/speed*distance, 0);
  4204. shine4:SetPoint("CENTER", parent, "TOPLEFT", (value.timer-speed)/speed*distance, 0);
  4205. elseif ( value.timer <= speed*3 ) then
  4206. shine1:SetPoint("CENTER", parent, "BOTTOMRIGHT", -(value.timer-speed*2)/speed*distance, 0);
  4207. shine2:SetPoint("CENTER", parent, "TOPLEFT", (value.timer-speed*2)/speed*distance, 0);
  4208. shine3:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, (value.timer-speed*2)/speed*distance);
  4209. shine4:SetPoint("CENTER", parent, "TOPRIGHT", 0, -(value.timer-speed*2)/speed*distance);
  4210. else
  4211. shine1:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, (value.timer-speed*3)/speed*distance);
  4212. shine2:SetPoint("CENTER", parent, "TOPRIGHT", 0, -(value.timer-speed*3)/speed*distance);
  4213. shine3:SetPoint("CENTER", parent, "TOPLEFT", (value.timer-speed*3)/speed*distance, 0);
  4214. shine4:SetPoint("CENTER", parent, "BOTTOMRIGHT", -(value.timer-speed*3)/speed*distance, 0);
  4215. end
  4216. end
  4217. end
  4218. -- Autocast shine stuff --
  4219. AUTOCAST_SHINE_R = .95;
  4220. AUTOCAST_SHINE_G = .95;
  4221. AUTOCAST_SHINE_B = .32;
  4222. AUTOCAST_SHINE_SPEEDS = { 2, 4, 6, 8 };
  4223. AUTOCAST_SHINE_TIMERS = { 0, 0, 0, 0 };
  4224. local AUTOCAST_SHINES = {};
  4225. function AutoCastShine_OnLoad(self)
  4226. self.sparkles = {};
  4227. local name = self:GetName();
  4228. for i = 1, 16 do
  4229. tinsert(self.sparkles, _G[name .. i]);
  4230. end
  4231. end
  4232. function AutoCastShine_AutoCastStart(button, r, g, b)
  4233. if ( AUTOCAST_SHINES[button] ) then
  4234. return;
  4235. end
  4236. AUTOCAST_SHINES[button] = true;
  4237. if ( not r ) then
  4238. r, g, b = AUTOCAST_SHINE_R, AUTOCAST_SHINE_G, AUTOCAST_SHINE_B;
  4239. end
  4240. for _, sparkle in next, button.sparkles do
  4241. sparkle:Show();
  4242. sparkle:SetVertexColor(r, g, b);
  4243. end
  4244. end
  4245. function AutoCastShine_AutoCastStop(button)
  4246. AUTOCAST_SHINES[button] = nil;
  4247. for _, sparkle in next, button.sparkles do
  4248. sparkle:Hide();
  4249. end
  4250. end
  4251. function AutoCastShine_OnUpdate(self, elapsed)
  4252. for i in next, AUTOCAST_SHINE_TIMERS do
  4253. AUTOCAST_SHINE_TIMERS[i] = AUTOCAST_SHINE_TIMERS[i] + elapsed;
  4254. if ( AUTOCAST_SHINE_TIMERS[i] > AUTOCAST_SHINE_SPEEDS[i]*4 ) then
  4255. AUTOCAST_SHINE_TIMERS[i] = 0;
  4256. end
  4257. end
  4258. for button in next, AUTOCAST_SHINES do
  4259. self = button;
  4260. local parent, distance = self, self:GetWidth();
  4261. -- This is local to this function to save a lookup. If you need to use it elsewhere, might wanna make it global and use a local reference.
  4262. local AUTOCAST_SHINE_SPACING = 6;
  4263. for i = 1, 4 do
  4264. local timer = AUTOCAST_SHINE_TIMERS[i];
  4265. local speed = AUTOCAST_SHINE_SPEEDS[i];
  4266. if ( timer <= speed ) then
  4267. local basePosition = timer/speed*distance;
  4268. self.sparkles[0+i]:SetPoint("CENTER", parent, "TOPLEFT", basePosition, 0);
  4269. self.sparkles[4+i]:SetPoint("CENTER", parent, "BOTTOMRIGHT", -basePosition, 0);
  4270. self.sparkles[8+i]:SetPoint("CENTER", parent, "TOPRIGHT", 0, -basePosition);
  4271. self.sparkles[12+i]:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, basePosition);
  4272. elseif ( timer <= speed*2 ) then
  4273. local basePosition = (timer-speed)/speed*distance;
  4274. self.sparkles[0+i]:SetPoint("CENTER", parent, "TOPRIGHT", 0, -basePosition);
  4275. self.sparkles[4+i]:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, basePosition);
  4276. self.sparkles[8+i]:SetPoint("CENTER", parent, "BOTTOMRIGHT", -basePosition, 0);
  4277. self.sparkles[12+i]:SetPoint("CENTER", parent, "TOPLEFT", basePosition, 0);
  4278. elseif ( timer <= speed*3 ) then
  4279. local basePosition = (timer-speed*2)/speed*distance;
  4280. self.sparkles[0+i]:SetPoint("CENTER", parent, "BOTTOMRIGHT", -basePosition, 0);
  4281. self.sparkles[4+i]:SetPoint("CENTER", parent, "TOPLEFT", basePosition, 0);
  4282. self.sparkles[8+i]:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, basePosition);
  4283. self.sparkles[12+i]:SetPoint("CENTER", parent, "TOPRIGHT", 0, -basePosition);
  4284. else
  4285. local basePosition = (timer-speed*3)/speed*distance;
  4286. self.sparkles[0+i]:SetPoint("CENTER", parent, "BOTTOMLEFT", 0, basePosition);
  4287. self.sparkles[4+i]:SetPoint("CENTER", parent, "TOPRIGHT", 0, -basePosition);
  4288. self.sparkles[8+i]:SetPoint("CENTER", parent, "TOPLEFT", basePosition, 0);
  4289. self.sparkles[12+i]:SetPoint("CENTER", parent, "BOTTOMRIGHT", -basePosition, 0);
  4290. end
  4291. end
  4292. end
  4293. end
  4294. function ConsolePrint(...)
  4295. ConsoleAddMessage(strjoin(" ", tostringall(...)));
  4296. end
  4297. function LFD_IsEmpowered()
  4298. --Solo players are always empowered.
  4299. if ( not IsInGroup() ) then
  4300. return true;
  4301. end
  4302. --The leader may always queue/dequeue
  4303. if ( UnitIsGroupLeader("player") ) then
  4304. return true;
  4305. end
  4306. --In DF groups, anyone may queue/dequeue. In RF groups, the leader or assistants may queue/dequeue.
  4307. if ( HasLFGRestrictions() and (not IsInRaid() or UnitIsGroupAssistant("player")) ) then
  4308. return true;
  4309. end
  4310. return false;
  4311. end
  4312. function RaidBrowser_IsEmpowered()
  4313. return (not IsInGroup()) or UnitIsGroupLeader("player");
  4314. end
  4315. function GetLFGMode(category, lfgID)
  4316. if ( category ~= LE_LFG_CATEGORY_RF ) then
  4317. lfgID = nil; --HACK - RF works differently from everything else. You can queue for multiple RF slots with different ride tickets.
  4318. end
  4319. local proposalExists, id, typeID, subtypeID, name, texture, role, hasResponded, totalEncounters, completedEncounters, numMembers, isLeader, isHoliday, proposalCategory = GetLFGProposal();
  4320. local inParty, joined, queued, noPartialClear, achievements, lfgComment, slotCount = GetLFGInfoServer(category, lfgID);
  4321. local roleCheckInProgress, slots, members, roleUpdateCategory, roleUpdateID = GetLFGRoleUpdate();
  4322. local partyCategory = nil;
  4323. local partySlot = GetPartyLFGID();
  4324. if ( partySlot ) then
  4325. partyCategory = GetLFGCategoryForID(partySlot);
  4326. end
  4327. local empoweredFunc = LFD_IsEmpowered;
  4328. if ( category == LE_LFG_CATEGORY_LFR ) then
  4329. empoweredFunc = RaidBrowser_IsEmpowered;
  4330. end
  4331. if ( proposalExists and not hasResponded and proposalCategory == category and (not lfgID or lfgID == id) ) then
  4332. return "proposal", "unaccepted";
  4333. elseif ( proposalExists and proposalCategory == category and (not lfgID or lfgID == id) ) then
  4334. return "proposal", "accepted";
  4335. elseif ( queued ) then
  4336. return "queued", (empoweredFunc() and "empowered" or "unempowered");
  4337. elseif ( roleCheckInProgress and roleUpdateCategory == category and (not lfgID or lfgID == roleUpdateID) ) then
  4338. return "rolecheck";
  4339. elseif ( category == LE_LFG_CATEGORY_LFR and joined ) then
  4340. return "listed", (empoweredFunc() and "empowered" or "unempowered");
  4341. elseif ( joined ) then
  4342. return "suspended", (empoweredFunc() and "empowered" or "unempowered"); --We are "joined" to LFG, but not actually queued right now.
  4343. elseif ( IsInGroup() and IsPartyLFG() and partyCategory == category and (not lfgID or lfgID == partySlot) ) then
  4344. if IsAllowedToUserTeleport() then
  4345. return "lfgparty", "teleport";
  4346. end
  4347. if IsLFGComplete() then
  4348. return "lfgparty", "complete";
  4349. end
  4350. return "lfgparty", "noteleport";
  4351. elseif ( IsPartyLFG() and IsInLFGDungeon() and partyCategory == category and (not lfgID or lfgID == partySlot) ) then
  4352. return "abandonedInDungeon";
  4353. end
  4354. end
  4355. function IsLFGModeActive(category)
  4356. local partySlot = GetPartyLFGID();
  4357. local partyCategory = nil;
  4358. if ( partySlot ) then
  4359. partyCategory = GetLFGCategoryForID(partySlot);
  4360. end
  4361. if ( partyCategory == category ) then
  4362. return true;
  4363. end
  4364. return false;
  4365. end
  4366. --Like date(), but localizes AM/PM. In the future, could also localize other stuff.
  4367. function BetterDate(formatString, timeVal)
  4368. local dateTable = date("*t", timeVal);
  4369. local amString = (dateTable.hour >= 12) and TIMEMANAGER_PM or TIMEMANAGER_AM;
  4370. --First, we'll replace %p with the appropriate AM or PM.
  4371. formatString = gsub(formatString, "^%%p", amString) --Replaces %p at the beginning of the string with the am/pm token
  4372. formatString = gsub(formatString, "([^%%])%%p", "%1"..amString); -- Replaces %p anywhere else in the string, but doesn't replace %%p (since the first % escapes the second)
  4373. return date(formatString, timeVal);
  4374. end
  4375. function GMError(...)
  4376. if ( IsGMClient() ) then
  4377. error(...);
  4378. end
  4379. end
  4380. function OnExcessiveErrors()
  4381. StaticPopup_Show("TOO_MANY_LUA_ERRORS");
  4382. end
  4383. function SetLargeGuildTabardTextures(unit, emblemTexture, backgroundTexture, borderTexture, tabardData)
  4384. -- texure dimensions are 1024x1024, icon dimensions are 64x64
  4385. local emblemSize, columns, offset;
  4386. if ( emblemTexture ) then
  4387. emblemSize = 64 / 1024;
  4388. columns = 16
  4389. offset = 0;
  4390. emblemTexture:SetTexture("Interface\\GuildFrame\\GuildEmblemsLG_01");
  4391. end
  4392. local hasEmblem = SetGuildTabardTextures(emblemSize, columns, offset, unit, emblemTexture, backgroundTexture, borderTexture, tabardData);
  4393. emblemTexture:SetWidth(hasEmblem and (emblemTexture:GetHeight() * (7 / 8)) or emblemTexture:GetHeight());
  4394. end
  4395. function SetSmallGuildTabardTextures(unit, emblemTexture, backgroundTexture, borderTexture, tabardData)
  4396. -- texure dimensions are 256x256, icon dimensions are 16x16, centered in 18x18 cells
  4397. local emblemSize, columns, offset;
  4398. if ( emblemTexture ) then
  4399. emblemSize = 18 / 256;
  4400. columns = 14;
  4401. offset = 1 / 256;
  4402. emblemTexture:SetTexture("Interface\\GuildFrame\\GuildEmblems_01");
  4403. end
  4404. SetGuildTabardTextures(emblemSize, columns, offset, unit, emblemTexture, backgroundTexture, borderTexture, tabardData);
  4405. end
  4406. function SetDoubleGuildTabardTextures(unit, leftEmblemTexture, rightEmblemTexture, backgroundTexture, borderTexture, tabardData)
  4407. if ( leftEmblemTexture and rightEmblemTexture ) then
  4408. SetGuildTabardTextures(nil, nil, nil, unit, leftEmblemTexture, backgroundTexture, borderTexture, tabardData);
  4409. rightEmblemTexture:SetTexture(leftEmblemTexture:GetTexture());
  4410. rightEmblemTexture:SetVertexColor(leftEmblemTexture:GetVertexColor());
  4411. end
  4412. end
  4413. function SetGuildTabardTextures(emblemSize, columns, offset, unit, emblemTexture, backgroundTexture, borderTexture, tabardData)
  4414. local backgroundColor, borderColor, emblemColor, emblemFileID, emblemIndex;
  4415. tabardData = tabardData or C_GuildInfo.GetGuildTabardInfo(unit);
  4416. if(tabardData) then
  4417. backgroundColor = tabardData.backgroundColor;
  4418. borderColor = tabardData.borderColor;
  4419. emblemColor = tabardData.emblemColor;
  4420. emblemFileID = tabardData.emblemFileID;
  4421. emblemIndex = tabardData.emblemStyle;
  4422. end
  4423. if (emblemFileID) then
  4424. if (backgroundTexture) then
  4425. backgroundTexture:SetVertexColor(backgroundColor:GetRGB());
  4426. end
  4427. if (borderTexture) then
  4428. borderTexture:SetVertexColor(borderColor:GetRGB());
  4429. end
  4430. if (emblemSize) then
  4431. if (emblemIndex) then
  4432. local xCoord = mod(emblemIndex, columns) * emblemSize;
  4433. local yCoord = floor(emblemIndex / columns) * emblemSize;
  4434. emblemTexture:SetTexCoord(xCoord + offset, xCoord + emblemSize - offset, yCoord + offset, yCoord + emblemSize - offset);
  4435. end
  4436. emblemTexture:SetVertexColor(emblemColor:GetRGB());
  4437. elseif (emblemTexture) then
  4438. emblemTexture:SetTexture(emblemFileID);
  4439. emblemTexture:SetVertexColor(emblemColor:GetRGB());
  4440. end
  4441. return true;
  4442. else
  4443. -- tabard lacks design
  4444. if (backgroundTexture) then
  4445. backgroundTexture:SetVertexColor(0.2245, 0.2088, 0.1794);
  4446. end
  4447. if (borderTexture) then
  4448. borderTexture:SetVertexColor(0.2, 0.2, 0.2);
  4449. end
  4450. if (emblemTexture) then
  4451. if (emblemSize) then
  4452. if (emblemSize == 18 / 256) then
  4453. emblemTexture:SetTexture("Interface\\GuildFrame\\GuildLogo-NoLogoSm");
  4454. else
  4455. emblemTexture:SetTexture("Interface\\GuildFrame\\GuildLogo-NoLogo");
  4456. end
  4457. emblemTexture:SetTexCoord(0, 1, 0, 1);
  4458. emblemTexture:SetVertexColor(1, 1, 1, 1);
  4459. else
  4460. emblemTexture:SetTexture("");
  4461. end
  4462. end
  4463. return false;
  4464. end
  4465. end
  4466. function GetDisplayedAllyFrames()
  4467. local useCompact = GetCVarBool("useCompactPartyFrames")
  4468. if ( IsActiveBattlefieldArena() and not useCompact and not C_PvP.IsInBrawl() ) then
  4469. return "party";
  4470. elseif ( IsInGroup() and (IsInRaid() or useCompact) ) then
  4471. return "raid";
  4472. elseif ( IsInGroup() ) then
  4473. return "party";
  4474. else
  4475. return nil;
  4476. end
  4477. end
  4478. local displayedCapMessage = false;
  4479. function TrialAccountCapReached_Inform(capType)
  4480. if ( displayedCapMessage or not GameLimitedMode_IsActive() ) then
  4481. return;
  4482. end
  4483. local info = ChatTypeInfo.SYSTEM;
  4484. if ( capType == "level" ) then
  4485. DEFAULT_CHAT_FRAME:AddMessage(CAPPED_LEVEL_TRIAL, info.r, info.g, info.b);
  4486. elseif ( capType == "money" ) then
  4487. DEFAULT_CHAT_FRAME:AddMessage(CAPPED_MONEY_TRIAL, info.r, info.g, info.b);
  4488. end
  4489. displayedCapMessage = true;
  4490. end
  4491. function AbbreviateLargeNumbers(value)
  4492. local strLen = strlen(value);
  4493. local retString = value;
  4494. if ( strLen > 8 ) then
  4495. retString = string.sub(value, 1, -7)..SECOND_NUMBER_CAP;
  4496. elseif ( strLen > 5 ) then
  4497. retString = string.sub(value, 1, -4)..FIRST_NUMBER_CAP;
  4498. elseif (strLen > 3 ) then
  4499. retString = BreakUpLargeNumbers(value);
  4500. end
  4501. return retString;
  4502. end
  4503. NUMBER_ABBREVIATION_DATA = {
  4504. -- Order these from largest to smallest
  4505. -- (significandDivisor and fractionDivisor should multiply to be equal to breakpoint)
  4506. { breakpoint = 10000000000000, abbreviation = FOURTH_NUMBER_CAP_NO_SPACE, significandDivisor = 1000000000000, fractionDivisor = 1 },
  4507. { breakpoint = 1000000000000, abbreviation = FOURTH_NUMBER_CAP_NO_SPACE, significandDivisor = 100000000000, fractionDivisor = 10 },
  4508. { breakpoint = 10000000000, abbreviation = THIRD_NUMBER_CAP_NO_SPACE, significandDivisor = 1000000000, fractionDivisor = 1 },
  4509. { breakpoint = 1000000000, abbreviation = THIRD_NUMBER_CAP_NO_SPACE, significandDivisor = 100000000, fractionDivisor = 10 },
  4510. { breakpoint = 10000000, abbreviation = SECOND_NUMBER_CAP_NO_SPACE, significandDivisor = 1000000, fractionDivisor = 1 },
  4511. { breakpoint = 1000000, abbreviation = SECOND_NUMBER_CAP_NO_SPACE, significandDivisor = 100000, fractionDivisor = 10 },
  4512. { breakpoint = 10000, abbreviation = FIRST_NUMBER_CAP_NO_SPACE, significandDivisor = 1000, fractionDivisor = 1 },
  4513. { breakpoint = 1000, abbreviation = FIRST_NUMBER_CAP_NO_SPACE, significandDivisor = 100, fractionDivisor = 10 },
  4514. }
  4515. function AbbreviateNumbers(value)
  4516. for i, data in ipairs(NUMBER_ABBREVIATION_DATA) do
  4517. if value >= data.breakpoint then
  4518. local finalValue = math.floor(value / data.significandDivisor) / data.fractionDivisor;
  4519. return finalValue .. data.abbreviation;
  4520. end
  4521. end
  4522. return tostring(value);
  4523. end
  4524. function IsInLFDBattlefield()
  4525. return IsLFGModeActive(LE_LFG_CATEGORY_BATTLEFIELD);
  4526. end
  4527. function LeaveInstanceParty()
  4528. if ( IsInLFDBattlefield() ) then
  4529. local currentMapID, _, lfgID = select(8, GetInstanceInfo());
  4530. local _, typeID, subtypeID, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, lfgMapID = GetLFGDungeonInfo(lfgID);
  4531. if currentMapID == lfgMapID and subtypeID == LE_LFG_CATEGORY_BATTLEFIELD then
  4532. LFGTeleport(true);
  4533. return;
  4534. end
  4535. end
  4536. C_PartyInfo.LeaveParty(LE_PARTY_CATEGORY_INSTANCE);
  4537. end
  4538. function ConfirmOrLeaveLFGParty()
  4539. if ( not IsInGroup(LE_PARTY_CATEGORY_INSTANCE) ) then
  4540. return;
  4541. end
  4542. if ( IsPartyLFG() and not IsLFGComplete() ) then
  4543. local partyLFGSlot = GetPartyLFGID();
  4544. local partyLFGCategory = nil;
  4545. if ( partyLFGSlot ) then
  4546. partyLFGCategory = GetLFGCategoryForID(partyLFGSlot);
  4547. end
  4548. StaticPopup_Show("CONFIRM_LEAVE_INSTANCE_PARTY", partyLFGCategory == LE_LFG_CATEGORY_WORLDPVP and CONFIRM_LEAVE_BATTLEFIELD or CONFIRM_LEAVE_INSTANCE_PARTY);
  4549. else
  4550. LeaveInstanceParty();
  4551. end
  4552. end
  4553. function ConfirmOrLeaveBattlefield()
  4554. if ( GetBattlefieldWinner() ) then
  4555. LeaveBattlefield();
  4556. else
  4557. StaticPopup_Show("CONFIRM_LEAVE_BATTLEFIELD");
  4558. end
  4559. end
  4560. function ConfirmSurrenderArena()
  4561. StaticPopup_Show("CONFIRM_SURRENDER_ARENA");
  4562. end
  4563. function GetCurrentScenarioType()
  4564. local scenarioType = select(10, C_Scenario.GetInfo());
  4565. return scenarioType;
  4566. end
  4567. function IsBoostTutorialScenario()
  4568. return GetCurrentScenarioType() == LE_SCENARIO_TYPE_BOOST_TUTORIAL;
  4569. end
  4570. function PrintLootSpecialization()
  4571. local specID = GetLootSpecialization();
  4572. local sex = UnitSex("player");
  4573. local lootSpecChoice;
  4574. if ( specID and specID > 0 ) then
  4575. local id, name = GetSpecializationInfoByID(specID, sex);
  4576. lootSpecChoice = format(ERR_LOOT_SPEC_CHANGED_S, name);
  4577. --[[ else
  4578. local specIndex = GetSpecialization();
  4579. if ( specIndex) then
  4580. local specID, specName = GetSpecializationInfo(specIndex, nil, nil, nil, sex);
  4581. if ( specName ) then
  4582. lootSpecChoice = format(ERR_LOOT_SPEC_CHANGED_S, format(LOOT_SPECIALIZATION_DEFAULT, specName));
  4583. end
  4584. end]]
  4585. end
  4586. if ( lootSpecChoice ) then
  4587. local info = ChatTypeInfo["SYSTEM"];
  4588. DEFAULT_CHAT_FRAME:AddMessage(lootSpecChoice, info.r, info.g, info.b, info.id);
  4589. end
  4590. end
  4591. function BuildIconArray(parent, baseName, template, rowSize, numRows, onButtonCreated)
  4592. local previousButton = CreateFrame("CheckButton", baseName.."1", parent, template);
  4593. local cornerButton = previousButton;
  4594. previousButton:SetID(1);
  4595. previousButton:SetPoint("TOPLEFT", 26, -85);
  4596. if ( onButtonCreated ) then
  4597. onButtonCreated(parent, previousButton);
  4598. end
  4599. local numIcons = rowSize * numRows;
  4600. for i = 2, numIcons do
  4601. local newButton = CreateFrame("CheckButton", baseName..i, parent, template);
  4602. newButton:SetID(i);
  4603. if ( i % rowSize == 1 ) then
  4604. newButton:SetPoint("TOPLEFT", cornerButton, "BOTTOMLEFT", 0, -8);
  4605. cornerButton = newButton;
  4606. else
  4607. newButton:SetPoint("LEFT", previousButton, "RIGHT", 10, 0);
  4608. end
  4609. previousButton = newButton;
  4610. newButton:Hide();
  4611. if ( onButtonCreated ) then
  4612. onButtonCreated(parent, newButton);
  4613. end
  4614. end
  4615. end
  4616. function GetSmoothProgressChange(value, displayedValue, range, elapsed, minPerSecond, maxPerSecond)
  4617. maxPerSecond = maxPerSecond or 0.7;
  4618. minPerSecond = minPerSecond or 0.3;
  4619. minPerSecond = max(minPerSecond, 1/range); --Make sure we're moving at least 1 unit/second (will only matter if our maximum power is 3 or less);
  4620. local diff = displayedValue - value;
  4621. local diffRatio = diff / range;
  4622. local change = range * ((minPerSecond/abs(diffRatio) + maxPerSecond - minPerSecond) * diffRatio) * elapsed;
  4623. if ( abs(change) > abs(diff) or abs(diffRatio) < 0.01 ) then
  4624. return value;
  4625. else
  4626. return displayedValue - change;
  4627. end
  4628. end
  4629. function InGlue()
  4630. return false;
  4631. end
  4632. function RGBToColorCode(r, g, b)
  4633. return format("|cff%02x%02x%02x", r*255, g*255, b*255);
  4634. end
  4635. function RGBTableToColorCode(rgbTable)
  4636. return RGBToColorCode(rgbTable.r, rgbTable.g, rgbTable.b);
  4637. end
  4638. function WillAcceptInviteRemoveQueues()
  4639. --Dungeon/Raid Finder
  4640. for i=1, NUM_LE_LFG_CATEGORYS do
  4641. local mode = GetLFGMode(i);
  4642. if ( mode and mode ~= "lfgparty" ) then
  4643. return true;
  4644. end
  4645. end
  4646. --Don't need to look at LFGList listings because we can't accept invites while in one
  4647. --LFGList applications
  4648. local apps = C_LFGList.GetApplications();
  4649. for i=1, #apps do
  4650. local _, appStatus = C_LFGList.GetApplicationInfo(apps[i]);
  4651. if ( appStatus == "applied" or appStatus == "invited" ) then
  4652. return true;
  4653. end
  4654. end
  4655. --PvP
  4656. for i=1, GetMaxBattlefieldID() do
  4657. local status, mapName, teamSize, registeredMatch, suspend = GetBattlefieldStatus(i);
  4658. if ( status == "queued" or status == "confirmed" ) then
  4659. return true;
  4660. end
  4661. end
  4662. return false;
  4663. end
  4664. --Only really works on friends and guild-mates
  4665. function GetDisplayedInviteType(guid)
  4666. if ( IsInGroup() ) then
  4667. if ( UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") ) then
  4668. return "INVITE";
  4669. else
  4670. return "SUGGEST_INVITE";
  4671. end
  4672. else
  4673. if ( not guid ) then
  4674. return "INVITE";
  4675. end
  4676. local party, isSoloQueueParty = C_SocialQueue.GetGroupForPlayer(guid);
  4677. if ( party and not isSoloQueueParty ) then --In a real party, not a secret hidden party for solo queuing
  4678. return "REQUEST_INVITE";
  4679. elseif ( WillAcceptInviteRemoveQueues() ) then
  4680. return "INVITE";
  4681. elseif ( party ) then --They are queued solo for something
  4682. return "REQUEST_INVITE";
  4683. else
  4684. return "INVITE";
  4685. end
  4686. end
  4687. end
  4688. function nop()
  4689. end
  4690. function ShakeFrameRandom(frame, magnitude, duration, frequency)
  4691. if frequency <= 0 then
  4692. return;
  4693. end
  4694. local shake = {};
  4695. for i = 1, math.ceil(duration / frequency) do
  4696. local xVariation, yVariation = RandomFloatInRange(-magnitude, magnitude), RandomFloatInRange(-magnitude, magnitude);
  4697. shake[i] = { x = xVariation, y = yVariation };
  4698. end
  4699. ShakeFrame(frame, shake, duration, frequency);
  4700. end
  4701. function ShakeFrame(frame, shake, maximumDuration, frequency)
  4702. if ( frame.shakeTicker and not frame.shakeTicker:IsCancelled() ) then
  4703. return;
  4704. end
  4705. local point, relativeFrame, relativePoint, x, y = frame:GetPoint();
  4706. local shakeIndex = 1;
  4707. local endTime = GetTime() + maximumDuration;
  4708. frame.shakeTicker = C_Timer.NewTicker(frequency, function()
  4709. local xVariation, yVariation = shake[shakeIndex].x, shake[shakeIndex].y;
  4710. frame:SetPoint(point, relativeFrame, relativePoint, x + xVariation, y + yVariation);
  4711. shakeIndex = shakeIndex + 1;
  4712. if shakeIndex > #shake or GetTime() >= endTime then
  4713. frame:SetPoint(point, relativeFrame, relativePoint, x, y);
  4714. frame.shakeTicker:Cancel();
  4715. end
  4716. end);
  4717. end
  4718. -- Currency Overflow --
  4719. function WillCurrencyRewardOverflow(currencyID, rewardQuantity)
  4720. local name, quantity, icon, earnedThisWeek, weeklyMax, maxQuantity, discovered, rarity = GetCurrencyInfo(currencyID);
  4721. return maxQuantity > 0 and rewardQuantity + quantity > maxQuantity;
  4722. end
  4723. function GetColorForCurrencyReward(currencyID, rewardQuantity, defaultColor)
  4724. if WillCurrencyRewardOverflow(currencyID, rewardQuantity) then
  4725. return RED_FONT_COLOR;
  4726. elseif defaultColor then
  4727. return defaultColor;
  4728. else
  4729. return HIGHLIGHT_FONT_COLOR;
  4730. end
  4731. end
  4732. function GetSortedSelfResurrectOptions()
  4733. local options = C_DeathInfo.GetSelfResurrectOptions();
  4734. if ( not options ) then
  4735. return nil;
  4736. end
  4737. table.sort(options, function(a, b)
  4738. if ( a.canUse ~= b.canUse ) then
  4739. return a.canUse;
  4740. end
  4741. if ( a.isLimited ~= b.isLimited ) then
  4742. return not a.isLimited;
  4743. end
  4744. -- lowest priority is first
  4745. return a.priority < b.priority end
  4746. );
  4747. return options;
  4748. end
  4749. function OpenAchievementFrameToAchievement(achievementID)
  4750. if ( not AchievementFrame ) then
  4751. AchievementFrame_LoadUI();
  4752. end
  4753. if ( not AchievementFrame:IsShown() ) then
  4754. AchievementFrame_ToggleAchievementFrame();
  4755. end
  4756. AchievementFrame_SelectAchievement(achievementID);
  4757. end
  4758. function ChatClassColorOverrideShown()
  4759. local value = GetCVar("chatClassColorOverride");
  4760. if value == "0" then
  4761. return true;
  4762. elseif value == "1" then
  4763. return false;
  4764. else
  4765. return nil;
  4766. end
  4767. end
  4768. -- takes into account the current expansion
  4769. -- NOTE: it's not safe to cache this value as it could change in the middle of the session
  4770. function GetEffectivePlayerMaxLevel()
  4771. return MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()];
  4772. end
  4773. function IsLevelAtEffectiveMaxLevel(level)
  4774. return level >= GetEffectivePlayerMaxLevel();
  4775. end
  4776. function IsPlayerAtEffectiveMaxLevel()
  4777. return IsLevelAtEffectiveMaxLevel(UnitLevel("player"));
  4778. end
  4779. function DisplayInterfaceActionBlockedMessage()
  4780. if ( not INTERFACE_ACTION_BLOCKED_SHOWN ) then
  4781. local info = ChatTypeInfo["SYSTEM"];
  4782. DEFAULT_CHAT_FRAME:AddMessage(INTERFACE_ACTION_BLOCKED, info.r, info.g, info.b, info.id);
  4783. INTERFACE_ACTION_BLOCKED_SHOWN = true;
  4784. end
  4785. end