diff --git a/SVUI_!Core/SVUI_!Core.toc b/SVUI_!Core/SVUI_!Core.toc index ea1fa43..14009e8 100644 --- a/SVUI_!Core/SVUI_!Core.toc +++ b/SVUI_!Core/SVUI_!Core.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.8 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cff00FF00!Core|r ## Notes: SVUI [|cff9911FFCore Framework|r]. ## SavedVariables: SVUI_Global, SVUI_Errors, SVUI_Filters, SVUI_Media, SVUI_Shared diff --git a/SVUI_!Core/system/api.lua b/SVUI_!Core/system/api.lua index 7b0b9ea..f291f66 100644 --- a/SVUI_!Core/system/api.lua +++ b/SVUI_!Core/system/api.lua @@ -1498,9 +1498,9 @@ API INJECTION ]]-- local MODIFIED_OBJECTS = {}; -local function AppendFrameMethods(OBJECT) +local function AppendFrameMethods(OBJECT, FORCE) local objType = OBJECT:GetObjectType() - if(not MODIFIED_OBJECTS[objType]) then + if(FORCE or (not MODIFIED_OBJECTS[objType])) then local META = getmetatable(OBJECT).__index if not OBJECT.SetStyle then META.SetStyle = SetStyle end if not OBJECT.SetPanelColor then META.SetPanelColor = SetPanelColor end @@ -1545,15 +1545,19 @@ AppendFrameMethods(CURRENT_OBJECT) AppendTextureMethods(CURRENT_OBJECT:CreateTexture()) AppendFontStringMethods(CURRENT_OBJECT:CreateFontString()) -function SV:AppendAPI(obj) - AppendFrameMethods(obj) -end - CURRENT_OBJECT = EnumerateFrames() while CURRENT_OBJECT do AppendFrameMethods(CURRENT_OBJECT) CURRENT_OBJECT = EnumerateFrames(CURRENT_OBJECT) end + +function SV:AppendAPI() + local NEW_OBJECT = EnumerateFrames() + while NEW_OBJECT do + AppendFrameMethods(NEW_OBJECT, true) + NEW_OBJECT = EnumerateFrames(NEW_OBJECT) + end +end --[[ ########################################################## STYLING CONCEPTS diff --git a/SVUI_!Core/system/dock.lua b/SVUI_!Core/system/dock.lua index 27fea81..8f7beb8 100644 --- a/SVUI_!Core/system/dock.lua +++ b/SVUI_!Core/system/dock.lua @@ -2139,6 +2139,7 @@ function MOD:Load() dock.Window:ClearAllPoints() dock.Window:SetSize(width, height) dock.Window:SetPoint(anchor, dock.Alert, reverse, 0, 4) + dock.Window:SetFrameStrata("BACKGROUND") SV:NewAnchor(dock.Bar, location .. " Dock ToolBar"); SV:SetAnchorResizing(dock.Bar, dockBarPostSizeFunc, 10, 500, 10, 80); diff --git a/SVUI_!Options/SVUI_!Options.toc b/SVUI_!Options/SVUI_!Options.toc index b9d6440..5e72dda 100644 --- a/SVUI_!Options/SVUI_!Options.toc +++ b/SVUI_!Options/SVUI_!Options.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cff00FF00!Options|r ## Notes: SVUI [|cff9911FFConfig Options|r] ## RequiredDeps: SVUI_!Core diff --git a/SVUI_ActionBars/SVUI_ActionBars.toc b/SVUI_ActionBars/SVUI_ActionBars.toc index a24b866..0233365 100644 --- a/SVUI_ActionBars/SVUI_ActionBars.toc +++ b/SVUI_ActionBars/SVUI_ActionBars.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Action Bars|r ## Notes: Action Bar Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0, LibActionButton-1.0 diff --git a/SVUI_Auras/SVUI_Auras.toc b/SVUI_Auras/SVUI_Auras.toc index cdd1de2..58db28a 100644 --- a/SVUI_Auras/SVUI_Auras.toc +++ b/SVUI_Auras/SVUI_Auras.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Auras|r ## Notes: Aura Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_Chat/SVUI_Chat.toc b/SVUI_Chat/SVUI_Chat.toc index 3c14d29..b61efc0 100644 --- a/SVUI_Chat/SVUI_Chat.toc +++ b/SVUI_Chat/SVUI_Chat.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Chat|r ## Notes: Chat Plugin for [|cff9911FFSVUI|r]. ## SavedVariables: SVUI_Global_ChatCache diff --git a/SVUI_Inventory/SVUI_Inventory.toc b/SVUI_Inventory/SVUI_Inventory.toc index 029389b..3392b02 100644 --- a/SVUI_Inventory/SVUI_Inventory.toc +++ b/SVUI_Inventory/SVUI_Inventory.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Inventory|r ## Notes: Inventory Plugin for [|cff9911FFSVUI|r]. ## SavedVariables: SVUI_LootCache diff --git a/SVUI_Maps/SVUI_Maps.toc b/SVUI_Maps/SVUI_Maps.toc index a74d658..7229c8a 100644 --- a/SVUI_Maps/SVUI_Maps.toc +++ b/SVUI_Maps/SVUI_Maps.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Maps|r ## Notes: Maps Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_NamePlates/SVUI_NamePlates.toc b/SVUI_NamePlates/SVUI_NamePlates.toc index 257a57a..d903d08 100644 --- a/SVUI_NamePlates/SVUI_NamePlates.toc +++ b/SVUI_NamePlates/SVUI_NamePlates.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00NamePlates|r ## Notes: NamePlates Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_PKG.toc b/SVUI_PKG.toc index 00dc63d..0f349e0 100644 --- a/SVUI_PKG.toc +++ b/SVUI_PKG.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI|r ## RequiredDeps: SVUI_!Core, SVUI_!Options ## X-Email: munglunch@gmail.com diff --git a/SVUI_QuestTracker/SVUI_QuestTracker.toc b/SVUI_QuestTracker/SVUI_QuestTracker.toc index 6a3e7d0..67776a2 100644 --- a/SVUI_QuestTracker/SVUI_QuestTracker.toc +++ b/SVUI_QuestTracker/SVUI_QuestTracker.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00QuestTracker|r ## Notes: QuestTracker Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_Skins/SVUI_Skins.lua b/SVUI_Skins/SVUI_Skins.lua index 2a233bf..90c8b5d 100644 --- a/SVUI_Skins/SVUI_Skins.lua +++ b/SVUI_Skins/SVUI_Skins.lua @@ -207,10 +207,15 @@ end function MOD:ADDON_LOADED(event, addon) --print(addon) + local apiRefreshed = false; local needsUpdate = false for name, fn in pairs(self.OnLoadAddons) do if(addon:find(name)) then self.Debugging = self.DebugInternal + if(not apiRefreshed) then + SV:AppendAPI(); + apiRefreshed = true + end if(self:Style(name, fn, event, addon)) then self.OnLoadAddons[name] = nil needsUpdate = true @@ -223,6 +228,10 @@ function MOD:ADDON_LOADED(event, addon) for name, fn in pairs(self.AddOnQueue) do if(listener[name] and self:IsAddonReady(name)) then self.Debugging = self.DebugExternal + if(not apiRefreshed) then + SV:AppendAPI(); + apiRefreshed = true + end if(self:Style(name, fn, event, addon)) then self.AddOnQueue[name] = nil needsUpdate = true diff --git a/SVUI_Skins/SVUI_Skins.toc b/SVUI_Skins/SVUI_Skins.toc index 7fd8563..f554e19 100644 --- a/SVUI_Skins/SVUI_Skins.toc +++ b/SVUI_Skins/SVUI_Skins.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder, Azilroka, Sortokk -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Skins|r ## Notes: SVUI [|cff9911FFSkins System and AddOn Frames|r]. ## SavedVariables: SVUIUI_STYLE_GLOBAL diff --git a/SVUI_Skins/components/blizzard/auctionhouse.lua b/SVUI_Skins/components/blizzard/auctionhouse.lua index 7b6412b..f3a4767 100644 --- a/SVUI_Skins/components/blizzard/auctionhouse.lua +++ b/SVUI_Skins/components/blizzard/auctionhouse.lua @@ -75,7 +75,7 @@ local AuctionTextFields = { AUCTIONFRAME MODR ########################################################## ]]-- -local _hook_FilterButton_SetType = function(button) +local _hook_FilterButton_SetUp = function(button) if(button) then local normalTexture = _G[button:GetName().."NormalTexture"]; normalTexture:SetTexture("") @@ -124,15 +124,15 @@ local function AuctionStyle() AuctionProgressFrameCancelButton:GetNormalTexture():SetTexCoord(0.67, 0.37, 0.61, 0.26) AuctionProgressFrameCancelButton:SetSize(28, 28) AuctionProgressFrameCancelButton:SetPoint("LEFT", AuctionProgressBar, "RIGHT", 8, 0) - AuctionProgressBarIcon:SetTexCoord(0.67, 0.37, 0.61, 0.26) + AuctionProgressBar.Icon:SetTexCoord(0.67, 0.37, 0.61, 0.26) - local AuctionProgressBarBG = CreateFrame("Frame", nil, AuctionProgressBarIcon:GetParent()) - AuctionProgressBarBG:WrapPoints(AuctionProgressBarIcon) + local AuctionProgressBarBG = CreateFrame("Frame", nil, AuctionProgressBar.Icon:GetParent()) + AuctionProgressBarBG:WrapPoints(AuctionProgressBar.Icon) AuctionProgressBarBG:SetStyle("!_Frame", "Default") - AuctionProgressBarIcon:SetParent(AuctionProgressBarBG) + AuctionProgressBar.Icon:SetParent(AuctionProgressBarBG) - AuctionProgressBarText:ClearAllPoints() - AuctionProgressBarText:SetPoint("CENTER") + AuctionProgressBar.Text:ClearAllPoints() + AuctionProgressBar.Text:SetPoint("CENTER") AuctionProgressBar:RemoveTextures() AuctionProgressBar:SetStyle("Frame", "Default") AuctionProgressBar:SetStatusBarTexture(SV.media.statusbar.default) @@ -195,7 +195,7 @@ local function AuctionStyle() AuctionFrameBrowse.bg2:SetPoint("BOTTOMRIGHT", AuctionFrame, "BOTTOMRIGHT", -8, 40) AuctionFrameBrowse.bg2:SetFrameLevel(AuctionFrameBrowse.bg2:GetFrameLevel() - 1) - hooksecurefunc("FilterButton_SetType", _hook_FilterButton_SetType) + hooksecurefunc("FilterButton_SetUp", _hook_FilterButton_SetUp) for _,field in pairs(AuctionTextFields) do --_G[field]:RemoveTextures() diff --git a/SVUI_Skins/components/blizzard/collections.lua b/SVUI_Skins/components/blizzard/collections.lua index 6b7d016..3cafdf5 100644 --- a/SVUI_Skins/components/blizzard/collections.lua +++ b/SVUI_Skins/components/blizzard/collections.lua @@ -352,6 +352,18 @@ local function CollectionsJournalStyle() end SV.API:Set("Tab", CollectionsJournalTab5) + + SV.API:Set("Window", WardrobeFrame, true, true, 1, 3, 3) + + WardrobeTransmogFrame:RemoveTextures() + WardrobeTransmogFrame.Inset:RemoveTextures() + WardrobeTransmogFrame.Model:SetStyle("!_Frame", 'Model') + WardrobeTransmogFrame.OutfitHelpBox:SetStyle("!_Frame", 'Premium') + WardrobeTransmogFrame.ApplyButton:SetStyle("Button") + WardrobeTransmogFrame.SpecButton:SetStyle("Button") + SV.API:Set("DropDown", WardrobeTransmogFrame.SpecDropDown) + SV.API:Set("DropDown", WardrobeTransmogFrame.OutfitDropDown) + WardrobeCollectionFrame:RemoveTextures() WardrobeCollectionFrameSearchBox:SetStyle("Editbox") WardrobeCollectionFrame.FilterButton:RemoveTextures(true) diff --git a/SVUI_Skins/components/blizzard/guild.lua b/SVUI_Skins/components/blizzard/guild.lua index 3825c11..5a9e2c9 100644 --- a/SVUI_Skins/components/blizzard/guild.lua +++ b/SVUI_Skins/components/blizzard/guild.lua @@ -521,7 +521,7 @@ local function GuildFrameStyle() GuildFactionBar.Panel:SetPoint("TOPLEFT", GuildFactionBar.progress, "TOPLEFT", -1, 1) GuildFactionBar.Panel:SetPoint("BOTTOMRIGHT", GuildFactionBar, "BOTTOMRIGHT", 1, 1) - -- FIXME GuildRosterContainer:SetStyle("Frame", "Inset") + GuildRosterContainer:SetStyle("Frame", "Inset") SV.API:Set("ScrollBar", GuildRosterContainerScrollBar, 4, -4) GuildRosterShowOfflineButton:SetStyle("CheckButton") @@ -547,7 +547,7 @@ local function GuildFrameStyle() GuildMemberRankDropdown:HookScript("OnShow", function() GuildMemberDetailRankText:Hide() end) GuildMemberRankDropdown:HookScript("OnHide", function() GuildMemberDetailRankText:Show() end) GuildNewsFrame:RemoveTextures() - -- FIXME GuildNewsContainer:SetStyle("Frame", "Inset") + GuildNewsContainer:SetStyle("Frame", "Inset") for i = 1, 17 do local button = _G["GuildNewsContainerButton"..i] diff --git a/SVUI_Tooltip/SVUI_Tooltip.toc b/SVUI_Tooltip/SVUI_Tooltip.toc index 039420d..a0ba50e 100644 --- a/SVUI_Tooltip/SVUI_Tooltip.toc +++ b/SVUI_Tooltip/SVUI_Tooltip.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00Tooltip|r ## Notes: Tooltip Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_UnitFrames/SVUI_UnitFrames.toc b/SVUI_UnitFrames/SVUI_UnitFrames.toc index 6869b18..c5f6b24 100644 --- a/SVUI_UnitFrames/SVUI_UnitFrames.toc +++ b/SVUI_UnitFrames/SVUI_UnitFrames.toc @@ -1,6 +1,6 @@ ## Interface: 70100 ## Author: Failcoder -## Version: 1.3.7 +## Version: 1.3.9 ## Title: |cffFF9900SuperVillain UI: |r|cffFFEF00UnitFrames|r ## Notes: UnitFrames Plugin for [|cff9911FFSVUI|r]. ## OptionalDeps: LibSharedMedia-3.0 diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/LICENSE b/SVUI_UnitFrames/libs/oUF_1.6.9/LICENSE new file mode 100644 index 0000000..871e18e --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2006-2014 Trond A Ekseth <troeks@gmail.com> + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/blizzard.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/blizzard.lua new file mode 100644 index 0000000..271b988 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/blizzard.lua @@ -0,0 +1,102 @@ +local parent, ns = ... +local oUF = ns.oUF + +local hiddenParent = CreateFrame("Frame") +hiddenParent:Hide() + +local HandleFrame = function(baseName) + local frame + if(type(baseName) == 'string') then + frame = _G[baseName] + else + frame = baseName + end + + if(frame) then + frame:UnregisterAllEvents() + frame:Hide() + + -- Keep frame hidden without causing taint + frame:SetParent(hiddenParent) + + local health = frame.healthbar + if(health) then + health:UnregisterAllEvents() + end + + local power = frame.manabar + if(power) then + power:UnregisterAllEvents() + end + + local spell = frame.spellbar + if(spell) then + spell:UnregisterAllEvents() + end + + local altpowerbar = frame.powerBarAlt + if(altpowerbar) then + altpowerbar:UnregisterAllEvents() + end + end +end + +function oUF:DisableBlizzard(unit) + if(not unit) then return end + + if(unit == 'player') then + HandleFrame(PlayerFrame) + + -- For the damn vehicle support: + PlayerFrame:RegisterEvent('PLAYER_ENTERING_WORLD') + PlayerFrame:RegisterEvent('UNIT_ENTERING_VEHICLE') + PlayerFrame:RegisterEvent('UNIT_ENTERED_VEHICLE') + PlayerFrame:RegisterEvent('UNIT_EXITING_VEHICLE') + PlayerFrame:RegisterEvent('UNIT_EXITED_VEHICLE') + + -- User placed frames don't animate + PlayerFrame:SetUserPlaced(true) + PlayerFrame:SetDontSavePosition(true) + elseif(unit == 'pet') then + HandleFrame(PetFrame) + elseif(unit == 'target') then + HandleFrame(TargetFrame) + HandleFrame(ComboFrame) + elseif(unit == 'focus') then + HandleFrame(FocusFrame) + HandleFrame(TargetofFocusFrame) + elseif(unit == 'targettarget') then + HandleFrame(TargetFrameToT) + elseif(unit:match'(boss)%d?$' == 'boss') then + local id = unit:match'boss(%d)' + if(id) then + HandleFrame('Boss' .. id .. 'TargetFrame') + else + for i=1, 4 do + HandleFrame(('Boss%dTargetFrame'):format(i)) + end + end + elseif(unit:match'(party)%d?$' == 'party') then + local id = unit:match'party(%d)' + if(id) then + HandleFrame('PartyMemberFrame' .. id) + else + for i=1, 4 do + HandleFrame(('PartyMemberFrame%d'):format(i)) + end + end + elseif(unit:match'(arena)%d?$' == 'arena') then + local id = unit:match'arena(%d)' + if(id) then + HandleFrame('ArenaEnemyFrame' .. id) + else + for i=1, 4 do + HandleFrame(('ArenaEnemyFrame%d'):format(i)) + end + end + + -- Blizzard_ArenaUI should not be loaded + Arena_LoadUI = function() end + SetCVar('showArenaEnemyFrames', '0', 'SHOW_ARENA_ENEMY_FRAMES_TEXT') + end +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/colors.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/colors.lua new file mode 100644 index 0000000..0a50820 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/colors.lua @@ -0,0 +1,168 @@ +local parent, ns = ... +local oUF = ns.oUF +local Private = oUF.Private + +local frame_metatable = Private.frame_metatable + +local colors = { + smooth = { + 1, 0, 0, + 1, 1, 0, + 0, 1, 0 + }, + disconnected = {.6, .6, .6}, + tapped = {.6,.6,.6}, + class = {}, + reaction = {}, +} + +-- We do this because people edit the vars directly, and changing the default +-- globals makes SPICE FLOW! +local customClassColors = function() + if(CUSTOM_CLASS_COLORS) then + local updateColors = function() + for eclass, color in next, CUSTOM_CLASS_COLORS do + colors.class[eclass] = {color.r, color.g, color.b} + end + + for _, obj in next, oUF.objects do + obj:UpdateAllElements("CUSTOM_CLASS_COLORS") + end + end + + updateColors() + CUSTOM_CLASS_COLORS:RegisterCallback(updateColors) + + return true + end +end +if not customClassColors() then + for eclass, color in next, RAID_CLASS_COLORS do + colors.class[eclass] = {color.r, color.g, color.b} + end + + local f = CreateFrame("Frame") + f:RegisterEvent("ADDON_LOADED") + f:SetScript("OnEvent", function() + if customClassColors() then + f:UnregisterEvent("ADDON_LOADED") + f:SetScript("OnEvent", nil) + end + end) +end + +for eclass, color in next, FACTION_BAR_COLORS do + colors.reaction[eclass] = {color.r, color.g, color.b} +end + +local function ColorsAndPercent(a, b, ...) + if a <= 0 or b == 0 then + return nil, ... + elseif a >= b then + return nil, select(select('#', ...) - 2, ...) + end + + local num = select('#', ...) / 3 + local segment, relperc = math.modf((a/b)*(num-1)) + return relperc, select((segment*3)+1, ...) +end + +-- http://www.wowwiki.com/ColorGradient +local RGBColorGradient = function(...) + local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...) + if relperc then + return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc + else + return r1, g1, b1 + end +end + +-- HCY functions are based on http://www.chilliant.com/rgb2hsv.html +local function GetY(r, g, b) + return 0.299 * r + 0.587 * g + 0.114 * b +end + +local function RGBToHCY(r, g, b) + local min, max = min(r, g, b), max(r, g, b) + local chroma = max - min + local hue + if chroma > 0 then + if r == max then + hue = ((g - b) / chroma) % 6 + elseif g == max then + hue = (b - r) / chroma + 2 + elseif b == max then + hue = (r - g) / chroma + 4 + end + hue = hue / 6 + end + return hue, chroma, GetY(r, g, b) +end + +local abs = math.abs +local function HCYtoRGB(hue, chroma, luma) + local r, g, b = 0, 0, 0 + if hue and luma > 0 then + local h2 = hue * 6 + local x = chroma * (1 - abs(h2 % 2 - 1)) + if h2 < 1 then + r, g, b = chroma, x, 0 + elseif h2 < 2 then + r, g, b = x, chroma, 0 + elseif h2 < 3 then + r, g, b = 0, chroma, x + elseif h2 < 4 then + r, g, b = 0, x, chroma + elseif h2 < 5 then + r, g, b = x, 0, chroma + else + r, g, b = chroma, 0, x + end + local y = GetY(r, g, b) + if luma < y then + chroma = chroma * (luma / y) + elseif y < 1 then + chroma = chroma * (1 - luma) / (1 - y) + end + r = (r - y) * chroma + luma + g = (g - y) * chroma + luma + b = (b - y) * chroma + luma + end + return r, g, b +end + +local HCYColorGradient = function(...) + local relperc, r1, g1, b1, r2, g2, b2 = ColorsAndPercent(...) + if not relperc then return r1, g1, b1 end + local h1, c1, y1 = RGBToHCY(r1, g1, b1) + local h2, c2, y2 = RGBToHCY(r2, g2, b2) + local c = c1 + (c2-c1) * relperc + local y = y1 + (y2-y1) * relperc + if h1 and h2 then + local dh = h2 - h1 + if dh < -0.5 then + dh = dh + 1 + elseif dh > 0.5 then + dh = dh - 1 + end + return HCYtoRGB((h1 + dh * relperc) % 1, c, y) + else + return HCYtoRGB(h1 or h2, c, y) + end + +end + +local ColorGradient = function(...) + return (oUF.useHCYColorGradient and HCYColorGradient or RGBColorGradient)(...) +end + +Private.colors = colors + +oUF.colors = colors +oUF.ColorGradient = ColorGradient +oUF.RGBColorGradient = RGBColorGradient +oUF.HCYColorGradient = HCYColorGradient +oUF.useHCYColorGradient = false + +frame_metatable.__index.colors = colors +frame_metatable.__index.ColorGradient = ColorGradient diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/altpowerbar.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/altpowerbar.lua new file mode 100644 index 0000000..e95e93b --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/altpowerbar.lua @@ -0,0 +1,203 @@ +--[[ Element: Alternative Power Bar + + Handles visibility and updating of the alternative power bar. + + This bar is used to display encounter/quest related power information, such as + the number of hour glass uses left on the end boss in End Time. + + Widget + + AltPowerBar - A StatusBar to represent alternative power. + + Options + + .colorTexture - Use the vertex color values returned by + UnitAlternatePowerTextureInfo to color the bar. + + Notes + + OnEnter and OnLeave handlers to display a tooltip will be set on the widget if + it is mouse enabled. + + Examples + + -- Position and size + local AltPowerBar = CreateFrame('StatusBar', nil, self) + AltPowerBar:SetHeight(20) + AltPowerBar:SetPoint('BOTTOM') + AltPowerBar:SetPoint('LEFT') + AltPowerBar:SetPoint('RIGHT') + + -- Register with oUF + self.AltPowerBar = AltPowerBar + + Callbacks +]] + +local parent, ns = ... +local oUF = ns.oUF + +local ALTERNATE_POWER_INDEX = ALTERNATE_POWER_INDEX + +--[[ :UpdateTooltip() + + The function called when the widget is hovered. Used to populate the tooltip. + + Arguments + + self - The AltPowerBar element. +]] +local UpdateTooltip = function(self) + GameTooltip:SetText(self.powerName, 1, 1, 1) + GameTooltip:AddLine(self.powerTooltip, nil, nil, nil, 1) + GameTooltip:Show() +end + +local OnEnter = function(self) + if(not self:IsVisible()) then return end + + GameTooltip_SetDefaultAnchor(GameTooltip, self) + self:UpdateTooltip() +end + +local OnLeave = function() + GameTooltip:Hide() +end + +local UpdatePower = function(self, event, unit, powerType) + if(self.unit ~= unit or powerType ~= 'ALTERNATE') then return end + + local altpowerbar = self.AltPowerBar + + --[[ :PreUpdate() + + Called before the element has been updated. + + Arguments + + self - The AltPowerBar element. + ]] + if(altpowerbar.PreUpdate) then + altpowerbar:PreUpdate() + end + + local _, r, g, b + if(altpowerbar.colorTexture) then + _, r, g, b = UnitAlternatePowerTextureInfo(unit, 2) + end + + local cur = UnitPower(unit, ALTERNATE_POWER_INDEX) + local max = UnitPowerMax(unit, ALTERNATE_POWER_INDEX) + + local barType, min, _, _, _, _, _, _, _, _, powerName, powerTooltip = UnitAlternatePowerInfo(unit) + altpowerbar.barType = barType + altpowerbar.powerName = powerName + altpowerbar.powerTooltip = powerTooltip + altpowerbar:SetMinMaxValues(min, max) + altpowerbar:SetValue(math.min(math.max(cur, min), max)) + + if(b) then + altpowerbar:SetStatusBarColor(r, g, b) + end + + --[[ :PostUpdate(min, cur, max) + + Called after the element has been updated. + + Arguments + + self - The AltPowerBar element. + min - The minimum possible power value for the active type. + cur - The current power value. + max - The maximum possible power value for the active type. + ]] + if(altpowerbar.PostUpdate) then + return altpowerbar:PostUpdate(min, cur, max) + end +end + + +--[[ Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] +local Path = function(self, ...) + return (self.AltPowerBar.Override or UpdatePower)(self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit, 'ALTERNATE') +end + +local Toggler = function(self, event, unit) + if(unit ~= self.unit) then return end + local altpowerbar = self.AltPowerBar + + local barType, _, _, _, _, hideFromOthers, showOnRaid = UnitAlternatePowerInfo(unit) + if(barType and (showOnRaid and (UnitInParty(unit) or UnitInRaid(unit)) or not hideFromOthers or unit == 'player' or self.realUnit == 'player')) then + self:RegisterEvent('UNIT_POWER', Path) + self:RegisterEvent('UNIT_MAXPOWER', Path) + + ForceUpdate(altpowerbar) + altpowerbar:Show() + else + self:UnregisterEvent('UNIT_POWER', Path) + self:UnregisterEvent('UNIT_MAXPOWER', Path) + + altpowerbar:Hide() + end +end + +local Enable = function(self, unit) + local altpowerbar = self.AltPowerBar + if(altpowerbar) then + altpowerbar.__owner = self + altpowerbar.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_POWER_BAR_SHOW', Toggler) + self:RegisterEvent('UNIT_POWER_BAR_HIDE', Toggler) + + altpowerbar:Hide() + + if(altpowerbar:IsMouseEnabled()) then + if(not altpowerbar:GetScript('OnEnter')) then + altpowerbar:SetScript('OnEnter', OnEnter) + end + + if(not altpowerbar:GetScript('OnLeave')) then + altpowerbar:SetScript('OnLeave', OnLeave) + end + + if(not altpowerbar.UpdateTooltip) then + altpowerbar.UpdateTooltip = UpdateTooltip + end + end + + if(unit == 'player') then + PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_SHOW' + PlayerPowerBarAlt:UnregisterEvent'UNIT_POWER_BAR_HIDE' + PlayerPowerBarAlt:UnregisterEvent'PLAYER_ENTERING_WORLD' + end + + return true + end +end + +local Disable = function(self, unit) + local altpowerbar = self.AltPowerBar + if(altpowerbar) then + altpowerbar:Hide() + self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Toggler) + self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Toggler) + + if(unit == 'player') then + PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_SHOW' + PlayerPowerBarAlt:RegisterEvent'UNIT_POWER_BAR_HIDE' + PlayerPowerBarAlt:RegisterEvent'PLAYER_ENTERING_WORLD' + end + end +end + +oUF:AddElement('AltPowerBar', Toggler, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/assistant.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/assistant.lua new file mode 100644 index 0000000..be6df47 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/assistant.lua @@ -0,0 +1,111 @@ +--[[ Element: Assistant Icon + Toggles visibility of `self.Assistant` based on the units raid officer status. + + Widget + + Assistant - Any UI widget. + + Notes + + The default assistant icon will be applied if the UI widget is a texture and + doesn't have a texture or color defined. + + Examples + + -- Position and size + local Assistant = self:CreateTexture(nil, "OVERLAY") + Assistant:SetSize(16, 16) + Assistant:SetPoint('TOP', self) + + -- Register it with oUF + self.Assistant = Assistant + + Hooks and Callbacks + +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local assistant = self.Assistant + + --[[ :PreUpdate() + + Called before the element has been updated. + + Arguments + + self - The Assistant element. + ]] + if(assistant.PreUpdate) then + assistant:PreUpdate() + end + + local unit = self.unit + local isAssistant = UnitInRaid(unit) and UnitIsGroupAssistant(unit) and not UnitIsGroupLeader(unit) + if(isAssistant) then + assistant:Show() + else + assistant:Hide() + end + + --[[ :PostUpdate(isAssistant) + + Called after the element has been updated. + + Arguments + + self - The Assistant element. + isAssistant - A boolean holding whether the unit is a raid officer or not. + ]] + if(assistant.PostUpdate) then + return assistant:PostUpdate(isAssistant) + end +end + +local Path = function(self, ...) + --[[ :Override(self, event, ...) + + Used to completely override the internal update function. Removing the + table key entry will make the element fall-back to its internal function + again. + + Arguments + + self - The Assistant element. + event - The UI event that fired. + ... - A vararg with the arguments that accompany the event. + ]] + return (self.Assistant.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local assistant = self.Assistant + if(assistant) then + self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) + + if(assistant:IsObjectType"Texture" and not assistant:GetTexture()) then + assistant:SetTexture[[Interface\GroupFrame\UI-Group-AssistantIcon]] + end + + assistant.__owner = self + assistant.ForceUpdate = ForceUpdate + + return true + end +end + +local Disable = function(self) + local assistant = self.Assistant + if(assistant) then + self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) + assistant:Hide() + end +end + +oUF:AddElement('Assistant', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/aura.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/aura.lua new file mode 100644 index 0000000..ab1d271 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/aura.lua @@ -0,0 +1,854 @@ +--[[ MODIFIED FOR SVUI BY SVUILUNCH ]]-- + +--GLOBAL NAMESPACE +local _G = _G; +--LUA +local unpack = _G.unpack; +local select = _G.select; +local assert = _G.assert; +local type = _G.type; +--STRING +local string = _G.string; +local format = string.format; +--MATH +local math = math; +local floor = math.floor +local ceil = math.ceil +local hugeMath = math.huge; +local min = math.min; +local random = math.random; +--TABLE +local table = _G.table; +local tsort = table.sort; +local tinsert = _G.tinsert; +--BLIZZARD API +local GetTime = _G.GetTime; +local CreateFrame = _G.CreateFrame; +local UnitAura = _G.UnitAura; +local UnitIsFriend = _G.UnitIsFriend; +local GameTooltip = _G.GameTooltip; +local GetSpellInfo = _G.GetSpellInfo; +local DebuffTypeColor = _G.DebuffTypeColor; +local NumberFontNormal = _G.NumberFontNormal; + +local _, ns = ... +local oUF = oUF or ns.oUF +assert(oUF, 'oUF_Auras was unable to locate oUF install.') + +local DAY, HOUR, MINUTE = 86400, 3600, 60; +local BUFF_FILTER = 'HELPFUL'; +local DEBUFF_FILTER = 'HARMFUL'; +local VISIBLE = 1; +local HIDDEN = 0; + +local DEMO_SPELLS = {47540, 974, 111264, 57934, 124081} + +local function FormatTime(seconds) + if seconds < MINUTE then + return ("%.1f"):format(seconds) + elseif seconds < HOUR then + return ("%d:%d"):format(seconds/60%60, seconds%60) + elseif seconds < DAY then + return ("%dh %dm"):format(seconds/(60*60), seconds/60%60) + else + return ("%dd %dh"):format(seconds/DAY, (seconds / HOUR) - (floor(seconds/DAY) * 24)) + end +end + +local SORTING_METHODS = { + ["TIME_REMAINING"] = function(a, b) + local compA = a.noTime and hugeMath or a.expirationTime + local compB = b.noTime and hugeMath or b.expirationTime + return compA > compB + end, + ["TIME_REMAINING_REVERSE"] = function(a, b) + local compA = a.noTime and hugeMath or a.expirationTime + local compB = b.noTime and hugeMath or b.expirationTime + return compA < compB + end, + ["TIME_DURATION"] = function(a, b) + local compA = a.noTime and hugeMath or a.duration + local compB = b.noTime and hugeMath or b.duration + return compA > compB + end, + ["TIME_DURATION_REVERSE"] = function(a, b) + local compA = a.noTime and hugeMath or a.duration + local compB = b.noTime and hugeMath or b.duration + return compA < compB + end, + ["NAME"] = function(a, b) + return a.name > b.name + end, +} + +local SetSorting = function(self, sorting) + if(sorting) then + if((type(sorting) == "string") and SORTING_METHODS[sorting]) then + self.sort = SORTING_METHODS[sorting]; + else + self.sort = SORTING_METHODS["TIME_REMAINING"]; + end + else + self.sort = nil; + end +end + +local Aura_OnEnter = function(self) + if(not self:IsVisible()) then return end + GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT") + GameTooltip:SetUnitAura(self.unit, self.index, self.filter) +end + +local Aura_OnLeave = function() + GameTooltip:Hide() +end + +local AuraBars_OnUpdate = function(self) + local timeNow = GetTime() + for index = 1, #self do + local frame = self[index] + local bar = frame.statusBar + if not frame:IsVisible() then + break + end + if frame.noTime then + bar.spelltime:SetText() + bar.spark:Hide() + else + local timeleft = frame.expirationTime - timeNow + bar:SetValue(timeleft) + bar.spelltime:SetText(FormatTime(timeleft)) + if self.spark == true then + bar.spark:Show() + end + end + end +end + +local AuraIcon_OnUpdate = function(self, elapsed) + self.expiration = self.expiration - elapsed; + + if(self.nextUpdate > 0) then + self.nextUpdate = self.nextUpdate - elapsed; + return; + end + + if(self.expiration <= 0) then + self:SetScript("OnUpdate", nil) + self.text:SetText('') + return; + end + + local expires = self.expiration; + local calc, timeLeft = 0, 0; + if expires < 4 then + self.nextUpdate = 0.051 + self.text:SetFormattedText("|cffff0000%.1f|r", expires) + elseif expires < 60 then + self.nextUpdate = 0.51 + self.text:SetFormattedText("|cffffff00%d|r", floor(expires)) + elseif expires < 3600 then + timeLeft = ceil(expires / 60); + calc = floor((expires / 60) + .5); + self.nextUpdate = calc > 1 and ((expires - calc) * 29.5) or (expires - 59.5); + self.text:SetFormattedText("|cffffffff%dm|r", timeLeft) + elseif expires < 86400 then + timeLeft = ceil(expires / 3600); + calc = floor((expires / 3600) + .5); + self.nextUpdate = calc > 1 and ((expires - calc) * 1799.5) or (expires - 3570); + self.text:SetFormattedText("|cff66ffff%dh|r", timeLeft) + else + timeLeft = ceil(expires / 86400); + calc = floor((expires / 86400) + .5); + self.nextUpdate = calc > 1 and ((expires - calc) * 43199.5) or (expires - 85680); + if(timeLeft > 7) then + self.text:SetFormattedText("|cff6666ff%s|r", "long") + else + self.text:SetFormattedText("|cff6666ff%dd|r", timeLeft) + end + end +end + +local SetBarLayout = function(self, visible, cache) + local auras = self.Bars; + + local width = self.barWidth or self:GetParent():GetWidth(); + local height = self.barHeight or 16; + local growDown = self.down or false; + local spacing = self.spacing or 0; + local gap = self.gap; + local size = self.auraSize + spacing; + + if(visible > 0) then + local newHeight = 1 + (size * visible); + self:SetSize(width, newHeight) + else + self:SetSize(width, 1) + end + + for i = visible + 1, #auras do + auras[i]:Hide() + end + + local lastBar; + if(cache) then + for i = 1, #cache do + local info = cache[i] + local bar = auras[info.ref] + if(bar and bar:IsShown()) then + bar:SetHeight(height) + bar:SetWidth(width) + bar.iconHolder:SetWidth(height) + bar:ClearAllPoints() + if(growDown) then + if(not lastBar) then + bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) + else + bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing) + end + else + if(not lastBar) then + bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0) + else + bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing) + end + end + lastBar = bar + end + end + else + for index = 1, #auras do + local bar = auras[index] + if(bar and bar:IsShown()) then + bar:SetHeight(height) + bar:SetWidth(width) + bar.iconHolder:SetWidth(height) + bar:ClearAllPoints() + if(growDown) then + if(not lastBar) then + bar:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) + else + bar:SetPoint('TOPLEFT', lastBar, 'BOTTOMLEFT', 0, -spacing) + end + else + if(not lastBar) then + bar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 0, 0) + else + bar:SetPoint('BOTTOMLEFT', lastBar, 'TOPLEFT', 0, spacing) + end + end + lastBar = bar + end + end + end +end + +local SetIconLayout = function(self, visible, cache) + local auras = self.Icons + + local col = 0 + local row = 0 + local gap = self.gap + local size = self.auraSize + self.spacing + local anchor = self.initialAnchor or "BOTTOMLEFT" + local growthx = (self["growth-x"] == "LEFT" and -1) or 1 + local growthy = (self["growth-y"] == "DOWN" and -1) or 1 + local cols = self.maxColumns + local rows = self.maxRows + + for i = visible + 1, #auras do + auras[i]:Hide() + end + + if(cache) then + for i = 1, #cache do + local info = cache[i] + local button = auras[info.ref] + if(button and button:IsShown()) then + if(gap and button.debuff) then + if(col > 0) then + col = col + 1 + end + gap = false + end + + if(col >= cols) then + col = 0 + row = row + 1 + end + button:ClearAllPoints() + button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy) + button:SetWidth(self.auraSize) + button:SetHeight(self.auraSize) + col = col + 1 + elseif(not button) then + break + end + end + else + for i = 1, #auras do + local button = auras[i] + if(button and button:IsShown()) then + if(gap and button.debuff) then + if(col > 0) then + col = col + 1 + end + gap = false + end + + if(col >= cols) then + col = 0 + row = row + 1 + end + button:ClearAllPoints() + button:SetPoint(anchor, self, anchor, col * size * growthx, row * size * growthy) + button:SetWidth(self.auraSize) + button:SetHeight(self.auraSize) + col = col + 1 + elseif(not button) then + break + end + end + end + + local newWidth, newHeight; + if(visible > 0) then + local visibleRows = ceil(visible / cols); + newHeight = 1 + (size * visibleRows); + if(visibleRows <= 1) then + newWidth = 1 + (size * col) + else + newWidth = 1 + (size * cols) + end + else + newWidth = 1 + (size * cols) + newHeight = 1 + end + self:SetSize(newWidth, newHeight) +end + +--[[ ICON SPECIFIC ]]-- + +local CreateAuraIcon = function(self, index) + local button = CreateFrame("Button", nil, self) + button:EnableMouse(true) + button:RegisterForClicks'RightButtonUp' + + button:SetWidth(self.auraSize or 16) + button:SetHeight(self.auraSize or 16) + + local cd = CreateFrame("Cooldown", nil, button, "CooldownFrameTemplate") + cd:SetAllPoints(button) + + local icon = button:CreateTexture(nil, "BORDER") + icon:SetAllPoints(button) + + local count = button:CreateFontString(nil, "OVERLAY") + count:SetFontObject(NumberFontNormal) + count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 0) + + local overlay = button:CreateTexture(nil, "OVERLAY") + overlay:SetTexture"Interface\\Buttons\\UI-Debuff-Overlays" + overlay:SetAllPoints(button) + overlay:SetTexCoord(.296875, .5703125, 0, .515625) + button.overlay = overlay + + local stealable = button:CreateTexture(nil, 'OVERLAY') + stealable:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-Stealable]] + stealable:SetPoint('TOPLEFT', -3, 3) + stealable:SetPoint('BOTTOMRIGHT', 3, -3) + stealable:SetBlendMode'ADD' + button.stealable = stealable + + button:SetScript("OnEnter", Aura_OnEnter) + button:SetScript("OnLeave", Aura_OnLeave) + + button.icon = icon + button.count = count + button.cooldown = cd + + if(self.PostCreateIcon) then self:PostCreateIcon(button) end + + return button +end + +--[[ BAR SPECIFIC ]]-- + +local CreateAuraBar = function(self, index) + local frame = CreateFrame("Button", nil, self) + + frame:SetScript('OnEnter', Aura_OnEnter) + frame:SetScript('OnLeave', Aura_OnLeave) + + local iconHolder = CreateFrame('Frame', nil, frame) + iconHolder:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0) + iconHolder:SetPoint('BOTTOMLEFT', frame, 'BOTTOMLEFT', 0, 0) + iconHolder:SetWidth(frame:GetHeight()) + iconHolder:SetBackdrop({ + bgFile = [[Interface\BUTTONS\WHITE8X8]], + edgeFile = [[Interface\BUTTONS\WHITE8X8]], + tile = false, + tileSize = 0, + edgeSize = 1, + insets = + { + left = 0, + right = 0, + top = 0, + bottom = 0, + }, + }) + iconHolder:SetBackdropColor(0,0,0,0.5) + iconHolder:SetBackdropBorderColor(0,0,0) + frame.iconHolder = iconHolder + + frame.icon = frame.iconHolder:CreateTexture(nil, 'BORDER') + frame.icon:SetTexCoord(.1, .9, .1, .9) + frame.icon:SetPoint("TOPLEFT", frame.iconHolder, "TOPLEFT", 1, -1) + frame.icon:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 1) + + frame.count = frame.iconHolder:CreateFontString(nil, "OVERLAY") + frame.count:SetFontObject(NumberFontNormal) + frame.count:SetPoint("BOTTOMRIGHT", frame.iconHolder, "BOTTOMRIGHT", -1, 0) + + local barHolder = CreateFrame('Frame', nil, frame) + barHolder:SetPoint('BOTTOMLEFT', frame.iconHolder, 'BOTTOMRIGHT', self.gap, 0) + barHolder:SetPoint('TOPRIGHT', frame, 'TOPRIGHT', 0, 0) + barHolder:SetBackdrop({ + bgFile = [[Interface\BUTTONS\WHITE8X8]], + edgeFile = [[Interface\BUTTONS\WHITE8X8]], + tile = false, + tileSize = 0, + edgeSize = 1, + insets = + { + left = 0, + right = 0, + top = 0, + bottom = 0, + }, + }) + barHolder:SetBackdropColor(0,0,0,0.5) + barHolder:SetBackdropBorderColor(0,0,0) + frame.barHolder = barHolder + + -- the main bar + frame.statusBar = CreateFrame("StatusBar", nil, frame.barHolder) + frame.statusBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + frame.statusBar:SetAlpha(self.fgalpha or 1) + frame.statusBar:SetPoint("TOPLEFT", frame.barHolder, "TOPLEFT", 1, -1) + frame.statusBar:SetPoint("BOTTOMRIGHT", frame.barHolder, "BOTTOMRIGHT", -1, 1) + + local spark = frame.statusBar:CreateTexture(nil, "OVERLAY", nil); + spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]]); + spark:SetWidth(12); + spark:SetBlendMode("ADD"); + spark:SetPoint('CENTER', frame.statusBar:GetStatusBarTexture(), 'RIGHT') + frame.statusBar.spark = spark + + frame.statusBar.spelltime = frame.statusBar:CreateFontString(nil, 'ARTWORK') + frame.statusBar.spellname = frame.statusBar:CreateFontString(nil, 'ARTWORK') + + --print("New Bar #" .. index) + + if self.PostCreateBar then + self.PostCreateBar(frame) + else + frame.statusBar.spelltime:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE") + frame.statusBar.spelltime:SetTextColor(1 ,1, 1) + frame.statusBar.spelltime:SetShadowOffset(1, -1) + frame.statusBar.spelltime:SetShadowColor(0, 0, 0) + frame.statusBar.spelltime:SetJustifyH'RIGHT' + frame.statusBar.spelltime:SetJustifyV'CENTER' + frame.statusBar.spelltime:SetPoint'RIGHT' + frame.statusBar.spellname:SetFont([[Fonts\FRIZQT__.TTF]], 10, "NONE") + frame.statusBar.spellname:SetTextColor(1, 1, 1) + frame.statusBar.spellname:SetShadowOffset(1, -1) + frame.statusBar.spellname:SetShadowColor(0, 0, 0) + frame.statusBar.spellname:SetJustifyH'LEFT' + frame.statusBar.spellname:SetJustifyV'CENTER' + frame.statusBar.spellname:SetPoint'LEFT' + frame.statusBar.spellname:SetPoint('RIGHT', frame.statusBar.spelltime, 'LEFT') + end + return frame +end + +local UpdateIconAuras = function(self, cache, unit, index, filter, visible, isEnemy) + if not unit then return; end + + local isDebuff = filter == DEBUFF_FILTER + local timeNow = GetTime() + local auras = self.Icons; + + local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff; + + if(self.forceShow) then + spellID = DEMO_SPELLS[random(1, #DEMO_SPELLS)]; + name, rank, texture = GetSpellInfo(spellID) + count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil + else + name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter); + end + + if(name) then + local show = true + local isPlayer = false; + if((not caster) or (caster == "player" or caster == "vehicle")) then isPlayer = true end; + if(self.CustomFilter and (not self.forceShow)) then + show = self:CustomFilter(isEnemy, isPlayer, name, spellID, debuffType, duration, shouldConsolidate) + end + + if(show) then + local i = visible + 1 + local this = auras[i] + if(not this) then + this = (self.CreateAuraIcon or CreateAuraIcon) (self, i) + auras[i] = this + end + + duration = duration or 0; + timeLeft = timeLeft or 0; + count = count or 0; + local noTime = (duration == 0 and timeLeft == 0) + --FOR TOOLTIPS + this.unit = unit + this.index = index + this.filter = filter + --FOR ONCLICK EVENTS + this.name = name + this.spellID = spellID + --FOR ONUPDATE EVENTS + this.expirationTime = timeLeft + this.noTime = noTime + + this.icon:SetTexture(texture) + this.count:SetText((count > 1 and count)) + + this:Show() + + --SORTING CACHE + local cached = { + ref = i, + noTime = noTime, + duration = duration, + expirationTime = timeLeft + } + tinsert(cache, cached) + + local cd = this.cooldown + if(cd and not self.disableCooldown) then + if(noTime) then + cd:Hide() + else + cd:SetCooldown(timeLeft - duration, duration) + cd:Show() + end + end + + if(isDebuff) then + local color = DebuffTypeColor[debuffType] or DebuffTypeColor.none + if((isEnemy) and (not isPlayer)) then + this:SetBackdropBorderColor(0.9, 0.1, 0.1, 1) + this.bg:SetBackdropColor(1, 0, 0, 1) + this.icon:SetDesaturated((unit and not unit:find('arena%d')) and true or false) + else + this:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6, 1) + this.bg:SetBackdropColor(color.r, color.g, color.b, 1) + this.icon:SetDesaturated(false) + end + + this.bg:SetBackdropBorderColor(0, 0, 0, 1) + + if(self.showType and this.overlay) then + this.overlay:SetVertexColor(color.r, color.g, color.b) + this.overlay:Show() + else + this.overlay:Hide() + end + else + if((isStealable) and (isEnemy)) then + this:SetBackdropBorderColor(0.92, 0.91, 0.55, 1) + this.bg:SetBackdropColor(1, 1, 0.5, 1) + this.bg:SetBackdropBorderColor(0, 0, 0, 1) + else + this:SetBackdropBorderColor(0, 0, 0, 1) + this.bg:SetBackdropColor(0, 0, 0, 0) + this.bg:SetBackdropBorderColor(0, 0, 0, 0) + end + end + + if(noTime) then + this:SetScript('OnUpdate', nil) + this.text:SetText('') + else + this.expirationTime = timeLeft + this.expiration = timeLeft - timeNow + this.nextUpdate = -1 + if(not this:GetScript('OnUpdate')) then + this:SetScript('OnUpdate', AuraIcon_OnUpdate) + end + end + + return VISIBLE + else + return HIDDEN + end + end +end + +local UpdateBarAuras = function(self, cache, unit, index, filter, visible, isEnemy) + if not unit then return; end + local isDebuff = filter == DEBUFF_FILTER + local timeNow = GetTime() + local auras = self.Bars; + + local name, rank, texture, count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, spellID, canApplyAura, isBossDebuff = UnitAura(unit, index, filter); + + if(self.forceShow) then + spellID = DEMO_SPELLS[random(1, #DEMO_SPELLS)]; + name, rank, texture = GetSpellInfo(spellID) + count, debuffType, duration, timeLeft, caster, isStealable, shouldConsolidate, canApplyAura, isBossDebuff = 5, 'Magic', 0, 60, 'player', nil, nil, nil, nil + end + + if(name) then + local show = true + local isPlayer = false; + if((not caster) or (caster == "player" or caster == "vehicle")) then isPlayer = true end; + if((not self.forceShow) and self.CustomFilter) then + show = self:CustomFilter(isEnemy, isPlayer, name, spellID, debuffType, duration, shouldConsolidate) + end + + if(show) then + local i = visible + 1 + local this = auras[i] + if(not this) then + this = (self.CreateAuraBar or CreateAuraBar) (self, i) + auras[i] = this + end + + duration = duration or 0; + timeLeft = timeLeft or 0; + count = count or 0; + local noTime = (duration == 0 and timeLeft == 0) + --FOR TOOLTIPS + this.unit = unit + this.index = index + this.filter = filter + --FOR ONCLICK EVENTS + this.name = name + this.spellID = spellID + --FOR ONUPDATE EVENTS + this.expirationTime = timeLeft + this.noTime = noTime + + this.icon:SetTexture(texture) + this.count:SetText((count > 1 and count)) + + this:Show() + + --SORTING CACHE + local cached = { + ref = i, + noTime = noTime, + duration = duration, + expirationTime = timeLeft + } + tinsert(cache, cached) + + local bar = this.statusBar + if(noTime) then + bar:SetMinMaxValues(0, 1) + bar:SetValue(1) + bar.spelltime:SetText('') + else + local value = timeLeft - timeNow + bar:SetMinMaxValues(0, duration) + bar:SetValue(value) + bar.spelltime:SetText(value) + end + bar.spellname:SetText(count > 1 and format("%s [%d]", name, count) or name) + + if self.PostBarUpdate then + self:PostBarUpdate(bar, spellID, isDebuff, debuffType) + elseif(isDebuff) then + bar:SetStatusBarColor(.9, 0, 0) + else + bar:SetStatusBarColor(.2, .6, 1) + end + + return VISIBLE + else + return HIDDEN + end + end +end + +local ParseIconAuras = function(self, unit) + local limit = self.maxCount or 0; + local filter = self.filtering; + local index = 1; + local visible = 0; + local cache = {}; + local isEnemy = UnitIsEnemy('player', unit); + + while(visible < limit) do + if(self.forceShow and visible > 8) then break end + local result = UpdateIconAuras(self, cache, unit, index, filter, visible, isEnemy) + if(not result) then + break + elseif(result == VISIBLE) then + visible = visible + 1 + end + + index = index + 1 + end + + if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then + tsort(cache, self.sort) + SetIconLayout(self, visible, cache) + else + SetIconLayout(self, visible) + end +end + +local ParseBarAuras = function(self, unit) + local limit = self.maxCount or 0; + local filter = self.filtering; + local index = 1; + local visible = 0; + local cache = {}; + local isEnemy = UnitIsEnemy('player', unit); + + while(visible < limit) do + if(self.forceShow and visible > 8) then break end + local result = UpdateBarAuras(self, cache, unit, index, filter, visible, isEnemy) + if(not result) then + break + elseif(result == VISIBLE) then + visible = visible + 1 + end + + index = index + 1 + end + + if(self.sort and type(self.sort) == 'function' and (#cache > 0)) then + tsort(cache, self.sort) + SetBarLayout(self, visible, cache) + else + SetBarLayout(self, visible) + end +end + +--[[ SETUP AND ENABLE/DISABLE ]]-- + +local Update = function(self, event, unit) + if((not unit) or (self.unit ~= unit)) then return end + + local buffs = self.Buffs + if(buffs) then + --if(self.unit == 'player') then print(event)print(buffs.UseBars) end + if(buffs.UseBars and (buffs.UseBars == true)) then + --if(self.unit == 'player') then print('Parsing BUFF BARS') end + ParseBarAuras(buffs, unit) + else + --if(self.unit == 'player') then print('Parsing BUFF ICONS') end + ParseIconAuras(buffs, unit) + end + end + + local debuffs = self.Debuffs + if(debuffs) then + --if(self.unit == 'player') then print(event)print(debuffs.UseBars) end + if(debuffs.UseBars and (debuffs.UseBars == true)) then + --if(self.unit == 'player') then print('Parsing DEBUFF BARS') end + ParseBarAuras(debuffs, unit) + else + --if(self.unit == 'player') then print('Parsing DEBUFF ICONS') end + ParseIconAuras(debuffs, unit) + end + end +end + +local ForceUpdate = function(element) + return Update(element.__owner, 'ForceUpdate', element.unit) +end + +local Enable = function(self) + if(self.Buffs or self.Debuffs) then + self:RegisterEvent('UNIT_AURA', Update) + + local barsAvailable = self.AuraBarsAvailable; + + local buffs = self.Buffs + if(buffs) then + buffs.__owner = self; + buffs.gap = buffs.gap or 2; + buffs.spacing = buffs.spacing or 2; + buffs.auraSize = buffs.auraSize or 16; + buffs.maxRows = buffs.maxRows or 2; + buffs.maxColumns = buffs.maxColumns or 8; + buffs.maxCount = buffs.maxCount or 16; + buffs.filtering = BUFF_FILTER; + buffs.ForceUpdate = ForceUpdate; + buffs.SetSorting = SetSorting; + + buffs:SetHeight(1) + + buffs.Icons = buffs.Icons or CreateFrame("Frame", nil, buffs) + buffs.Icons:SetAllPoints(buffs) + + if(barsAvailable) then + buffs.spark = true; + buffs.UseBars = false; + buffs.barHeight = buffs.barHeight or 16 + buffs.Bars = buffs.Bars or CreateFrame("Frame", nil, buffs) + buffs.Bars:SetAllPoints(buffs) + buffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate) + end + end + + local debuffs = self.Debuffs + if(debuffs) then + debuffs.__owner = self; + debuffs.gap = debuffs.gap or 2; + debuffs.spacing = debuffs.spacing or 2; + debuffs.auraSize = debuffs.auraSize or 16; + debuffs.maxRows = debuffs.maxRows or 2; + debuffs.maxColumns = debuffs.maxColumns or 8; + debuffs.maxCount = debuffs.maxCount or 16; + debuffs.filtering = DEBUFF_FILTER; + debuffs.ForceUpdate = ForceUpdate; + debuffs.SetSorting = SetSorting; + + debuffs:SetHeight(1) + + debuffs.Icons = debuffs.Icons or CreateFrame("Frame", nil, debuffs) + debuffs.Icons:SetAllPoints(debuffs) + + if(barsAvailable) then + debuffs.spark = true; + debuffs.UseBars = false; + debuffs.barHeight = debuffs.barHeight or 16 + debuffs.Bars = debuffs.Bars or CreateFrame("Frame", nil, debuffs) + debuffs.Bars:SetAllPoints(debuffs) + debuffs.Bars:SetScript('OnUpdate', AuraBars_OnUpdate) + end + end + + return true + end +end + +local Disable = function(self) + if(self.Buffs or self.Debuffs) then + self:UnregisterEvent('UNIT_AURA', Update) + if(self.Buffs and self.Buffs.Bars) then + self.Buffs.Bars:SetScript('OnUpdate', nil) + end + if(self.Debuffs and self.Debuffs.Bars) then + self.Debuffs.Bars:SetScript('OnUpdate', nil) + end + end +end + +oUF:AddElement('Auras', Update, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/castbar.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/castbar.lua new file mode 100644 index 0000000..6772dcd --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/castbar.lua @@ -0,0 +1,518 @@ +--[[ Element: Cast Bar + + THIS FILE HEAVILY MODIFIED FOR USE WITH SUPERVILLAIN UI + +]] +--GLOBAL NAMESPACE +local _G = _G; +--LUA +local unpack = _G.unpack; +local select = _G.select; +local assert = _G.assert; +local error = _G.error; +local print = _G.print; +local pairs = _G.pairs; +local next = _G.next; +local tostring = _G.tostring; +local setmetatable = _G.setmetatable; +--STRING +local string = _G.string; +local format = string.format; +--MATH +local math = _G.math; +local floor = math.floor +local ceil = math.ceil +--BLIZZARD API +local GetTime = _G.GetTime; +local CreateFrame = _G.CreateFrame; +local GetNetStats = _G.GetNetStats; +local UnitCastingInfo = _G.UnitCastingInfo; +local UnitChannelInfo = _G.UnitChannelInfo; +--local GetTradeskillRepeatCount = _G.GetTradeskillRepeatCount; +local CastingBarFrame = _G.CastingBarFrame; +local PetCastingBarFrame = _G.PetCastingBarFrame; + +local parent, ns = ... +local oUF = ns.oUF + +local updateSafeZone = function(self) + local sz = self.SafeZone + local width = self:GetWidth() + local _, _, _, ms = GetNetStats() + + -- Guard against GetNetStats returning latencies of 0. + if(ms ~= 0) then + -- MADNESS! + local safeZonePercent = (width / self.max) * (ms / 1e5) + if(safeZonePercent > 1) then safeZonePercent = 1 end + sz:SetWidth(width * safeZonePercent) + sz:Show() + else + sz:Hide() + end +end + +local UNIT_SPELLCAST_SENT = function (self, event, unit, spell, rank, target) + local castbar = self.Castbar + castbar.curTarget = (target and target ~= "") and target or nil +end + +local UNIT_SPELLCAST_START = function(self, event, unit, spell) + if(self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + local name, _, text, texture, startTime, endTime, tradeskill, castid, interrupt = UnitCastingInfo(unit) + if(not name) then + castbar:Hide() + return + end + + endTime = endTime / 1e3 + startTime = startTime / 1e3 + + local repeatCount = 1 + local start = GetTime() - startTime + + if(tradeskill and repeatCount >= 1) then + if(castbar.previous ~= name) then + castbar.recipecount = 1 + castbar.maxrecipe = repeatCount + castbar.duration = start + else + castbar.recipecount = castbar.recipecount or 1 + castbar.maxrecipe = castbar.maxrecipe or repeatCount + castbar.duration = castbar.duration or start + end + else + castbar.recipecount = nil + castbar.maxrecipe = 1 + castbar.duration = start + end + + castbar.previous = name + castbar.tradeskill = tradeskill + castbar.castid = castid + + local max = (endTime - startTime) * castbar.maxrecipe + + castbar.max = max + castbar.delay = 0 + castbar.casting = true + castbar.interrupt = interrupt + + castbar:SetMinMaxValues(0, max) + castbar:SetValue(0) + + if(castbar.Text) then castbar.Text:SetText(text) end + if(castbar.Icon) then castbar.Icon:SetTexture(texture) end + if(castbar.Time) then castbar.Time:SetText() end + + local shield = castbar.Shield + if(shield and interrupt) then + shield:Show() + elseif(shield) then + shield:Hide() + end + + local sf = castbar.SafeZone + if(sf) then + sf:ClearAllPoints() + sf:SetPoint'RIGHT' + sf:SetPoint'TOP' + sf:SetPoint'BOTTOM' + updateSafeZone(castbar) + end + + if(castbar.PostCastStart) then + castbar:PostCastStart(unit, name, castid) + end + + castbar:Show() +end + +local UNIT_SPELLCAST_FAILED = function(self, event, unit, spellname, _, castid) + if (self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + if (castbar.castid ~= castid) then return end + + castbar.previous = nil + castbar.casting = nil + castbar.tradeskill = nil + castbar.recipecount = nil + castbar.maxrecipe = 1 + castbar.interrupt = nil + castbar:SetValue(0) + castbar:Hide() + + if(castbar.PostCastFailed) then + return castbar:PostCastFailed(unit, spellname, castid) + end +end + +local UNIT_SPELLCAST_INTERRUPTED = function(self, event, unit, spellname, _, castid) + if(self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + if (castbar.castid ~= castid) then return end + + castbar.previous = nil + castbar.casting = nil + castbar.tradeskill = nil + castbar.recipecount = nil + castbar.maxrecipe = 1 + castbar.channeling = nil + + castbar:SetValue(0) + castbar:Hide() + + if(castbar.PostCastInterrupted) then + return castbar:PostCastInterrupted(unit, spellname, castid) + end +end + +local UNIT_SPELLCAST_INTERRUPTIBLE = function(self, event, unit) + if(self.unit ~= unit) or not unit then return end + + local shield = self.Castbar.Shield + if(shield) then + shield:Hide() + end + + local castbar = self.Castbar + if(castbar.PostCastInterruptible) then + return castbar:PostCastInterruptible(unit) + end +end + +local UNIT_SPELLCAST_NOT_INTERRUPTIBLE = function(self, event, unit) + if(self.unit ~= unit) or not unit then return end + + local shield = self.Castbar.Shield + if(shield) then + shield:Show() + end + + local castbar = self.Castbar + if(castbar.PostCastNotInterruptible) then + return castbar:PostCastNotInterruptible(unit) + end +end + +local UNIT_SPELLCAST_DELAYED = function(self, event, unit, spellname, _, castid) + if(self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + local name, _, text, texture, startTime, endTime = UnitCastingInfo(unit) + if(not startTime or not castbar:IsShown()) then return end + + local duration = GetTime() - (startTime / 1000) + if(duration < 0) then duration = 0 end + castbar.previous = name + castbar.delay = castbar.delay + castbar.duration - duration + castbar.duration = duration + + castbar:SetValue(duration) + + if(castbar.PostCastDelayed) then + return castbar:PostCastDelayed(unit, name, castid) + end +end + +local UNIT_SPELLCAST_STOP = function(self, event, unit, spellname, _, castid) + if (self.unit ~= unit) or not unit then return end + local castbar = self.Castbar + if (castbar.castid ~= castid) then return end + + if(castbar.tradeskill and castbar.recipecount and castbar.recipecount >= 0) then + castbar.recipecount = castbar.recipecount + 1 + else + castbar.previous = nil + castbar.casting = nil + castbar.interrupt = nil + castbar.tradeskill = nil + castbar.recipecount = nil + castbar.maxrecipe = 1 + castbar:SetValue(0) + end + + if((not castbar.recipecount) or (castbar.recipecount and castbar.recipecount < 2)) then + castbar:Hide() + end + + if(castbar.PostCastStop) then + return castbar:PostCastStop(unit, spellname, castid) + end +end + +local UNIT_SPELLCAST_CHANNEL_START = function(self, event, unit, spellname) + if (self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + local name, _, text, texture, startTime, endTime, isTrade, interrupt = UnitChannelInfo(unit) + if (not name) then return end + + endTime = endTime / 1e3 + startTime = startTime / 1e3 + local max = (endTime - startTime) + local duration = endTime - GetTime() + + castbar.previous = name + castbar.duration = duration + castbar.max = max + castbar.delay = 0 + castbar.startTime = startTime + castbar.endTime = endTime + castbar.extraTickRatio = 0 + castbar.channeling = true + castbar.interrupt = interrupt + + -- We have to do this, as it's possible for spell casts to never have _STOP + -- executed or be fully completed by the OnUpdate handler before CHANNEL_START + -- is called. + castbar.casting = nil + castbar.tradeskill = nil + castbar.recipecount = nil + castbar.maxrecipe = 1 + castbar.castid = nil + + castbar:SetMinMaxValues(0, max) + castbar:SetValue(duration) + + if(castbar.Text) then castbar.Text:SetText(name) end + if(castbar.Icon) then castbar.Icon:SetTexture(texture) end + if(castbar.Time) then castbar.Time:SetText() end + + local shield = castbar.Shield + if(shield and interrupt) then + shield:Show() + elseif(shield) then + shield:Hide() + end + + local sf = castbar.SafeZone + if(sf) then + sf:ClearAllPoints() + sf:SetPoint'LEFT' + sf:SetPoint'TOP' + sf:SetPoint'BOTTOM' + updateSafeZone(castbar) + end + + if(castbar.PostChannelStart) then castbar:PostChannelStart(unit, name) end + castbar:Show() +end + +local UNIT_SPELLCAST_CHANNEL_UPDATE = function(self, event, unit, spellname) + if(self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + local name, _, text, texture, startTime, endTime, oldStart = UnitChannelInfo(unit) + if(not name or not castbar:IsShown()) then + return + end + + castbar.previous = name + local duration = (endTime / 1000) - GetTime() + local startDelay = castbar.startTime - startTime / 1000 + castbar.startTime = startTime / 1000 + castbar.endTime = endTime / 1000 + castbar.delay = castbar.delay + startDelay + + castbar.duration = duration + castbar.max = (endTime - startTime) / 1000 + + castbar:SetMinMaxValues(0, castbar.max) + castbar:SetValue(duration) + + if(castbar.PostChannelUpdate) then + return castbar:PostChannelUpdate(unit, name) + end +end + +local UNIT_SPELLCAST_CHANNEL_STOP = function(self, event, unit, spellname) + if(self.unit ~= unit) or not unit then return end + + local castbar = self.Castbar + if(castbar:IsShown()) then + castbar.channeling = nil + castbar.interrupt = nil + + castbar:SetValue(castbar.max) + castbar:Hide() + + if(castbar.PostChannelStop) then + return castbar:PostChannelStop(unit, spellname) + end + end +end + +local UpdateCastingTimeInfo = function(self, duration) + if(self.Time) then + if(self.delay ~= 0) then + if(self.CustomDelayText) then + self:CustomDelayText(duration) + else + self.Time:SetFormattedText("%.1f|cffff0000-%.1f|r", duration, self.delay) + end + elseif(self.recipecount and self.recipecount > 0 and self.maxrecipe and self.maxrecipe > 1) then + self.Time:SetText(self.recipecount .. "/" .. self.maxrecipe) + else + if(self.CustomTimeText) then + self:CustomTimeText(duration) + else + self.Time:SetFormattedText("%.1f", duration) + end + end + end + if(self.Spark) then + self.Spark:SetPoint("CENTER", self, "LEFT", (duration / self.max) * self:GetWidth(), 0) + end +end + +local onUpdate = function(self, elapsed) + self.lastUpdate = (self.lastUpdate or 0) + elapsed + + if not (self.casting or self.channeling) then + self.unitName = nil + self.previous = nil + self.casting = nil + self.tradeskill = nil + self.recipecount = nil + self.maxrecipe = 1 + self.castid = nil + self.channeling = nil + + self:SetValue(1) + self:Hide() + return + end + + if(self.casting) then + local duration = self.duration + self.lastUpdate + if(duration >= self.max) then + self.previous = nil + self.casting = nil + self.tradeskill = nil + self.recipecount = nil + self.maxrecipe = 1 + self:Hide() + + if(self.PostCastStop) then self:PostCastStop(self.__owner.unit) end + return + end + + UpdateCastingTimeInfo(self, duration) + + self.duration = duration + self:SetValue(duration) + elseif(self.channeling) then + local duration = self.duration - self.lastUpdate + + if(duration <= 0) then + self.channeling = nil + self:Hide() + + if(self.PostChannelStop) then self:PostChannelStop(self.__owner.unit) end + return + end + + UpdateCastingTimeInfo(self, duration) + + self.duration = duration + self:SetValue(duration) + end + + self.lastUpdate = 0 +end + +local Update = function(self, ...) + UNIT_SPELLCAST_START(self, ...) + return UNIT_SPELLCAST_CHANNEL_START(self, ...) +end + +local ForceUpdate = function(element) + return Update(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(object, unit) + local castbar = object.Castbar + + if(castbar) then + castbar.__owner = object + castbar.ForceUpdate = ForceUpdate + + if(not (unit and unit:match'%wtarget$')) then + object:RegisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT) + object:RegisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START) + object:RegisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED) + object:RegisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP) + object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED) + object:RegisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE) + object:RegisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE) + object:RegisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED) + object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START) + object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE) + object:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP) + --object:RegisterEvent("UPDATE_TRADESKILL_RECAST", UPDATE_TRADESKILL_RECAST) + end + + castbar:SetScript("OnUpdate", castbar.OnUpdate or onUpdate) + + if(object.unit == "player") then + CastingBarFrame:UnregisterAllEvents() + CastingBarFrame.Show = CastingBarFrame.Hide + CastingBarFrame:Hide() + elseif(object.unit == 'pet') then + PetCastingBarFrame:UnregisterAllEvents() + PetCastingBarFrame.Show = PetCastingBarFrame.Hide + PetCastingBarFrame:Hide() + end + + if(castbar:IsObjectType'StatusBar' and not castbar:GetStatusBarTexture()) then + castbar:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + end + + local spark = castbar.Spark + if(spark and spark:IsObjectType'Texture' and not spark:GetTexture()) then + spark:SetTexture[[Interface\CastingBar\UI-CastingBar-Spark]] + end + + local shield = castbar.Shield + if(shield and shield:IsObjectType'Texture' and not shield:GetTexture()) then + shield:SetTexture[[Interface\CastingBar\UI-CastingBar-Small-Shield]] + end + + local sz = castbar.SafeZone + if(sz and sz:IsObjectType'Texture' and not sz:GetTexture()) then + sz:SetColorTexture(1, 0, 0) + end + + castbar:Hide() + + return true + end +end + +local Disable = function(object, unit) + local castbar = object.Castbar + + if(castbar) then + object:UnregisterEvent("UNIT_SPELLCAST_SENT", UNIT_SPELLCAST_SENT) + object:UnregisterEvent("UNIT_SPELLCAST_START", UNIT_SPELLCAST_START) + object:UnregisterEvent("UNIT_SPELLCAST_FAILED", UNIT_SPELLCAST_FAILED) + object:UnregisterEvent("UNIT_SPELLCAST_STOP", UNIT_SPELLCAST_STOP) + object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED", UNIT_SPELLCAST_INTERRUPTED) + object:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTIBLE", UNIT_SPELLCAST_INTERRUPTIBLE) + object:UnregisterEvent("UNIT_SPELLCAST_NOT_INTERRUPTIBLE", UNIT_SPELLCAST_NOT_INTERRUPTIBLE) + object:UnregisterEvent("UNIT_SPELLCAST_DELAYED", UNIT_SPELLCAST_DELAYED) + object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START", UNIT_SPELLCAST_CHANNEL_START) + object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", UNIT_SPELLCAST_CHANNEL_UPDATE) + object:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", UNIT_SPELLCAST_CHANNEL_STOP) + --object:UnregisterEvent("UPDATE_TRADESKILL_RECAST", UPDATE_TRADESKILL_RECAST) + + castbar:SetScript("OnUpdate", nil) + end +end + +oUF:AddElement('Castbar', Update, Enable, Disable) \ No newline at end of file diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/classicons.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/classicons.lua new file mode 100644 index 0000000..7f142d4 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/classicons.lua @@ -0,0 +1,279 @@ +--[[ Element: Class Icons + + Toggles the visibility of icons depending on the player's class and + specialization. + + Widget + + ClassIcons - An array consisting of as many UI Textures as the theoretical + maximum return of `UnitPowerMax`. + + Notes + + All - Combo Points + Mage - Arcane Charges + Monk - Chi Orbs + Paladin - Holy Power + Warlock - Soul Shards + + Examples + + local ClassIcons = {} + for index = 1, 6 do + local Icon = self:CreateTexture(nil, 'BACKGROUND') + + -- Position and size. + Icon:SetSize(16, 16) + Icon:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Icon:GetWidth(), 0) + + ClassIcons[index] = Icon + end + + -- Register with oUF + self.ClassIcons = ClassIcons + + Hooks + + OverrideVisibility(self) - Used to completely override the internal visibility + function. Removing the table key entry will make + the element fall-back to its internal function + again. + Override(self) - Used to completely override the internal update + function. Removing the table key entry will make the + element fall-back to its internal function again. + UpdateTexture(element) - Used to completely override the internal function + for updating the power icon textures. Removing the + table key entry will make the element fall-back to + its internal function again. + +]] + +local parent, ns = ... +local oUF = ns.oUF + +local _, PlayerClass = UnitClass'player' + +-- Holds the class specific stuff. +local ClassPowerID, ClassPowerType +local ClassPowerEnable, ClassPowerDisable +local RequireSpec, RequireSpell + +local UpdateTexture = function(element) + local color = oUF.colors.power[ClassPowerType or 'COMBO_POINTS'] + for i = 1, #element do + local icon = element[i] + if(icon.SetDesaturated) then + icon:SetDesaturated(PlayerClass ~= 'PRIEST') + end + + icon:SetVertexColor(color[1], color[2], color[3]) + end +end + +local Update = function(self, event, unit, powerType) + if(not (unit == 'player' and powerType == ClassPowerType) + and not (unit == 'vehicle' and powerType == 'COMBO_POINTS')) then + return + end + + local element = self.ClassIcons + + --[[ :PreUpdate() + + Called before the element has been updated + + Arguments + + self - The ClassIcons element + event - The event, that the update is being triggered for + ]] + if(element.PreUpdate) then + element:PreUpdate(event) + end + + local cur, max, oldMax + if(event ~= 'ClassPowerDisable') then + if(unit == 'vehicle') then + -- XXX: UnitPower is bugged for vehicles, always returns 0 combo points + cur = GetComboPoints('vehicle', 'target') + max = MAX_COMBO_POINTS + else + cur = UnitPower('player', ClassPowerID) + max = UnitPowerMax('player', ClassPowerID) + end + + for i = 1, max do + if(i <= cur) then + element[i]:Show() + else + element[i]:Hide() + end + end + + oldMax = element.__max + if(max ~= oldMax) then + if(max < oldMax) then + for i = max + 1, oldMax do + element[i]:Hide() + end + end + + element.__max = max + end + end + --[[ :PostUpdate(cur, max, hasMaxChanged, event) + + Called after the element has been updated + + Arguments + + self - The ClassIcons element + cur - The current amount of power + max - The maximum amount of power + hasMaxChanged - Shows if the maximum amount has changed since the last + update + powerType - The type of power used + event - The event, which the update happened for + ]] + if(element.PostUpdate) then + return element:PostUpdate(cur, max, oldMax ~= max, powerType, event) + end +end + +local Path = function(self, ...) + return (self.ClassIcons.Override or Update) (self, ...) +end + +local function Visibility(self, event, unit) + local element = self.ClassIcons + local shouldEnable + + if(UnitHasVehicleUI('player')) then + shouldEnable = true + elseif(ClassPowerID) then + if(not RequireSpec or RequireSpec == GetSpecialization()) then + if(not RequireSpell or IsPlayerSpell(RequireSpell)) then + self:UnregisterEvent('SPELLS_CHANGED', Visibility) + shouldEnable = true + else + self:RegisterEvent('SPELLS_CHANGED', Visibility, true) + end + end + end + + local isEnabled = element.isEnabled + if(shouldEnable and not isEnabled) then + ClassPowerEnable(self) + elseif(not shouldEnable and (isEnabled or isEnabled == nil)) then + ClassPowerDisable(self) + elseif(shouldEnable and isEnabled) then + Path(self, event, unit, unit == 'vehicle' and 'COMBO_POINTS' or ClassPowerType) + end +end + +local VisibilityPath = function(self, ...) + return (self.ClassIcons.OverrideVisibility or Visibility) (self, ...) +end + +local ForceUpdate = function(element) + return VisibilityPath(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +do + ClassPowerEnable = function(self) + self:RegisterEvent('UNIT_DISPLAYPOWER', Path) + self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + self:RegisterEvent('UNIT_MAXPOWER', Path) + + if(UnitHasVehicleUI('player')) then + Path(self, 'ClassPowerEnable', 'vehicle', 'COMBO_POINTS') + else + Path(self, 'ClassPowerEnable', 'player', ClassPowerType) + end + self.ClassIcons.isEnabled = true + end + + ClassPowerDisable = function(self) + self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) + self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + self:UnregisterEvent('UNIT_MAXPOWER', Path) + + local element = self.ClassIcons + for i = 1, #element do + element[i]:Hide() + end + + Path(self, 'ClassPowerDisable', 'player', ClassPowerType) + self.ClassIcons.isEnabled = false + end + + if(PlayerClass == 'MONK') then + ClassPowerID = SPELL_POWER_CHI + ClassPowerType = "CHI" + RequireSpec = SPEC_MONK_WINDWALKER + elseif(PlayerClass == 'PALADIN') then + ClassPowerID = SPELL_POWER_HOLY_POWER + ClassPowerType = "HOLY_POWER" + RequireSpec = SPEC_PALADIN_RETRIBUTION + elseif(PlayerClass == 'WARLOCK') then + ClassPowerID = SPELL_POWER_SOUL_SHARDS + ClassPowerType = "SOUL_SHARDS" + elseif(PlayerClass == 'ROGUE' or PlayerClass == 'DRUID') then + ClassPowerID = SPELL_POWER_COMBO_POINTS + ClassPowerType = 'COMBO_POINTS' + + if(PlayerClass == 'DRUID') then + RequireSpell = 5221 -- Shred + end + elseif(PlayerClass == 'MAGE') then + ClassPowerID = SPELL_POWER_ARCANE_CHARGES + ClassPowerType = 'ARCANE_CHARGES' + RequireSpec = SPEC_MAGE_ARCANE + end +end + +local Enable = function(self, unit) + if(unit ~= 'player') then return end + + local element = self.ClassIcons + if(not element) then return end + + element.__owner = self + element.__max = #element + element.ForceUpdate = ForceUpdate + + if(RequireSpec or RequireSpell) then + self:RegisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath, true) + end + + element.ClassPowerEnable = ClassPowerEnable + element.ClassPowerDisable = ClassPowerDisable + + local isChildrenTextures + for i = 1, #element do + local icon = element[i] + if(icon:IsObjectType'Texture') then + if(not icon:GetTexture()) then + icon:SetTexCoord(0.45703125, 0.60546875, 0.44531250, 0.73437500) + icon:SetTexture([[Interface\PlayerFrame\Priest-ShadowUI]]) + end + + isChildrenTextures = true + end + end + + if(isChildrenTextures) then + (element.UpdateTexture or UpdateTexture) (element) + end + + return true +end + +local Disable = function(self) + local element = self.ClassIcons + if(not element) then return end + + ClassPowerDisable(self) +end + +oUF:AddElement('ClassIcons', VisibilityPath, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/combat.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/combat.lua new file mode 100644 index 0000000..06e5708 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/combat.lua @@ -0,0 +1,86 @@ +--[[ Element: Combat Icon + Toggles the visibility of `self.Combat` based on the player's combat status. + + Widget + + Combat - Any UI widget. + + Notes + + The default assistant icon will be applied if the UI widget is a texture and + doesn't have a texture or color defined. + + Examples + + -- Position and size + local Combat = self:CreateTexture(nil, "OVERLAY") + Combat:SetSize(16, 16) + Combat:SetPoint('TOP', self) + + -- Register it with oUF + self.Combat = Combat + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. + +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local combat = self.Combat + if(combat.PreUpdate) then + combat:PreUpdate() + end + + local inCombat = UnitAffectingCombat('player') + if(inCombat) then + combat:Show() + else + combat:Hide() + end + + if(combat.PostUpdate) then + return combat:PostUpdate(inCombat) + end +end + +local Path = function(self, ...) + return (self.Combat.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self, unit) + local combat = self.Combat + if(combat and unit == 'player') then + combat.__owner = self + combat.ForceUpdate = ForceUpdate + + self:RegisterEvent("PLAYER_REGEN_DISABLED", Path, true) + self:RegisterEvent("PLAYER_REGEN_ENABLED", Path, true) + + if(combat:IsObjectType"Texture" and not combat:GetTexture()) then + combat:SetTexture[[Interface\CharacterFrame\UI-StateIcon]] + combat:SetTexCoord(.5, 1, 0, .49) + end + + return true + end +end + +local Disable = function(self) + if(self.Combat) then + self.Combat:Hide() + self:UnregisterEvent("PLAYER_REGEN_DISABLED", Path) + self:UnregisterEvent("PLAYER_REGEN_ENABLED", Path) + end +end + +oUF:AddElement('Combat', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/cpoints.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/cpoints.lua new file mode 100644 index 0000000..6a6dc1c --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/cpoints.lua @@ -0,0 +1,110 @@ +--[[ Element: Combo Point Icons + Toggles visibility of the player and vehicles combo points. + + Widget + + CPoints - An array consisting of five UI widgets. + + Notes + + The default combo point texture will be applied to textures within the CPoints + array that don't have a texture or color defined. + + Examples + + local CPoints = {} + for index = 1, MAX_COMBO_POINTS do + local CPoint = self:CreateTexture(nil, 'BACKGROUND') + + -- Position and size of the combo point. + CPoint:SetSize(12, 16) + CPoint:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * CPoint:GetWidth(), 0) + + CPoints[index] = CPoint + end + + -- Register with oUF + self.CPoints = CPoints + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local GetComboPoints = GetComboPoints +local MAX_COMBO_POINTS = MAX_COMBO_POINTS + +local Update = function(self, event, unit) + if(unit == 'pet') then return end + + local cpoints = self.CPoints + if(cpoints.PreUpdate) then + cpoints:PreUpdate() + end + + local cp + if(UnitHasVehicleUI'player') then + cp = GetComboPoints('vehicle', 'target') + else + cp = GetComboPoints('player', 'target') + end + + for i=1, MAX_COMBO_POINTS do + if(i <= cp) then + cpoints[i]:Show() + else + cpoints[i]:Hide() + end + end + + if(cpoints.PostUpdate) then + return cpoints:PostUpdate(cp) + end +end + +local Path = function(self, ...) + return (self.CPoints.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self) + local cpoints = self.CPoints + if(cpoints) then + cpoints.__owner = self + cpoints.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + self:RegisterEvent('PLAYER_TARGET_CHANGED', Path, true) + + for index = 1, MAX_COMBO_POINTS do + local cpoint = cpoints[index] + if(cpoint:IsObjectType'Texture' and not cpoint:GetTexture()) then + cpoint:SetTexture[[Interface\ComboFrame\ComboPoint]] + cpoint:SetTexCoord(0, 0.375, 0, 1) + end + end + + return true + end +end + +local Disable = function(self) + local cpoints = self.CPoints + if(cpoints) then + for index = 1, MAX_COMBO_POINTS do + cpoints[index]:Hide() + end + self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + self:UnregisterEvent('PLAYER_TARGET_CHANGED', Path) + end +end + +oUF:AddElement('CPoints', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/druidmana.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/druidmana.lua new file mode 100644 index 0000000..78ed3ff --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/druidmana.lua @@ -0,0 +1,194 @@ +--[[ Element: Druid Mana Bar + Handles updating and visibility of a status bar displaying the player's + alternate/additional power, such as Mana for Balance druids. + + Widget + + DruidMana - A StatusBar to represent current caster mana. + + Sub-Widgets + + .bg - A Texture which functions as a background. It will inherit the color of + the main StatusBar. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + Options + + .colorClass - Use `self.colors.class[class]` to color the bar. This will + always use DRUID as class. + .colorSmooth - Use `self.colors.smooth` to color the bar with a smooth + gradient based on the players current mana percentage. + .colorPower - Use `self.colors.power[token]` to color the bar. This will + always use MANA as token. + .displayPairs - Overridable table of pairs used to match class and power to + display or hide the element. + + Sub-Widget Options + + .multiplier - Defines a multiplier, which is used to tint the background based + on the main widgets R, G and B values. Defaults to 1 if not + present. + + Examples + + -- Position and size + local DruidMana = CreateFrame("StatusBar", nil, self) + DruidMana:SetSize(20, 20) + DruidMana:SetPoint('TOP') + DruidMana:SetPoint('LEFT') + DruidMana:SetPoint('RIGHT') + + -- Add a background + local Background = DruidMana:CreateTexture(nil, 'BACKGROUND') + Background:SetAllPoints(DruidMana) + Background:SetTexture(1, 1, 1, .5) + + -- Register it with oUF + self.DruidMana = DruidMana + self.DruidMana.bg = Background + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. + +]] + +local _, ns = ... +local oUF = ns.oUF + +local playerClass = select(2, UnitClass('player')) +local isBetaClient = select(4, GetBuildInfo()) >= 70000 + +local ADDITIONAL_POWER_BAR_NAME = ADDITIONAL_POWER_BAR_NAME +local ADDITIONAL_POWER_BAR_INDEX = ADDITIONAL_POWER_BAR_INDEX + +local function Update(self, event, unit, powertype) + if(unit ~= 'player' or (powertype and powertype ~= ADDITIONAL_POWER_BAR_NAME)) then return end + + local druidmana = self.DruidMana + if(druidmana.PreUpdate) then druidmana:PreUpdate(unit) end + + local cur = UnitPower('player', ADDITIONAL_POWER_BAR_INDEX) + local max = UnitPowerMax('player', ADDITIONAL_POWER_BAR_INDEX) + druidmana:SetMinMaxValues(0, max) + druidmana:SetValue(cur) + + local r, g, b, t + if(druidmana.colorClass) then + t = self.colors.class[playerClass] + elseif(druidmana.colorSmooth) then + r, g, b = self.ColorGradient(cur, max, unpack(druidmana.smoothGradient or self.colors.smooth)) + elseif(druidmana.colorPower) then + t = self.colors.power[ADDITIONAL_POWER_BAR_NAME] + end + + if(t) then + r, g, b = t[1], t[2], t[3] + end + + if(b) then + druidmana:SetStatusBarColor(r, g, b) + + local bg = druidmana.bg + if(bg) then + local mu = bg.multiplier or 1 + bg:SetVertexColor(r * mu, g * mu, b * mu) + end + end + + if(druidmana.PostUpdate) then + return druidmana:PostUpdate(unit, cur, max) + end +end + +local function Path(self, ...) + return (self.DruidMana.Override or Update) (self, ...) +end + +local function ElementEnable(self) + self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + self:RegisterEvent('UNIT_DISPLAYPOWER', Path) + self:RegisterEvent('UNIT_MAXPOWER', Path) + + self.DruidMana:Show() + + Path(self, 'ElementEnable', 'player', ADDITIONAL_POWER_BAR_NAME) +end + +local function ElementDisable(self) + self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) + self:UnregisterEvent('UNIT_MAXPOWER', Path) + + self.DruidMana:Hide() + + Path(self, 'ElementDisable', 'player', ADDITIONAL_POWER_BAR_NAME) +end + +local function Visibility(self, event, unit) + local druidmana = self.DruidMana + local shouldEnable + + if(not UnitHasVehicleUI('player')) then + if(UnitPowerMax(unit, ADDITIONAL_POWER_BAR_INDEX) ~= 0) then + if(isBetaClient) then + if(druidmana.displayPairs[playerClass]) then + local powerType = UnitPowerType(unit) + shouldEnable = druidmana.displayPairs[playerClass][powerType] + end + else + if(playerClass == 'DRUID' and UnitPowerType(unit) == ADDITIONAL_POWER_BAR_INDEX) then + shouldEnable = true + end + end + end + end + + if(shouldEnable) then + ElementEnable(self) + else + ElementDisable(self) + end +end + +local VisibilityPath = function(self, ...) + return (self.DruidMana.OverrideVisibility or Visibility) (self, ...) +end + +local function ForceUpdate(element) + return VisibilityPath(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self, unit) + local druidmana = self.DruidMana + if(druidmana and unit == 'player') then + druidmana.displayPairs = druidmana.displayPairs or ALT_MANA_BAR_PAIR_DISPLAY_INFO + druidmana.__owner = self + druidmana.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) + + if(druidmana:IsObjectType'StatusBar' and not druidmana:GetStatusBarTexture()) then + druidmana:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + end + + return true + end +end + +local Disable = function(self) + local druidmana = self.DruidMana + if(druidmana) then + ElementDisable(self) + + self:UnregisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) + end +end + +oUF:AddElement('DruidMana', VisibilityPath, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/healprediction.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/healprediction.lua new file mode 100644 index 0000000..86cdcc5 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/healprediction.lua @@ -0,0 +1,237 @@ +--[[ Element: Heal Prediction Bar + Handle updating and visibility of the heal prediction status bars. + + Widget + + HealPrediction - A table containing `myBar` and `otherBar`. + + Sub-Widgets + + myBar - A StatusBar used to represent your incoming heals. + otherBar - A StatusBar used to represent other peoples incoming heals. + absorbBar - A StatusBar used to represent total absorbs. + healAbsorbBar - A StatusBar used to represent heal absorbs. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + Options + + .maxOverflow - Defines the maximum amount of overflow past the end of the + health bar. + .frequentUpdates - Update on UNIT_HEALTH_FREQUENT instead of UNIT_HEALTH. Use + this if .frequentUpdates is also set on the Health element. + + Examples + + -- Position and size + local myBar = CreateFrame('StatusBar', nil, self.Health) + myBar:SetPoint('TOP') + myBar:SetPoint('BOTTOM') + myBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') + myBar:SetWidth(200) + + local otherBar = CreateFrame('StatusBar', nil, self.Health) + otherBar:SetPoint('TOP') + otherBar:SetPoint('BOTTOM') + otherBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') + otherBar:SetWidth(200) + + local absorbBar = CreateFrame('StatusBar', nil, self.Health) + absorbBar:SetPoint('TOP') + absorbBar:SetPoint('BOTTOM') + absorbBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') + absorbBar:SetWidth(200) + + local healAbsorbBar = CreateFrame('StatusBar', nil, self.Health) + healAbsorbBar:SetPoint('TOP') + healAbsorbBar:SetPoint('BOTTOM') + healAbsorbBar:SetPoint('LEFT', self.Health:GetStatusBarTexture(), 'RIGHT') + healAbsorbBar:SetWidth(200) + + -- Register with oUF + self.HealPrediction = { + myBar = myBar, + otherBar = otherBar, + absorbBar = absorbBar, + healAbsorbBar = healAbsorbBar, + maxOverflow = 1.05, + frequentUpdates = true, + } + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local _, ns = ... +local oUF = ns.oUF + +local function Update(self, event, unit) + if(self.unit ~= unit) then return end + + local hp = self.HealPrediction + if(hp.PreUpdate) then hp:PreUpdate(unit) end + + local myIncomingHeal = UnitGetIncomingHeals(unit, 'player') or 0 + local allIncomingHeal = UnitGetIncomingHeals(unit) or 0 + local totalAbsorb = UnitGetTotalAbsorbs(unit) or 0 + local myCurrentHealAbsorb = UnitGetTotalHealAbsorbs(unit) or 0 + local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) + + local overHealAbsorb = false + if(health < myCurrentHealAbsorb) then + overHealAbsorb = true + myCurrentHealAbsorb = health + end + + if(health - myCurrentHealAbsorb + allIncomingHeal > maxHealth * hp.maxOverflow) then + allIncomingHeal = maxHealth * hp.maxOverflow - health + myCurrentHealAbsorb + end + + local otherIncomingHeal = 0 + if(allIncomingHeal < myIncomingHeal) then + myIncomingHeal = allIncomingHeal + else + otherIncomingHeal = allIncomingHeal - myIncomingHeal + end + + local overAbsorb = false + if(health - myCurrentHealAbsorb + allIncomingHeal + totalAbsorb >= maxHealth or health + totalAbsorb >= maxHealth) then + if(totalAbsorb > 0) then + overAbsorb = true + end + + if(allIncomingHeal > myCurrentHealAbsorb) then + totalAbsorb = max(0, maxHealth - (health - myCurrentHealAbsorb + allIncomingHeal)) + else + totalAbsorb = max(0, maxHealth - health) + end + end + + if(myCurrentHealAbsorb > allIncomingHeal) then + myCurrentHealAbsorb = myCurrentHealAbsorb - allIncomingHeal + else + myCurrentHealAbsorb = 0 + end + + if(hp.myBar) then + hp.myBar:SetMinMaxValues(0, maxHealth) + hp.myBar:SetValue(myIncomingHeal) + hp.myBar:Show() + end + + if(hp.otherBar) then + hp.otherBar:SetMinMaxValues(0, maxHealth) + hp.otherBar:SetValue(otherIncomingHeal) + hp.otherBar:Show() + end + + if(hp.absorbBar) then + hp.absorbBar:SetMinMaxValues(0, maxHealth) + hp.absorbBar:SetValue(totalAbsorb) + hp.absorbBar:Show() + end + + if(hp.healAbsorbBar) then + hp.healAbsorbBar:SetMinMaxValues(0, maxHealth) + hp.healAbsorbBar:SetValue(myCurrentHealAbsorb) + hp.healAbsorbBar:Show() + end + + if(hp.PostUpdate) then + return hp:PostUpdate(unit, overAbsorb, overHealAbsorb) + end +end + +local function Path(self, ...) + return (self.HealPrediction.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local function Enable(self) + local hp = self.HealPrediction + if(hp) then + hp.__owner = self + hp.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_HEAL_PREDICTION', Path) + self:RegisterEvent('UNIT_MAXHEALTH', Path) + if(hp.frequentUpdates) then + self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path) + else + self:RegisterEvent('UNIT_HEALTH', Path) + end + self:RegisterEvent('UNIT_ABSORB_AMOUNT_CHANGED', Path) + self:RegisterEvent('UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path) + + if(not hp.maxOverflow) then + hp.maxOverflow = 1.05 + end + + if(hp.myBar) then + if(hp.myBar:IsObjectType'StatusBar' and not hp.myBar:GetStatusBarTexture()) then + hp.myBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + hp.myBar:Show() + end + if(hp.otherBar) then + if(hp.otherBar:IsObjectType'StatusBar' and not hp.otherBar:GetStatusBarTexture()) then + hp.otherBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + hp.otherBar:Show() + end + if(hp.absorbBar) then + if(hp.absorbBar:IsObjectType'StatusBar' and not hp.absorbBar:GetStatusBarTexture()) then + hp.absorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + hp.absorbBar:Show() + end + if(hp.healAbsorbBar) then + if(hp.healAbsorbBar:IsObjectType'StatusBar' and not hp.healAbsorbBar:GetStatusBarTexture()) then + hp.healAbsorbBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + hp.healAbsorbBar:Show() + end + + return true + end +end + +local function Disable(self) + local hp = self.HealPrediction + if(hp) then + if(hp.myBar) then + hp.myBar:Hide() + end + if(hp.otherBar) then + hp.otherBar:Hide() + end + if(hp.absorbBar) then + hp.absorbBar:Hide() + end + if(hp.healAbsorbBar) then + hp.healAbsorbBar:Hide() + end + + self:UnregisterEvent('UNIT_HEAL_PREDICTION', Path) + self:UnregisterEvent('UNIT_MAXHEALTH', Path) + self:UnregisterEvent('UNIT_HEALTH', Path) + self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path) + self:UnregisterEvent('UNIT_ABSORB_AMOUNT_CHANGED', Path) + self:UnregisterEvent('UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path) + end +end + +oUF:AddElement('HealPrediction', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/health.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/health.lua new file mode 100644 index 0000000..495a168 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/health.lua @@ -0,0 +1,192 @@ +--[[ Element: Health Bar + + Handles updating of `self.Health` based on the units health. + + Widget + + Health - A StatusBar used to represent current unit health. + + Sub-Widgets + + .bg - A Texture which functions as a background. It will inherit the color of + the main StatusBar. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + Options + + The following options are listed by priority. The first check that returns + true decides the color of the bar. + + .colorTapping - Use `self.colors.tapping` to color the bar if the unit + isn't tapped by the player. + .colorDisconnected - Use `self.colors.disconnected` to color the bar if the + unit is offline. + .colorClass - Use `self.colors.class[class]` to color the bar based on + unit class. `class` is defined by the second return of + [UnitClass](http://wowprogramming.com/docs/api/UnitClass). + .colorClassNPC - Use `self.colors.class[class]` to color the bar if the + unit is a NPC. + .colorClassPet - Use `self.colors.class[class]` to color the bar if the + unit is player controlled, but not a player. + .colorReaction - Use `self.colors.reaction[reaction]` to color the bar + based on the player's reaction towards the unit. + `reaction` is defined by the return value of + [UnitReaction](http://wowprogramming.com/docs/api/UnitReaction). + .colorSmooth - Use `self.colors.smooth` to color the bar with a smooth + gradient based on the player's current health percentage. + .colorHealth - Use `self.colors.health` to color the bar. This flag is + used to reset the bar color back to default if none of the + above conditions are met. + + Sub-Widgets Options + + .multiplier - Defines a multiplier, which is used to tint the background based + on the main widgets R, G and B values. Defaults to 1 if not + present. + + Examples + + -- Position and size + local Health = CreateFrame("StatusBar", nil, self) + Health:SetHeight(20) + Health:SetPoint('TOP') + Health:SetPoint('LEFT') + Health:SetPoint('RIGHT') + + -- Add a background + local Background = Health:CreateTexture(nil, 'BACKGROUND') + Background:SetAllPoints(Health) + Background:SetTexture(1, 1, 1, .5) + + -- Options + Health.frequentUpdates = true + Health.colorTapping = true + Health.colorDisconnected = true + Health.colorClass = true + Health.colorReaction = true + Health.colorHealth = true + + -- Make the background darker. + Background.multiplier = .5 + + -- Register it with oUF + self.Health = Health + self.Health.bg = Background + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] +local parent, ns = ... +local oUF = ns.oUF + +oUF.colors.health = {49/255, 207/255, 37/255} + +local Update = function(self, event, unit) + if(self.unit ~= unit) then return end + local health = self.Health + + if(health.PreUpdate) then health:PreUpdate(unit) end + + local min, max = UnitHealth(unit), UnitHealthMax(unit) + local disconnected = not UnitIsConnected(unit) + health:SetMinMaxValues(0, max) + + if(disconnected) then + health:SetValue(max) + else + health:SetValue(min) + end + + health.disconnected = disconnected + + local r, g, b, t + if(health.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then + t = self.colors.tapped + elseif(health.colorDisconnected and not UnitIsConnected(unit)) then + t = self.colors.disconnected + elseif(health.colorClass and UnitIsPlayer(unit)) or + (health.colorClassNPC and not UnitIsPlayer(unit)) or + (health.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then + local _, class = UnitClass(unit) + t = self.colors.class[class] + elseif(health.colorReaction and UnitReaction(unit, 'player')) then + t = self.colors.reaction[UnitReaction(unit, "player")] + elseif(health.colorSmooth) then + r, g, b = self.ColorGradient(min, max, unpack(health.smoothGradient or self.colors.smooth)) + elseif(health.colorHealth) then + t = self.colors.health + end + + if(t) then + r, g, b = t[1], t[2], t[3] + end + + if(b) then + health:SetStatusBarColor(r, g, b) + + local bg = health.bg + if(bg) then local mu = bg.multiplier or 1 + bg:SetVertexColor(r * mu, g * mu, b * mu) + end + end + + if(health.PostUpdate) then + return health:PostUpdate(unit, min, max) + end +end + +local Path = function(self, ...) + return (self.Health.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self, unit) + local health = self.Health + if(health) then + health.__owner = self + health.ForceUpdate = ForceUpdate + + if(health.frequentUpdates) then + self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path) + else + self:RegisterEvent('UNIT_HEALTH', Path) + end + + self:RegisterEvent("UNIT_MAXHEALTH", Path) + self:RegisterEvent('UNIT_CONNECTION', Path) + + -- For tapping. + self:RegisterEvent('UNIT_FACTION', Path) + + if(health:IsObjectType'StatusBar' and not health:GetStatusBarTexture()) then + health:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + end + + return true + end +end + +local Disable = function(self) + local health = self.Health + if(health) then + health:Hide() + self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path) + self:UnregisterEvent('UNIT_HEALTH', Path) + self:UnregisterEvent('UNIT_MAXHEALTH', Path) + self:UnregisterEvent('UNIT_CONNECTION', Path) + + self:UnregisterEvent('UNIT_FACTION', Path) + end +end + +oUF:AddElement('Health', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/leader.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/leader.lua new file mode 100644 index 0000000..79bdd03 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/leader.lua @@ -0,0 +1,87 @@ +--[[ Element: Leader Icon + + Toggles visibility based on the units leader status. + + Widget + + Leader - Any UI widget. + + Notes + + The default leader icon will be applied if the UI widget is a texture and + doesn't have a texture or color defined. + + Examples + + -- Position and size + local Leader = self:CreateTexture(nil, "OVERLAY") + Leader:SetSize(16, 16) + Leader:SetPoint("BOTTOM", self, "TOP") + + -- Register it with oUF + self.Leader = Leadera + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local leader = self.Leader + if(leader.PreUpdate) then + leader:PreUpdate() + end + + local unit = self.unit + local isLeader = (UnitInParty(unit) or UnitInRaid(unit)) and UnitIsGroupLeader(unit) + if(isLeader) then + leader:Show() + else + leader:Hide() + end + + if(leader.PostUpdate) then + return leader:PostUpdate(isLeader) + end +end + +local Path = function(self, ...) + return (self.Leader.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local leader = self.Leader + if(leader) then + leader.__owner = self + leader.ForceUpdate = ForceUpdate + + self:RegisterEvent("PARTY_LEADER_CHANGED", Path, true) + self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) + + if(leader:IsObjectType"Texture" and not leader:GetTexture()) then + leader:SetTexture[[Interface\GroupFrame\UI-Group-LeaderIcon]] + end + + return true + end +end + +local Disable = function(self) + local leader = self.Leader + if(leader) then + leader:Hide() + self:UnregisterEvent("PARTY_LEADER_CHANGED", Path) + self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) + end +end + +oUF:AddElement('Leader', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/lfdrole.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/lfdrole.lua new file mode 100644 index 0000000..c54683d --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/lfdrole.lua @@ -0,0 +1,94 @@ +--[[ Element: LFD Role Icon + + Toggles visibility of the LFD role icon based upon the units current dungeon + role. + + Widget + + LFDRole - A Texture containing the LFD role icons at specific locations. Look + at the default LFD role icon texture for an example of this. + Alternatively you can look at the return values of + GetTexCoordsForRoleSmallCircle(role). + + Notes + + The default LFD role texture will be applied if the UI widget is a texture and + doesn't have a texture or color defined. + + Examples + + -- Position and size + local LFDRole = self:CreateTexture(nil, "OVERLAY") + LFDRole:SetSize(16, 16) + LFDRole:SetPoint("LEFT", self) + + -- Register it with oUF + self.LFDRole = LFDRole + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local lfdrole = self.LFDRole + if(lfdrole.PreUpdate) then + lfdrole:PreUpdate() + end + + local role = UnitGroupRolesAssigned(self.unit) + if(role == 'TANK' or role == 'HEALER' or role == 'DAMAGER') then + lfdrole:SetTexCoord(GetTexCoordsForRoleSmallCircle(role)) + lfdrole:Show() + else + lfdrole:Hide() + end + + if(lfdrole.PostUpdate) then + return lfdrole:PostUpdate(role) + end +end + +local Path = function(self, ...) + return (self.LFDRole.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local lfdrole = self.LFDRole + if(lfdrole) then + lfdrole.__owner = self + lfdrole.ForceUpdate = ForceUpdate + + if(self.unit == "player") then + self:RegisterEvent("PLAYER_ROLES_ASSIGNED", Path, true) + else + self:RegisterEvent("GROUP_ROSTER_UPDATE", Path, true) + end + + if(lfdrole:IsObjectType"Texture" and not lfdrole:GetTexture()) then + lfdrole:SetTexture[[Interface\LFGFrame\UI-LFG-ICON-PORTRAITROLES]] + end + + return true + end +end + +local Disable = function(self) + local lfdrole = self.LFDRole + if(lfdrole) then + lfdrole:Hide() + self:UnregisterEvent("PLAYER_ROLES_ASSIGNED", Path) + self:UnregisterEvent("GROUP_ROSTER_UPDATE", Path) + end +end + +oUF:AddElement('LFDRole', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/masterlooter.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/masterlooter.lua new file mode 100644 index 0000000..727b28a --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/masterlooter.lua @@ -0,0 +1,106 @@ +--[[ Element: Master Looter Icon + + Toggles visibility of the master looter icon. + + Widget + + MasterLooter - Any UI widget. + + Notes + + The default master looter icon will be applied if the UI widget is a texture + and doesn't have a texture or color defined. + + Examples + + -- Position and size + local MasterLooter = self:CreateTexture(nil, 'OVERLAY') + MasterLooter:SetSize(16, 16) + MasterLooter:SetPoint('TOPRIGHT', self) + + -- Register it with oUF + self.MasterLooter = MasterLooter + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. + +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local unit = self.unit + local masterlooter = self.MasterLooter + if(not (UnitInParty(unit) or UnitInRaid(unit))) then + return masterlooter:Hide() + end + + if(masterlooter.PreUpdate) then + masterlooter:PreUpdate() + end + + local method, pid, rid = GetLootMethod() + if(method == 'master') then + local mlUnit + if(pid) then + if(pid == 0) then + mlUnit = 'player' + else + mlUnit = 'party'..pid + end + elseif(rid) then + mlUnit = 'raid'..rid + end + + if(UnitIsUnit(unit, mlUnit)) then + masterlooter:Show() + elseif(masterlooter:IsShown()) then + masterlooter:Hide() + end + else + masterlooter:Hide() + end + + if(masterlooter.PostUpdate) then + return masterlooter:PostUpdate(masterlooter:IsShown()) + end +end + +local Path = function(self, ...) + return (self.MasterLooter.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local function Enable(self, unit) + local masterlooter = self.MasterLooter + if(masterlooter) then + masterlooter.__owner = self + masterlooter.ForceUpdate = ForceUpdate + + self:RegisterEvent('PARTY_LOOT_METHOD_CHANGED', Path, true) + self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true) + + if(masterlooter:IsObjectType('Texture') and not masterlooter:GetTexture()) then + masterlooter:SetTexture([[Interface\GroupFrame\UI-Group-MasterLooter]]) + end + + return true + end +end + +local function Disable(self) + if(self.MasterLooter) then + self.MasterLooter:Hide() + self:UnregisterEvent('PARTY_LOOT_METHOD_CHANGED', Path) + self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path) + end +end + +oUF:AddElement('MasterLooter', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/picon.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/picon.lua new file mode 100644 index 0000000..3f10e40 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/picon.lua @@ -0,0 +1,85 @@ +--[[ Element: Phasing Icon + + Toggles visibility of the phase icon based on the units phasing compared to the + player. + + Widget + + PhaseIcon - Any UI widget. + + Notes + + The default phasing icon will be used if the UI widget is a texture and doesn't + have a texture or color defined. + + Examples + + -- Position and size + local PhaseIcon = self:CreateTexture(nil, 'OVERLAY') + PhaseIcon:SetSize(16, 16) + PhaseIcon:SetPoint('TOPLEFT', self) + + -- Register it with oUF + self.PhaseIcon = PhaseIcon + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local picon = self.PhaseIcon + if(picon.PreUpdate) then + picon:PreUpdate() + end + + local inPhase = UnitInPhase(self.unit) + if(inPhase) then + picon:Hide() + else + picon:Show() + end + + if(picon.PostUpdate) then + return picon:PostUpdate(inPhase) + end +end + +local Path = function(self, ...) + return (self.PhaseIcon.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local picon = self.PhaseIcon + if(picon) then + picon.__owner = self + picon.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_PHASE', Path, true) + + if(picon:IsObjectType'Texture' and not picon:GetTexture()) then + picon:SetTexture[[Interface\TargetingFrame\UI-PhasingIcon]] + end + + return true + end +end + +local Disable = function(self) + local picon = self.PhaseIcon + if(picon) then + picon:Hide() + self:UnregisterEvent('UNIT_PHASE', Path) + end +end + +oUF:AddElement('PhaseIcon', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/portraits.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/portraits.lua new file mode 100644 index 0000000..01c4d4c --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/portraits.lua @@ -0,0 +1,119 @@ +--[[ Element: Portraits + + Handles updating of the unit's portrait. + + Widget + + Portrait - A PlayerModel or Texture used to represent the unit's portrait. + + Notes + + The quest delivery question mark will be used instead of the unit's model when + the client doesn't have the model information for the unit. + + Examples + + -- 3D Portrait + -- Position and size + local Portrait = CreateFrame('PlayerModel', nil, self) + Portrait:SetSize(32, 32) + Portrait:SetPoint('RIGHT', self, 'LEFT') + + -- Register it with oUF + self.Portrait = Portrait + + -- 2D Portrait + local Portrait = self:CreateTexture(nil, 'OVERLAY') + Portrait:SetSize(32, 32) + Portrait:SetPoint('RIGHT', self, 'LEFT') + + -- Register it with oUF + self.Portrait = Portrait + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event, unit) + if(not unit or not UnitIsUnit(self.unit, unit)) then return end + + local portrait = self.Portrait + if(portrait.PreUpdate) then portrait:PreUpdate(unit) end + + if(portrait:IsObjectType'Model') then + local guid = UnitGUID(unit) + if(not UnitExists(unit) or not UnitIsConnected(unit) or not UnitIsVisible(unit)) then + portrait:SetCamDistanceScale(0.25) + portrait:SetPortraitZoom(0) + portrait:SetPosition(0,0,0.5) + portrait:ClearModel() + portrait:SetModel('interface\\buttons\\talktomequestionmark.m2') + portrait.guid = nil + elseif(portrait.guid ~= guid or event == 'UNIT_MODEL_CHANGED') then + portrait:SetCamDistanceScale(1) + portrait:SetPortraitZoom(1) + portrait:SetPosition(0,0,0) + portrait:ClearModel() + portrait:SetUnit(unit) + portrait.guid = guid + end + else + SetPortraitTexture(portrait, unit) + end + + if(portrait.PostUpdate) then + return portrait:PostUpdate(unit) + end +end + +local Path = function(self, ...) + return (self.Portrait.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self, unit) + local portrait = self.Portrait + if(portrait) then + portrait:Show() + portrait.__owner = self + portrait.ForceUpdate = ForceUpdate + + self:RegisterEvent("UNIT_PORTRAIT_UPDATE", Path) + self:RegisterEvent("UNIT_MODEL_CHANGED", Path) + self:RegisterEvent('UNIT_CONNECTION', Path) + + -- The quest log uses PARTY_MEMBER_{ENABLE,DISABLE} to handle updating of + -- party members overlapping quests. This will probably be enough to handle + -- model updating. + -- + -- DISABLE isn't used as it fires when we most likely don't have the + -- information we want. + if(unit == 'party') then + self:RegisterEvent('PARTY_MEMBER_ENABLE', Path) + end + + return true + end +end + +local Disable = function(self) + local portrait = self.Portrait + if(portrait) then + portrait:Hide() + self:UnregisterEvent("UNIT_PORTRAIT_UPDATE", Path) + self:UnregisterEvent("UNIT_MODEL_CHANGED", Path) + self:UnregisterEvent('PARTY_MEMBER_ENABLE', Path) + self:UnregisterEvent('UNIT_CONNECTION', Path) + end +end + +oUF:AddElement('Portrait', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/power.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/power.lua new file mode 100644 index 0000000..c304d2b --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/power.lua @@ -0,0 +1,271 @@ +--[[ Element: Power Bar + + Handles updating of `self.Power` based upon the units power. + + Widget + + Power - A StatusBar used to represent mana. + + Sub-Widgets + + .bg - A Texture which functions as a background. It will inherit the color of + the main StatusBar. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + Options + + .displayAltPower - Use this to let the widget display alternate power if the + unit has one. If no alternate power the display will fall + back to primary power. + + The following options are listed by priority. The first check that returns + true decides the color of the bar. + + .colorTapping - Use `self.colors.tapping` to color the bar if the unit + isn't tapped by the player. + .colorDisconnected - Use `self.colors.disconnected` to color the bar if the + unit is offline. + .altPowerColor - A table containing the RGB values to use for a fixed + color if the alt power bar is being displayed instead + .colorPower - Use `self.colors.power[token]` to color the bar based on + the unit's power type. This method will fall-back to + `:GetAlternativeColor()` if it can't find a color matching + the token. If this function isn't defined, then it will + attempt to color based upon the alternative power colors + returned by [UnitPowerType](http://wowprogramming.com/docs/api/UnitPowerType). + Finally, if these aren't defined, then it will attempt to + color the bar based upon `self.colors.power[type]`. + .colorClass - Use `self.colors.class[class]` to color the bar based on + unit class. `class` is defined by the second return of + [UnitClass](http://wowprogramming.com/docs/api/UnitClass). + .colorClassNPC - Use `self.colors.class[class]` to color the bar if the + unit is a NPC. + .colorClassPet - Use `self.colors.class[class]` to color the bar if the + unit is player controlled, but not a player. + .colorReaction - Use `self.colors.reaction[reaction]` to color the bar + based on the player's reaction towards the unit. + `reaction` is defined by the return value of + [UnitReaction](http://wowprogramming.com/docs/api/UnitReaction). + .colorSmooth - Use `self.colors.smooth` to color the bar with a smooth + gradient based on the player's current health percentage. + + Sub-Widget Options + + .multiplier - Defines a multiplier, which is used to tint the background based + on the main widgets R, G and B values. Defaults to 1 if not + present. + + Examples + + -- Position and size + local Power = CreateFrame("StatusBar", nil, self) + Power:SetHeight(20) + Power:SetPoint('BOTTOM') + Power:SetPoint('LEFT') + Power:SetPoint('RIGHT') + + -- Add a background + local Background = Power:CreateTexture(nil, 'BACKGROUND') + Background:SetAllPoints(Power) + Background:SetTexture(1, 1, 1, .5) + + -- Options + Power.frequentUpdates = true + Power.colorTapping = true + Power.colorDisconnected = true + Power.colorPower = true + Power.colorClass = true + Power.colorReaction = true + + -- Make the background darker. + Background.multiplier = .5 + + -- Register it with oUF + self.Power = Power + self.Power.bg = Background + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +oUF.colors.power = {} +for power, color in next, PowerBarColor do + if (type(power) == "string") then + if(type(select(2, next(color))) == 'table') then + oUF.colors.power[power] = {} + + for index, color in next, color do + oUF.colors.power[power][index] = {color.r, color.g, color.b} + end + else + oUF.colors.power[power] = {color.r, color.g, color.b} + end + end +end + +-- sourced from FrameXML/Constants.lua +oUF.colors.power[0] = oUF.colors.power.MANA +oUF.colors.power[1] = oUF.colors.power.RAGE +oUF.colors.power[2] = oUF.colors.power.FOCUS +oUF.colors.power[3] = oUF.colors.power.ENERGY +oUF.colors.power[4] = oUF.colors.power.COMBO_POINTS +oUF.colors.power[5] = oUF.colors.power.RUNES +oUF.colors.power[6] = oUF.colors.power.RUNIC_POWER +oUF.colors.power[7] = oUF.colors.power.SOUL_SHARDS +oUF.colors.power[8] = oUF.colors.power.LUNAR_POWER +oUF.colors.power[9] = oUF.colors.power.HOLY_POWER +oUF.colors.power[11] = oUF.colors.power.MAELSTROM +oUF.colors.power[12] = oUF.colors.power.CHI +oUF.colors.power[13] = oUF.colors.power.INSANITY +oUF.colors.power[16] = oUF.colors.power.ARCANE_CHARGES +oUF.colors.power[17] = oUF.colors.power.FURY +oUF.colors.power[18] = oUF.colors.power.PAIN + +local GetDisplayPower = function(unit) + local _, min, _, _, _, _, showOnRaid = UnitAlternatePowerInfo(unit) + if(showOnRaid) then + return ALTERNATE_POWER_INDEX, min + end +end + +local Update = function(self, event, unit) + if(self.unit ~= unit) then return end + local power = self.Power + + if(power.PreUpdate) then power:PreUpdate(unit) end + + local displayType, min + if power.displayAltPower then + displayType, min = GetDisplayPower(unit) + end + local cur, max = UnitPower(unit, displayType), UnitPowerMax(unit, displayType) + local disconnected = not UnitIsConnected(unit) + power:SetMinMaxValues(min or 0, max) + + if(disconnected) then + power:SetValue(max) + else + power:SetValue(cur) + end + + power.disconnected = disconnected + + local r, g, b, t + + if(power.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then + t = self.colors.tapped + elseif(power.colorDisconnected and disconnected) then + t = self.colors.disconnected + elseif(displayType == ALTERNATE_POWER_INDEX and power.altPowerColor) then + t = power.altPowerColor + elseif(power.colorPower) then + local ptype, ptoken, altR, altG, altB = UnitPowerType(unit) + + t = self.colors.power[ptoken] + if(not t) then + if(power.GetAlternativeColor) then + r, g, b = power:GetAlternativeColor(unit, ptype, ptoken, altR, altG, altB) + elseif(altR) then + -- As of 7.0.3, altR, altG, altB may be in 0-1 or 0-255 range. + if(altR > 1) or (altG > 1) or (altB > 1) then + r, g, b = altR / 255, altG / 255, altB / 255 + else + r, g, b = altR, altG, altB + end + else + t = self.colors.power[ptype] + end + end + elseif(power.colorClass and UnitIsPlayer(unit)) or + (power.colorClassNPC and not UnitIsPlayer(unit)) or + (power.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then + local _, class = UnitClass(unit) + t = self.colors.class[class] + elseif(power.colorReaction and UnitReaction(unit, 'player')) then + t = self.colors.reaction[UnitReaction(unit, "player")] + elseif(power.colorSmooth) then + local adjust = 0 - (min or 0) + r, g, b = self.ColorGradient(cur + adjust, max + adjust, unpack(power.smoothGradient or self.colors.smooth)) + end + + if(t) then + r, g, b = t[1], t[2], t[3] + end + + if(b) then + power:SetStatusBarColor(r, g, b) + + local bg = power.bg + if(bg) then + local mu = bg.multiplier or 1 + bg:SetVertexColor(r * mu, g * mu, b * mu) + end + end + + if(power.PostUpdate) then + return power:PostUpdate(unit, cur, max, min) + end +end + +local Path = function(self, ...) + return (self.Power.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self, unit) + local power = self.Power + if(power) then + power.__owner = self + power.ForceUpdate = ForceUpdate + + if(power.frequentUpdates and (unit == 'player' or unit == 'pet')) then + self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + else + self:RegisterEvent('UNIT_POWER', Path) + end + + self:RegisterEvent('UNIT_POWER_BAR_SHOW', Path) + self:RegisterEvent('UNIT_POWER_BAR_HIDE', Path) + self:RegisterEvent('UNIT_DISPLAYPOWER', Path) + self:RegisterEvent('UNIT_CONNECTION', Path) + self:RegisterEvent('UNIT_MAXPOWER', Path) + + -- For tapping. + self:RegisterEvent('UNIT_FACTION', Path) + + if(power:IsObjectType'StatusBar' and not power:GetStatusBarTexture()) then + power:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + end + + return true + end +end + +local Disable = function(self) + local power = self.Power + if(power) then + self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + self:UnregisterEvent('UNIT_POWER', Path) + self:UnregisterEvent('UNIT_POWER_BAR_SHOW', Path) + self:UnregisterEvent('UNIT_POWER_BAR_HIDE', Path) + self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) + self:UnregisterEvent('UNIT_CONNECTION', Path) + self:UnregisterEvent('UNIT_MAXPOWER', Path) + self:UnregisterEvent('UNIT_FACTION', Path) + end +end + +oUF:AddElement('Power', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/powerprediction.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/powerprediction.lua new file mode 100644 index 0000000..cccb5bb --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/powerprediction.lua @@ -0,0 +1,169 @@ +--[[ Element: Power Prediction Bar + Handles updating and visibility of the power prediction status bars. + + Widget + + PowerPrediction - A table containing `mainBar` and `altBar`. + + Sub-Widgets + + mainBar - A StatusBar used to represent power cost of spells, that consume + your main power, e.g. mana for mages; + altBar - A StatusBar used to represent power cost of spells, that consume + your additional power, e.g. mana for balance druids. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture. + + Examples + + -- Position and size + local mainBar = CreateFrame('StatusBar', nil, self.Power) + mainBar:SetReverseFill(true) + mainBar:SetPoint('TOP') + mainBar:SetPoint('BOTTOM') + mainBar:SetPoint('RIGHT', self.Power:GetStatusBarTexture(), 'RIGHT') + mainBar:SetWidth(200) + + local altBar = CreateFrame('StatusBar', nil, self.DruidMana) + altBar:SetReverseFill(true) + altBar:SetPoint('TOP') + altBar:SetPoint('BOTTOM') + altBar:SetPoint('RIGHT', self.DruidMana:GetStatusBarTexture(), 'RIGHT') + altBar:SetWidth(200) + + -- Register with oUF + self.PowerPrediction = { + mainBar = mainBar, + altBar = altBar + } + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local _, ns = ... +local oUF = ns.oUF + +local playerClass = select(2, UnitClass('player')) + +local function Update(self, event, unit) + if(self.unit ~= unit) then return end + + local pp = self.PowerPrediction + + if(pp.PreUpdate) then + pp:PreUpdate(unit) + end + + local _, _, _, _, startTime, endTime, _, _, _, spellID = UnitCastingInfo(unit) + local mainPowerType = UnitPowerType(unit) + local hasAltManaBar = ALT_MANA_BAR_PAIR_DISPLAY_INFO[playerClass] and ALT_MANA_BAR_PAIR_DISPLAY_INFO[playerClass][mainPowerType] + local mainCost, altCost = 0, 0 + + if(event == 'UNIT_SPELLCAST_START' or startTime ~= endTime) then + local costTable = GetSpellPowerCost(spellID) + + for _, costInfo in pairs(costTable) do + --[[costInfo content: + -- name: string (powerToken) + -- type: number (powerType) + -- cost: number + -- costPercent: number + -- costPerSec: number + -- minCost: number + -- hasRequiredAura: boolean + -- requiredAuraID: number + ]] + if(costInfo.type == mainPowerType) then + mainCost = costInfo.cost + + break + elseif(costInfo.type == ADDITIONAL_POWER_BAR_INDEX) then + altCost = costInfo.cost + + break + end + end + end + + if(pp.mainBar) then + pp.mainBar:SetMinMaxValues(0, UnitPowerMax(unit, mainPowerType)) + pp.mainBar:SetValue(mainCost) + pp.mainBar:Show() + end + + if(pp.altBar and hasAltManaBar) then + pp.altBar:SetMinMaxValues(0, UnitPowerMax(unit, ADDITIONAL_POWER_BAR_INDEX)) + pp.altBar:SetValue(altCost) + pp.altBar:Show() + end + + if(pp.PostUpdate) then + return pp:PostUpdate(unit, mainCost, altCost, hasAltManaBar) + end +end + +local function Path(self, ...) + return (self.PowerPrediction.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local function Enable(self) + local pp = self.PowerPrediction + + if(pp) then + pp.__owner = self + pp.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_SPELLCAST_START', Path) + self:RegisterEvent('UNIT_SPELLCAST_STOP', Path) + self:RegisterEvent('UNIT_SPELLCAST_FAILED', Path) + self:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED', Path) + self:RegisterEvent('UNIT_DISPLAYPOWER', Path) + + if(pp.mainBar) then + if(pp.mainBar:IsObjectType('StatusBar') and not pp.mainBar:GetStatusBarTexture()) then + pp.mainBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + if(pp.altBar) then + if(pp.altBar:IsObjectType('StatusBar') and not pp.altBar:GetStatusBarTexture()) then + pp.altBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + return true + end +end + +local function Disable(self) + local pp = self.PowerPrediction + + if(pp) then + if(pp.mainBar) then + pp.mainBar:Hide() + end + + if(pp.altBar) then + pp.altBar:Hide() + end + + self:UnregisterEvent('UNIT_SPELLCAST_START', Path) + self:UnregisterEvent('UNIT_SPELLCAST_STOP', Path) + self:UnregisterEvent('UNIT_SPELLCAST_FAILED', Path) + self:UnregisterEvent('UNIT_SPELLCAST_SUCCEEDED', Path) + self:UnregisterEvent('UNIT_DISPLAYPOWER', Path) + end +end + +oUF:AddElement('PowerPrediction', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/pvp.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/pvp.lua new file mode 100644 index 0000000..013ad07 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/pvp.lua @@ -0,0 +1,160 @@ +--[[ Element: PvP and Prestige Icons + + Handles updating and visibility of PvP and prestige icons based on unit's PvP + status and prestige level. + + Widget + + PvP - A Texture used to display faction, FFA PvP status or prestige icon. + + Sub-Widgets + + Prestige - A Texture used to display prestige background image. + + Notes + + This element updates by changing the texture; + `Prestige` texture has to be on a lower sub-layer than `PvP` texture. + + Examples + + -- Position and size + local PvP = self:CreateTexture(nil, 'ARTWORK', nil, 1) + PvP:SetSize(30, 30) + PvP:SetPoint('RIGHT', self, 'LEFT') + + local Prestige = self:CreateTexture(nil, 'ARTWORK') + Prestige:SetSize(50, 52) + Prestige:SetPoint('CENTER', PvP, 'CENTER') + + -- Register it with oUF + self.PvP = PvP + self.PvP.Prestige = Prestige + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local function Update(self, event, unit) + if(unit ~= self.unit) then return end + + local pvp = self.PvP + + if(pvp.PreUpdate) then + pvp:PreUpdate(unit) + end + + local status + local hasPrestige + local level = UnitPrestige(unit) + local factionGroup = UnitFactionGroup(unit) + + if(UnitIsPVPFreeForAll(unit)) then + if(level > 0 and pvp.Prestige) then + pvp:SetTexture(GetPrestigeInfo(level)) + pvp:SetTexCoord(0, 1, 0, 1) + + pvp.Prestige:SetAtlas('honorsystem-portrait-neutral', false) + + hasPrestige = true + else + pvp:SetTexture('Interface\\TargetingFrame\\UI-PVP-FFA') + pvp:SetTexCoord(0, 0.65625, 0, 0.65625) + end + + status = 'ffa' + elseif(factionGroup and factionGroup ~= 'Neutral' and UnitIsPVP(unit)) then + if(UnitIsMercenary(unit)) then + if(factionGroup == 'Horde') then + factionGroup = 'Alliance' + elseif(factionGroup == 'Alliance') then + factionGroup = 'Horde' + end + end + + if(level > 0 and pvp.Prestige) then + pvp:SetTexture(GetPrestigeInfo(level)) + pvp:SetTexCoord(0, 1, 0, 1) + + pvp.Prestige:SetAtlas('honorsystem-portrait-'..factionGroup, false) + + hasPrestige = true + else + pvp:SetTexture('Interface\\TargetingFrame\\UI-PVP-'..factionGroup) + pvp:SetTexCoord(0, 0.65625, 0, 0.65625) + end + + status = factionGroup + end + + if(status) then + pvp:Show() + + if(pvp.Prestige) then + if(hasPrestige) then + pvp.Prestige:Show() + else + pvp.Prestige:Hide() + end + end + else + pvp:Hide() + + if(pvp.Prestige) then + pvp.Prestige:Hide() + end + end + + if(pvp.PostUpdate) then + return pvp:PostUpdate(unit, status, hasPrestige, level) + end +end + +local function Path(self, ...) + return (self.PvP.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local function Enable(self) + local pvp = self.PvP + + if(pvp) then + pvp.__owner = self + pvp.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_FACTION', Path) + + if(pvp.Prestige) then + self:RegisterEvent('HONOR_PRESTIGE_UPDATE', Path) + end + + return true + end +end + +local function Disable(self) + local pvp = self.PvP + + if(pvp) then + pvp:Hide() + + self:UnregisterEvent('UNIT_FACTION', Path) + + if(pvp.Prestige) then + pvp.Prestige:Hide() + + self:UnregisterEvent('HONOR_PRESTIGE_UPDATE', Path) + end + end +end + +oUF:AddElement('PvP', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/qicon.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/qicon.lua new file mode 100644 index 0000000..068887a --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/qicon.lua @@ -0,0 +1,86 @@ +--[[ Element: Quest Icon + + Handles updating and toggles visibility based upon the units connection to a + quest. + + Widget + + QuestIcon - Any UI widget. + + Notes + + The default quest icon will be used if the UI widget is a texture and doesn't + have a texture or color defined. + + Examples + + -- Position and size + local QuestIcon = self:CreateTexture(nil, 'OVERLAY') + QuestIcon:SetSize(16, 16) + QuestIcon:SetPoint('TOPRIGHT', self) + + -- Register it with oUF + self.QuestIcon = QuestIcon + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event, unit) + if(unit ~= self.unit) then return end + + local qicon = self.QuestIcon + if(qicon.PreUpdate) then + qicon:PreUpdate() + end + + local isQuestBoss = UnitIsQuestBoss(unit) + if(isQuestBoss) then + qicon:Show() + else + qicon:Hide() + end + + if(qicon.PostUpdate) then + return qicon:PostUpdate(isQuestBoss) + end +end + +local Path = function(self, ...) + return (self.QuestIcon.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self) + local qicon = self.QuestIcon + if(qicon) then + qicon.__owner = self + qicon.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_CLASSIFICATION_CHANGED', Path) + + if(qicon:IsObjectType'Texture' and not qicon:GetTexture()) then + qicon:SetTexture[[Interface\TargetingFrame\PortraitQuestBadge]] + end + + return true + end +end + +local Disable = function(self) + if(self.QuestIcon) then + self.QuestIcon:Hide() + self:UnregisterEvent('UNIT_CLASSIFICATION_CHANGED', Path) + end +end + +oUF:AddElement('QuestIcon', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/raidrole.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/raidrole.lua new file mode 100644 index 0000000..86c9048 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/raidrole.lua @@ -0,0 +1,89 @@ +--[[ Element: Raid Role Icon + + Handles visibility and updating of `self.RaidRole` based upon the units + party assignment. + + Widget + + RaidRole - A Texture representing the units party assignment. This is can be + main tank, main assist or blank. + + Notes + + This element updates by changing the texture. + + Examples + + -- Position and size + local RaidRole = self:CreateTexture(nil, 'OVERLAY') + RaidRole:SetSize(16, 16) + RaidRole:SetPoint('TOPLEFT') + + -- Register it with oUF + self.RaidRole = RaidRole + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local unit = self.unit + if(not UnitInRaid(unit)) then return end + + local raidrole = self.RaidRole + if(raidrole.PreUpdate) then + raidrole:PreUpdate() + end + + local inVehicle = UnitHasVehicleUI(unit) + if(GetPartyAssignment('MAINTANK', unit) and not inVehicle) then + raidrole:Show() + raidrole:SetTexture[[Interface\GROUPFRAME\UI-GROUP-MAINTANKICON]] + elseif(GetPartyAssignment('MAINASSIST', unit) and not inVehicle) then + raidrole:Show() + raidrole:SetTexture[[Interface\GROUPFRAME\UI-GROUP-MAINASSISTICON]] + else + raidrole:Hide() + end + + if(raidrole.PostUpdate) then + return raidrole:PostUpdate(rinfo) + end +end + +local Path = function(self, ...) + return (self.RaidRole.Override or Update)(self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local raidrole = self.RaidRole + + if(raidrole) then + raidrole.__owner = self + raidrole.ForceUpdate = ForceUpdate + + self:RegisterEvent('GROUP_ROSTER_UPDATE', Path, true) + + return true + end +end + +local Disable = function(self) + local raidrole = self.RaidRole + + if(raidrole) then + self:UnregisterEvent('GROUP_ROSTER_UPDATE', Path) + end +end + +oUF:AddElement('RaidRole', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/range.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/range.lua new file mode 100644 index 0000000..6f4f7ab --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/range.lua @@ -0,0 +1,115 @@ +--[[ Element: Range Fader + + Widget + + Range - A table containing opacity values. + + Options + + .outsideAlpha - Opacity when the unit is out of range. Values 0 (fully + transparent) - 1 (fully opaque). + .insideAlpha - Opacity when the unit is within range. Values 0 (fully + transparent) - 1 (fully opaque). + + Examples + + -- Register with oUF + self.Range = { + insideAlpha = 1, + outsideAlpha = 1/2, + } + + Hooks + +]] + +local parent, ns = ... +local oUF = ns.oUF + +local _FRAMES = {} +local OnRangeFrame + +local UnitInRange, UnitIsConnected = UnitInRange, UnitIsConnected + +-- updating of range. +local timer = 0 +local OnRangeUpdate = function(self, elapsed) + timer = timer + elapsed + + if(timer >= .20) then + for _, object in next, _FRAMES do + if(object:IsShown()) then + local range = object.Range + if(UnitIsConnected(object.unit)) then + local inRange, checkedRange = UnitInRange(object.unit) + if(checkedRange and not inRange) then + if(range.Override) then + --[[ .Override(self, status) + + A function used to override the calls to :SetAlpha(). + + Arguments + + self - The unit object. + status - The range status of the unit. Either `inside` or + `outside`. + ]] + range.Override(object, 'outside') + else + object:SetAlpha(range.outsideAlpha) + end + else + if(range.Override) then + range.Override(object, 'inside') + elseif(object:GetAlpha() ~= range.insideAlpha) then + object:SetAlpha(range.insideAlpha) + end + end + else + if(range.Override) then + range.Override(object, 'offline') + elseif(object:GetAlpha() ~= range.insideAlpha) then + object:SetAlpha(range.insideAlpha) + end + end + end + end + + timer = 0 + end +end + +local Enable = function(self) + local range = self.Range + if(range and range.insideAlpha and range.outsideAlpha) then + table.insert(_FRAMES, self) + + if(not OnRangeFrame) then + OnRangeFrame = CreateFrame"Frame" + OnRangeFrame:SetScript("OnUpdate", OnRangeUpdate) + end + + OnRangeFrame:Show() + + return true + end +end + +local Disable = function(self) + local range = self.Range + if(range) then + for k, frame in next, _FRAMES do + if(frame == self) then + table.remove(_FRAMES, k) + break + end + end + self:SetAlpha(1) + + if(#_FRAMES == 0) then + OnRangeFrame:Hide() + end + end +end + +oUF:AddElement('Range', nil, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/readycheck.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/readycheck.lua new file mode 100644 index 0000000..140a9d4 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/readycheck.lua @@ -0,0 +1,159 @@ +--[[ Element: Ready Check Icon + + Handles updating and visibility of `self.ReadyCheck` based upon the units + ready check status. + + Widget + + ReadyCheck - A Texture representing ready check status. + + Notes + + This element updates by changing the texture. + + Options + + .finishedTime - The number of seconds the icon should stick after a check has + completed. Defaults to 10 seconds. + .fadeTime - The number of seconds the icon should used to fade away after + the stick duration has completed. Defaults to 1.5 seconds. + .readyTexture - Path to alternate texture for the ready check "ready" status. + .notReadyTexture - Path to alternate texture for the ready check "notready" status. + .waitingTexture - Path to alternate texture for the ready check "waiting" status. + + Examples + + -- Position and size + local ReadyCheck = self:CreateTexture(nil, 'OVERLAY') + ReadyCheck:SetSize(16, 16) + ReadyCheck:SetPoint('TOP') + + -- Register with oUF + self.ReadyCheck = ReadyCheck + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local function OnFinished(self) + local element = self:GetParent() + element:Hide() + + --[[ :PostUpdateFadeOut() + + Called after the element has been faded out. + + Arguments + + self - The ReadyCheck element. + ]] + if(element.PostUpdateFadeOut) then + element:PostUpdateFadeOut() + end +end + +local Update = function(self, event) + local element = self.ReadyCheck + + --[[ :PreUpdate() + + Called before the element has been updated. + + Arguments + + self - The ReadyCheck element. + ]] + if(element.PreUpdate) then + element:PreUpdate() + end + + local unit = self.unit + local status = GetReadyCheckStatus(unit) + if(UnitExists(unit) and status) then + if(status == 'ready') then + element:SetTexture(element.readyTexture or READY_CHECK_READY_TEXTURE) + elseif(status == 'notready') then + element:SetTexture(element.notReadyTexture or READY_CHECK_NOT_READY_TEXTURE) + else + element:SetTexture(element.waitingTexture or READY_CHECK_WAITING_TEXTURE) + end + + element.status = status + element:Show() + elseif(event ~= 'READY_CHECK_FINISHED') then + element.status = nil + element:Hide() + end + + if(event == 'READY_CHECK_FINISHED') then + if(element.status == 'waiting') then + element:SetTexture(element.notReadyTexture or READY_CHECK_NOT_READY_TEXTURE) + end + + element.Animation:Play() + end + + --[[ :PostUpdate(status) + + Called after the element has been updated. + + Arguments + + self - The ReadyCheck element. + status - The units ready check status, if any. + ]] + if(element.PostUpdate) then + return element:PostUpdate(status) + end +end + +local Path = function(self, ...) + return (self.ReadyCheck.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self, unit) + local element = self.ReadyCheck + if(element and (unit and (unit:sub(1, 5) == 'party' or unit:sub(1,4) == 'raid'))) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + local AnimationGroup = element:CreateAnimationGroup() + AnimationGroup:HookScript('OnFinished', OnFinished) + element.Animation = AnimationGroup + + local Animation = AnimationGroup:CreateAnimation('Alpha') + Animation:SetFromAlpha(1) + Animation:SetToAlpha(0) + Animation:SetDuration(element.fadeTime or 1.5) + Animation:SetStartDelay(element.finishedTime or 10) + + self:RegisterEvent('READY_CHECK', Path, true) + self:RegisterEvent('READY_CHECK_CONFIRM', Path, true) + self:RegisterEvent('READY_CHECK_FINISHED', Path, true) + + return true + end +end + +local Disable = function(self) + local element = self.ReadyCheck + if(element) then + element:Hide() + + self:UnregisterEvent('READY_CHECK', Path) + self:UnregisterEvent('READY_CHECK_CONFIRM', Path) + self:UnregisterEvent('READY_CHECK_FINISHED', Path) + end +end + +oUF:AddElement('ReadyCheck', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resting.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resting.lua new file mode 100644 index 0000000..3e2898f --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resting.lua @@ -0,0 +1,85 @@ +--[[ Element: Resting Icon + + Toggles visibility of the resting icon. + + Widget + + Resting - Any UI widget. + + Notes + + The default resting icon will be used if the UI widget is a texture and doesn't + have a texture or color defined. + + Examples + + -- Position and size + local Resting = self:CreateTexture(nil, 'OVERLAY') + Resting:SetSize(16, 16) + Resting:SetPoint('TOPLEFT', self) + + -- Register it with oUF + self.Resting = Resting + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local resting = self.Resting + if(resting.PreUpdate) then + resting:PreUpdate() + end + + local isResting = IsResting() + if(isResting) then + resting:Show() + else + resting:Hide() + end + + if(resting.PostUpdate) then + return resting:PostUpdate(isResting) + end +end + +local Path = function(self, ...) + return (self.Resting.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self, unit) + local resting = self.Resting + if(resting and unit == 'player') then + resting.__owner = self + resting.ForceUpdate = ForceUpdate + + self:RegisterEvent("PLAYER_UPDATE_RESTING", Path, true) + + if(resting:IsObjectType"Texture" and not resting:GetTexture()) then + resting:SetTexture[[Interface\CharacterFrame\UI-StateIcon]] + resting:SetTexCoord(0, .5, 0, .421875) + end + + return true + end +end + +local Disable = function(self) + local resting = self.Resting + if(resting) then + resting:Hide() + self:UnregisterEvent("PLAYER_UPDATE_RESTING", Path) + end +end + +oUF:AddElement('Resting', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resurrect.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resurrect.lua new file mode 100644 index 0000000..3b7e041 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/resurrect.lua @@ -0,0 +1,84 @@ +--[[ Element: Resurrect Icon + + Handles updating and toggles visibility of incoming resurrect icon. + + Widget + + ResurrectIcon - A Texture used to display if the unit has an incoming + resurrect. + + Notes + + The default resurrect icon will be used if the UI widget is a texture and + doesn't have a texture or color defined. + + Examples + + -- Position and size + local ResurrectIcon = self:CreateTexture(nil, 'OVERLAY') + ResurrectIcon:SetSize(16, 16) + ResurrectIcon:SetPoint('TOPRIGHT', self) + + -- Register it with oUF + self.ResurrectIcon = ResurrectIcon + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event) + local resurrect = self.ResurrectIcon + if(resurrect.PreUpdate) then + resurrect:PreUpdate() + end + + local incomingResurrect = UnitHasIncomingResurrection(self.unit) + if(incomingResurrect) then + resurrect:Show() + else + resurrect:Hide() + end + + if(resurrect.PostUpdate) then + return resurrect:PostUpdate(incomingResurrect) + end +end + +local Path = function(self, ...) + return (self.ResurrectIcon.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local resurrect = self.ResurrectIcon + if(resurrect) then + resurrect.__owner = self + resurrect.ForceUpdate = ForceUpdate + + self:RegisterEvent('INCOMING_RESURRECT_CHANGED', Path, true) + + if(resurrect:IsObjectType('Texture') and not resurrect:GetTexture()) then + resurrect:SetTexture[[Interface\RaidFrame\Raid-Icon-Rez]] + end + + return true + end +end + +local Disable = function(self) + local resurrect = self.ResurrectIcon + if(resurrect) then + self:UnregisterEvent('INCOMING_RESURRECT_CHANGED', Path) + end +end + +oUF:AddElement('ResurrectIcon', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/ricons.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/ricons.lua new file mode 100644 index 0000000..9758024 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/ricons.lua @@ -0,0 +1,91 @@ +--[[ Element: Raid Icon + + Handles updating and toggles visibility of raid target icons. + + Widget + + RaidIcon - A Texture used to display the raid target icon. + + Notes + + This element updates by changing the texture. + + The default raid icons will be used if the UI widget is a texture and doesn't + have a texture or color defined. + + Examples + + -- Position and size + local RaidIcon = self:CreateTexture(nil, 'OVERLAY') + RaidIcon:SetSize(16, 16) + RaidIcon:SetPoint('TOPRIGHT', self) + + -- Register it with oUF + self.RaidIcon = RaidIcon + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local GetRaidTargetIndex = GetRaidTargetIndex +local SetRaidTargetIconTexture = SetRaidTargetIconTexture + +local Update = function(self, event) + local icon = self.RaidIcon + if(icon.PreUpdate) then + icon:PreUpdate() + end + + local index = GetRaidTargetIndex(self.unit) + if(index) then + SetRaidTargetIconTexture(icon, index) + icon:Show() + else + icon:Hide() + end + + if(icon.PostUpdate) then + return icon:PostUpdate(index) + end +end + +local Path = function(self, ...) + return (self.RaidIcon.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + if(not element.__owner.unit) then return end + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local ricon = self.RaidIcon + if(ricon) then + ricon.__owner = self + ricon.ForceUpdate = ForceUpdate + + self:RegisterEvent("RAID_TARGET_UPDATE", Path, true) + + if(ricon:IsObjectType"Texture" and not ricon:GetTexture()) then + ricon:SetTexture[[Interface\TargetingFrame\UI-RaidTargetingIcons]] + end + + return true + end +end + +local Disable = function(self) + local ricon = self.RaidIcon + if(ricon) then + ricon:Hide() + self:UnregisterEvent("RAID_TARGET_UPDATE", Path) + end +end + +oUF:AddElement('RaidIcon', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/runebar.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/runebar.lua new file mode 100644 index 0000000..15239f3 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/runebar.lua @@ -0,0 +1,137 @@ +--[[ Element: Runes Bar + + Handle updating and visibility of the Death Knight's Rune indicators. + + Widget + + Runes - An array holding StatusBar's. + + Sub-Widgets + + .bg - A Texture which functions as a background. It will inherit the color of + the main StatusBar. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + Sub-Widgets Options + + .multiplier - Defines a multiplier, which is used to tint the background based + on the main widgets R, G and B values. Defaults to 1 if not + present. + + Examples + + local Runes = {} + for index = 1, 6 do + -- Position and size of the rune bar indicators + local Rune = CreateFrame('StatusBar', nil, self) + Rune:SetSize(120 / 6, 20) + Rune:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * 120 / 6, 0) + + Runes[index] = Rune + end + + -- Register with oUF + self.Runes = Runes + + Hooks + + Override(self) - Used to completely override the internal update + function. Removing the table key entry will make the + element fall-back to its internal function again. + +]] + +if select(2, UnitClass("player")) ~= "DEATHKNIGHT" then return end + +local parent, ns = ... +local oUF = ns.oUF + +local OnUpdate = function(self, elapsed) + local duration = self.duration + elapsed + self.duration = duration + self:SetValue(duration) +end + +local Update = function(self, event, rid, energized) + local runes = self.Runes + local rune = runes[rid] + if(not rune) then return end + + local start, duration, runeReady + if(UnitHasVehicleUI'player') then + rune:Hide() + else + start, duration, runeReady = GetRuneCooldown(rid) + if(not start) then return end + + if(energized or runeReady) then + rune:SetMinMaxValues(0, 1) + rune:SetValue(1) + rune:SetScript("OnUpdate", nil) + else + rune.duration = GetTime() - start + rune.max = duration + rune:SetMinMaxValues(1, duration) + rune:SetScript("OnUpdate", OnUpdate) + end + + rune:Show() + end + + if(runes.PostUpdate) then + return runes:PostUpdate(rune, rid, start, duration, energized or runeReady) + end +end + +local Path = function(self, event, ...) + local runes = self.Runes + local UpdateMethod = runes.Override or Update + if(event == 'RUNE_POWER_UPDATE') then + return UpdateMethod(self, event, ...) + else + for index = 1, #runes do + UpdateMethod(self, event, index) + end + end +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate') +end + +local Enable = function(self, unit) + local runes = self.Runes + if(runes and unit == 'player') then + runes.__owner = self + runes.ForceUpdate = ForceUpdate + + for i = 1, #runes do + local rune = runes[i] + + local r, g, b = unpack(self.colors.power.RUNES) + if(rune:IsObjectType'StatusBar' and not rune:GetStatusBarTexture()) then + rune:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + rune:SetStatusBarColor(r, g, b) + end + + if(rune.bg) then + local mu = rune.bg.multiplier or 1 + rune.bg:SetVertexColor(r * mu, g * mu, b * mu) + end + end + + self:RegisterEvent("RUNE_POWER_UPDATE", Path, true) + + return true + end +end + +local Disable = function(self) + self:UnregisterEvent("RUNE_POWER_UPDATE", Path) +end + +oUF:AddElement("Runes", Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/stagger.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/stagger.lua new file mode 100644 index 0000000..9da966f --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/stagger.lua @@ -0,0 +1,175 @@ +--[[ Element: Monk Stagger Bar + + Handles updating and visibility of the monk's stagger bar. + + Widget + + Stagger - A StatusBar + + Sub-Widgets + + .bg - A Texture that functions as a background. It will inherit the color + of the main StatusBar. + + Notes + + The default StatusBar texture will be applied if the UI widget doesn't have a + status bar texture or color defined. + + In order to override the internal update define the 'OnUpdate' script on the + widget in the layout + + Sub-Widgets Options + + .multiplier - Defines a multiplier, which is used to tint the background based + on the main widgets R, G and B values. Defaults to 1 if not + present. + + Examples + + local Stagger = CreateFrame('StatusBar', nil, self) + Stagger:SetSize(120, 20) + Stagger:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', 0, 0) + + -- Register with oUF + self.Stagger = Stagger + + Hooks + + OverrideVisibility(self) - Used to completely override the internal visibility + function. Removing the table key entry will make + the element fall-back to its internal function + again. + Override(self) - Used to completely override the internal + update function. Removing the table key entry will + make the element fall-back to its internal function + again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +-- percentages at which the bar should change color +local STAGGER_YELLOW_TRANSITION = STAGGER_YELLOW_TRANSITION +local STAGGER_RED_TRANSITION = STAGGER_RED_TRANSITION + +-- table indices of bar colors +local STAGGER_GREEN_INDEX = STAGGER_GREEN_INDEX or 1 +local STAGGER_YELLOW_INDEX = STAGGER_YELLOW_INDEX or 2 +local STAGGER_RED_INDEX = STAGGER_RED_INDEX or 3 + +local UnitHealthMax = UnitHealthMax +local UnitStagger = UnitStagger + +local _, playerClass = UnitClass("player") +local color + +local Update = function(self, event, unit) + if unit and unit ~= self.unit then return end + local element = self.Stagger + + if(element.PreUpdate) then + element:PreUpdate() + end + + local maxHealth = UnitHealthMax("player") + local stagger = UnitStagger("player") + local staggerPercent = stagger / maxHealth + + element:SetMinMaxValues(0, maxHealth) + element:SetValue(stagger) + + local rgb + if(staggerPercent >= STAGGER_RED_TRANSITION) then + rgb = color[STAGGER_RED_INDEX] + elseif(staggerPercent > STAGGER_YELLOW_TRANSITION) then + rgb = color[STAGGER_YELLOW_INDEX] + else + rgb = color[STAGGER_GREEN_INDEX] + end + + local r, g, b = rgb[1], rgb[2], rgb[3] + element:SetStatusBarColor(r, g, b) + + local bg = element.bg + if(bg) then + local mu = bg.multiplier or 1 + bg:SetVertexColor(r * mu, g * mu, b * mu) + end + + if(element.PostUpdate) then + element:PostUpdate(maxHealth, stagger, staggerPercent, r, g, b) + end +end + +local Path = function(self, ...) + return (self.Stagger.Override or Update)(self, ...) +end + +local Visibility = function(self, event, unit) + if(SPEC_MONK_BREWMASTER ~= GetSpecialization() or UnitHasVehiclePlayerFrameUI('player')) then + if self.Stagger:IsShown() then + self.Stagger:Hide() + self:UnregisterEvent('UNIT_AURA', Path) + end + else + if(not self.Stagger:IsShown()) then + self.Stagger:Show() + self:RegisterEvent('UNIT_AURA', Path) + end + + return Path(self, event, unit) + end +end + +local VisibilityPath = function(self, ...) + return (self.Stagger.OverrideVisibility or Visibility)(self, ...) +end + +local ForceUpdate = function(element) + return VisibilityPath(element.__owner, "ForceUpdate", element.__owner.unit) +end + +local Enable = function(self, unit) + if(playerClass ~= "MONK") then return end + + local element = self.Stagger + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + element:Hide() + + color = self.colors.power[BREWMASTER_POWER_BAR_NAME] + + self:RegisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) + self:RegisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath, true) + + if(element:IsObjectType'StatusBar' and not element:GetStatusBarTexture()) then + element:SetStatusBarTexture[[Interface\TargetingFrame\UI-StatusBar]] + end + + MonkStaggerBar:UnregisterEvent'PLAYER_ENTERING_WORLD' + MonkStaggerBar:UnregisterEvent'PLAYER_SPECIALIZATION_CHANGED' + MonkStaggerBar:UnregisterEvent'UNIT_DISPLAYPOWER' + MonkStaggerBar:UnregisterEvent'UPDATE_VEHICLE_ACTION_BAR' + + return true + end +end + +local Disable = function(self) + local element = self.Stagger + if(element) then + element:Hide() + self:UnregisterEvent('UNIT_AURA', Path) + self:UnregisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) + self:UnregisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath) + + MonkStaggerBar:UnregisterEvent'PLAYER_ENTERING_WORLD' + MonkStaggerBar:UnregisterEvent'PLAYER_SPECIALIZATION_CHANGED' + MonkStaggerBar:UnregisterEvent'UNIT_DISPLAYPOWER' + MonkStaggerBar:UnregisterEvent'UPDATE_VEHICLE_ACTION_BAR' + end +end + +oUF:AddElement("Stagger", VisibilityPath, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/tags.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/tags.lua new file mode 100644 index 0000000..3ec554b --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/tags.lua @@ -0,0 +1,695 @@ +--[[ +-- Credits: Vika, Cladhaire, Tekkub +]] + +local parent, ns = ... +local oUF = ns.oUF + +local _PATTERN = '%[..-%]+' + +local _ENV = { + Hex = function(r, g, b) + if type(r) == "table" then + if r.r then r, g, b = r.r, r.g, r.b else r, g, b = unpack(r) end + end + return string.format("|cff%02x%02x%02x", r*255, g*255, b*255) + end, + ColorGradient = oUF.ColorGradient, +} +local _PROXY = setmetatable(_ENV, {__index = _G}) + +local tagStrings = { + ["creature"] = [[function(u) + return UnitCreatureFamily(u) or UnitCreatureType(u) + end]], + + ["dead"] = [[function(u) + if(UnitIsDead(u)) then + return 'Dead' + elseif(UnitIsGhost(u)) then + return 'Ghost' + end + end]], + + ["difficulty"] = [[function(u) + if UnitCanAttack("player", u) then + local l = UnitLevel(u) + return Hex(GetQuestDifficultyColor((l > 0) and l or 99)) + end + end]], + + ["leader"] = [[function(u) + if(UnitIsGroupLeader(u)) then + return 'L' + end + end]], + + ["leaderlong"] = [[function(u) + if(UnitIsGroupLeader(u)) then + return 'Leader' + end + end]], + + ["level"] = [[function(u) + local l = UnitLevel(u) + if(UnitIsWildBattlePet(u) or UnitIsBattlePetCompanion(u)) then + l = UnitBattlePetLevel(u) + end + + if(l > 0) then + return l + else + return '??' + end + end]], + + ["missinghp"] = [[function(u) + local current = UnitHealthMax(u) - UnitHealth(u) + if(current > 0) then + return current + end + end]], + + ["missingpp"] = [[function(u) + local current = UnitPowerMax(u) - UnitPower(u) + if(current > 0) then + return current + end + end]], + + ["name"] = [[function(u, r) + return UnitName(r or u) + end]], + + ["offline"] = [[function(u) + if(not UnitIsConnected(u)) then + return 'Offline' + end + end]], + + ["perhp"] = [[function(u) + local m = UnitHealthMax(u) + if(m == 0) then + return 0 + else + return math.floor(UnitHealth(u)/m*100+.5) + end + end]], + + ["perpp"] = [[function(u) + local m = UnitPowerMax(u) + if(m == 0) then + return 0 + else + return math.floor(UnitPower(u)/m*100+.5) + end + end]], + + ["plus"] = [[function(u) + local c = UnitClassification(u) + if(c == 'elite' or c == 'rareelite') then + return '+' + end + end]], + + ["pvp"] = [[function(u) + if(UnitIsPVP(u)) then + return 'PvP' + end + end]], + + ["raidcolor"] = [[function(u) + local _, x = UnitClass(u) + if(x) then + return Hex(_COLORS.class[x]) + end + end]], + + ["rare"] = [[function(u) + local c = UnitClassification(u) + if(c == 'rare' or c == 'rareelite') then + return 'Rare' + end + end]], + + ["resting"] = [[function(u) + if(u == 'player' and IsResting()) then + return 'zzz' + end + end]], + + ["sex"] = [[function(u) + local s = UnitSex(u) + if(s == 2) then + return 'Male' + elseif(s == 3) then + return 'Female' + end + end]], + + ["smartclass"] = [[function(u) + if(UnitIsPlayer(u)) then + return _TAGS['class'](u) + end + + return _TAGS['creature'](u) + end]], + + ["status"] = [[function(u) + if(UnitIsDead(u)) then + return 'Dead' + elseif(UnitIsGhost(u)) then + return 'Ghost' + elseif(not UnitIsConnected(u)) then + return 'Offline' + else + return _TAGS['resting'](u) + end + end]], + + ["threat"] = [[function(u) + local s = UnitThreatSituation(u) + if(s == 1) then + return '++' + elseif(s == 2) then + return '--' + elseif(s == 3) then + return 'Aggro' + end + end]], + + ["threatcolor"] = [[function(u) + return Hex(GetThreatStatusColor(UnitThreatSituation(u))) + end]], + + ["cpoints"] = [[function(u) + local cp + if(UnitHasVehicleUI'player') then + cp = GetComboPoints('vehicle', 'target') + else + cp = GetComboPoints('player', 'target') + end + + if(cp > 0) then + return cp + end + end]], + + ['smartlevel'] = [[function(u) + local c = UnitClassification(u) + if(c == 'worldboss') then + return 'Boss' + else + local plus = _TAGS['plus'](u) + local level = _TAGS['level'](u) + if(plus) then + return level .. plus + else + return level + end + end + end]], + + ["classification"] = [[function(u) + local c = UnitClassification(u) + if(c == 'rare') then + return 'Rare' + elseif(c == 'rareelite') then + return 'Rare Elite' + elseif(c == 'elite') then + return 'Elite' + elseif(c == 'worldboss') then + return 'Boss' + elseif(c == 'minus') then + return 'Affix' + end + end]], + + ["shortclassification"] = [[function(u) + local c = UnitClassification(u) + if(c == 'rare') then + return 'R' + elseif(c == 'rareelite') then + return 'R+' + elseif(c == 'elite') then + return '+' + elseif(c == 'worldboss') then + return 'B' + elseif(c == 'minus') then + return '-' + end + end]], + + ["group"] = [[function(unit) + local name, server = UnitName(unit) + if(server and server ~= "") then + name = string.format("%s-%s", name, server) + end + + for i=1, GetNumGroupMembers() do + local raidName, _, group = GetRaidRosterInfo(i) + if( raidName == name ) then + return group + end + end + end]], + + ["deficit:name"] = [[function(u) + local missinghp = _TAGS['missinghp'](u) + if(missinghp) then + return '-' .. missinghp + else + return _TAGS['name'](u) + end + end]], + + ['curmana'] = [[function(unit) + return UnitPower(unit, SPELL_POWER_MANA) + end]], + + ['maxmana'] = [[function(unit) + return UnitPowerMax(unit, SPELL_POWER_MANA) + end]], + + ['soulshards'] = [[function() + local num = UnitPower('player', SPELL_POWER_SOUL_SHARDS) + if(num > 0) then + return num + end + end]], + + ['holypower'] = [[function() + if(GetSpecialization() == SPEC_PALADIN_RETRIBUTION) then + local num = UnitPower('player', SPELL_POWER_HOLY_POWER) + if(num > 0) then + return num + end + end + end]], + + ['chi'] = [[function() + if(GetSpecialization() == SPEC_MONK_WINDWALKER) then + local num = UnitPower('player', SPELL_POWER_CHI) + if(num > 0) then + return num + end + end + end]], + + ['arcanecharges'] = [[function() + if(GetSpecialization() == SPEC_MAGE_ARCANE) then + local num = UnitPower('player', SPELL_POWER_ARCANE_CHARGES) + if(num > 0) then + return num + end + end + end]], + + ['affix'] = [[function(u) + local c = UnitClassification(u) + if(c == 'minus') then + return 'Affix' + end + end]], +} + +local tags = setmetatable( + { + curhp = UnitHealth, + curpp = UnitPower, + maxhp = UnitHealthMax, + maxpp = UnitPowerMax, + class = UnitClass, + faction = UnitFactionGroup, + race = UnitRace, + }, + + { + __index = function(self, key) + local tagFunc = tagStrings[key] + if(tagFunc) then + local func, err = loadstring('return ' .. tagFunc) + if(func) then + func = func() + + -- Want to trigger __newindex, so no rawset. + self[key] = func + tagStrings[key] = nil + + return func + else + error(err, 3) + end + end + end, + __newindex = function(self, key, val) + if(type(val) == 'string') then + tagStrings[key] = val + elseif(type(val) == 'function') then + -- So we don't clash with any custom envs. + if(getfenv(val) == _G) then + setfenv(val, _PROXY) + end + + rawset(self, key, val) + end + end, + } +) + +_ENV._TAGS = tags + +local tagEvents = { + ["curhp"] = "UNIT_HEALTH", + ["dead"] = "UNIT_HEALTH", + ["leader"] = "PARTY_LEADER_CHANGED", + ["leaderlong"] = "PARTY_LEADER_CHANGED", + ["level"] = "UNIT_LEVEL PLAYER_LEVEL_UP", + ["maxhp"] = "UNIT_MAXHEALTH", + ["missinghp"] = "UNIT_HEALTH UNIT_MAXHEALTH", + ["name"] = "UNIT_NAME_UPDATE", + ["perhp"] = "UNIT_HEALTH UNIT_MAXHEALTH", + ["pvp"] = "UNIT_FACTION", + ["resting"] = "PLAYER_UPDATE_RESTING", + ["smartlevel"] = "UNIT_LEVEL PLAYER_LEVEL_UP UNIT_CLASSIFICATION_CHANGED", + ["threat"] = "UNIT_THREAT_SITUATION_UPDATE", + ["threatcolor"] = "UNIT_THREAT_SITUATION_UPDATE", + ['cpoints'] = 'UNIT_POWER_FREQUENT PLAYER_TARGET_CHANGED', + ['affix'] = 'UNIT_CLASSIFICATION_CHANGED', + ['plus'] = 'UNIT_CLASSIFICATION_CHANGED', + ['rare'] = 'UNIT_CLASSIFICATION_CHANGED', + ['classification'] = 'UNIT_CLASSIFICATION_CHANGED', + ['shortclassification'] = 'UNIT_CLASSIFICATION_CHANGED', + ["group"] = "GROUP_ROSTER_UPDATE", + ["curpp"] = 'UNIT_POWER', + ["maxpp"] = 'UNIT_MAXPOWER', + ["missingpp"] = 'UNIT_MAXPOWER UNIT_POWER', + ["perpp"] = 'UNIT_MAXPOWER UNIT_POWER', + ["offline"] = "UNIT_HEALTH UNIT_CONNECTION", + ["status"] = "UNIT_HEALTH PLAYER_UPDATE_RESTING UNIT_CONNECTION", + ['curmana'] = 'UNIT_POWER UNIT_MAXPOWER', + ['maxmana'] = 'UNIT_POWER UNIT_MAXPOWER', + ['soulshards'] = 'UNIT_POWER', + ['holypower'] = 'UNIT_POWER SPELLS_CHANGED', + ['chi'] = 'UNIT_POWER SPELLS_CHANGED', + ['arcanecharges'] = 'UNIT_POWER SPELLS_CHANGED', +} + +local unitlessEvents = { + PLAYER_LEVEL_UP = true, + PLAYER_UPDATE_RESTING = true, + PLAYER_TARGET_CHANGED = true, + + PARTY_LEADER_CHANGED = true, + + GROUP_ROSTER_UPDATE = true, +} + +local events = {} +local frame = CreateFrame"Frame" +frame:SetScript('OnEvent', function(self, event, unit) + local strings = events[event] + if(strings) then + for k, fontstring in next, strings do + if(fontstring:IsVisible() and (unitlessEvents[event] or fontstring.parent.unit == unit)) then + fontstring:UpdateTag() + end + end + end +end) + +local OnUpdates = {} +local eventlessUnits = {} + +local createOnUpdate = function(timer) + local OnUpdate = OnUpdates[timer] + + if(not OnUpdate) then + local total = timer + local frame = CreateFrame'Frame' + local strings = eventlessUnits[timer] + + frame:SetScript('OnUpdate', function(self, elapsed) + if(total >= timer) then + for k, fs in next, strings do + if(fs.parent:IsShown() and UnitExists(fs.parent.unit)) then + fs:UpdateTag() + end + end + + total = 0 + end + + total = total + elapsed + end) + + OnUpdates[timer] = frame + end +end + +local OnShow = function(self) + for _, fs in next, self.__tags do + fs:UpdateTag() + end +end + +local getTagName = function(tag) + local s = (tag:match('>+()') or 2) + local e = tag:match('.*()<+') + e = (e and e - 1) or -2 + + return tag:sub(s, e), s, e +end + +local RegisterEvent = function(fontstr, event) + if(not events[event]) then events[event] = {} end + + frame:RegisterEvent(event) + table.insert(events[event], fontstr) +end + +local RegisterEvents = function(fontstr, tagstr) + for tag in tagstr:gmatch(_PATTERN) do + tag = getTagName(tag) + local tagevents = tagEvents[tag] + if(tagevents) then + for event in tagevents:gmatch'%S+' do + RegisterEvent(fontstr, event) + end + end + end +end + +local UnregisterEvents = function(fontstr) + for event, data in pairs(events) do + for k, tagfsstr in pairs(data) do + if(tagfsstr == fontstr) then + if(#data == 1) then + frame:UnregisterEvent(event) + end + + table.remove(data, k) + end + end + end +end + +local tagPool = {} +local funcPool = {} +local tmp = {} + +local Tag = function(self, fs, tagstr) + if(not fs or not tagstr) then return end + + if(not self.__tags) then + self.__tags = {} + table.insert(self.__elements, OnShow) + else + -- Since people ignore everything that's good practice - unregister the tag + -- if it already exists. + for _, tag in pairs(self.__tags) do + if(fs == tag) then + -- We don't need to remove it from the __tags table as Untag handles + -- that for us. + self:Untag(fs) + end + end + end + + fs.parent = self + + local func = tagPool[tagstr] + if(not func) then + local format, numTags = tagstr:gsub('%%', '%%%%'):gsub(_PATTERN, '%%s') + local args = {} + + for bracket in tagstr:gmatch(_PATTERN) do + local tagFunc = funcPool[bracket] or tags[bracket:sub(2, -2)] + if(not tagFunc) then + local tagName, s, e = getTagName(bracket) + + local tag = tags[tagName] + if(tag) then + s = s - 2 + e = e + 2 + + if(s ~= 0 and e ~= 0) then + local pre = bracket:sub(2, s) + local ap = bracket:sub(e, -2) + + tagFunc = function(u,r) + local str = tag(u,r) + if(str) then + return pre..str..ap + end + end + elseif(s ~= 0) then + local pre = bracket:sub(2, s) + + tagFunc = function(u,r) + local str = tag(u,r) + if(str) then + return pre..str + end + end + elseif(e ~= 0) then + local ap = bracket:sub(e, -2) + + tagFunc = function(u,r) + local str = tag(u,r) + if(str) then + return str..ap + end + end + end + + funcPool[bracket] = tagFunc + end + end + + if(tagFunc) then + table.insert(args, tagFunc) + else + return error(('Attempted to use invalid tag %s.'):format(bracket), 3) + end + end + + if(numTags == 1) then + func = function(self) + local parent = self.parent + local realUnit + if(self.overrideUnit) then + realUnit = parent.realUnit + end + + _ENV._COLORS = parent.colors + return self:SetFormattedText( + format, + args[1](parent.unit, realUnit) or '' + ) + end + elseif(numTags == 2) then + func = function(self) + local parent = self.parent + local unit = parent.unit + local realUnit + if(self.overrideUnit) then + realUnit = parent.realUnit + end + + _ENV._COLORS = parent.colors + return self:SetFormattedText( + format, + args[1](unit, realUnit) or '', + args[2](unit, realUnit) or '' + ) + end + elseif(numTags == 3) then + func = function(self) + local parent = self.parent + local unit = parent.unit + local realUnit + if(self.overrideUnit) then + realUnit = parent.realUnit + end + + _ENV._COLORS = parent.colors + return self:SetFormattedText( + format, + args[1](unit, realUnit) or '', + args[2](unit, realUnit) or '', + args[3](unit, realUnit) or '' + ) + end + else + func = function(self) + local parent = self.parent + local unit = parent.unit + local realUnit + if(self.overrideUnit) then + realUnit = parent.realUnit + end + + _ENV._COLORS = parent.colors + for i, func in next, args do + tmp[i] = func(unit, realUnit) or '' + end + + -- We do 1, numTags because tmp can hold several unneeded variables. + return self:SetFormattedText(format, unpack(tmp, 1, numTags)) + end + end + + tagPool[tagstr] = func + end + fs.UpdateTag = func + + local unit = self.unit + if(self.__eventless or fs.frequentUpdates) then + local timer + if(type(fs.frequentUpdates) == 'number') then + timer = fs.frequentUpdates + else + timer = .5 + end + + if(not eventlessUnits[timer]) then eventlessUnits[timer] = {} end + table.insert(eventlessUnits[timer], fs) + + createOnUpdate(timer) + else + RegisterEvents(fs, tagstr) + end + + table.insert(self.__tags, fs) +end + +local Untag = function(self, fs) + if(not fs) then return end + + UnregisterEvents(fs) + for _, timers in next, eventlessUnits do + for k, fontstr in next, timers do + if(fs == fontstr) then + table.remove(timers, k) + end + end + end + + for k, fontstr in next, self.__tags do + if(fontstr == fs) then + table.remove(self.__tags, k) + end + end + + fs.UpdateTag = nil +end + +oUF.Tags = { + Methods = tags, + Events = tagEvents, + SharedEvents = unitlessEvents, + +} +oUF:RegisterMetaFunction('Tag', Tag) +oUF:RegisterMetaFunction('Untag', Untag) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/threat.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/threat.lua new file mode 100644 index 0000000..44a8d6b --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/threat.lua @@ -0,0 +1,92 @@ +--[[ Element: Threat Icon + + Handles updating and toggles visibility of current threat level icon. + + Widget + + Threat - A Texture used to display the current threat level. + + Notes + + This element updates by changing colors of the texture. + + The default threat icon will be used if the UI widget is a texture and doesn't + have a texture or color defined. + + Examples + + -- Position and size + local Threat = self:CreateTexture(nil, 'OVERLAY') + Threat:SetSize(16, 16) + Threat:SetPoint('TOPRIGHT', self) + + -- Register it with oUF + self.Threat = Threat + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +local Update = function(self, event, unit) + if(unit ~= self.unit) then return end + + local threat = self.Threat + if(threat.PreUpdate) then threat:PreUpdate(unit) end + + unit = unit or self.unit + local status = UnitThreatSituation(unit) + + local r, g, b + if(status and status > 0) then + r, g, b = GetThreatStatusColor(status) + threat:SetVertexColor(r, g, b) + threat:Show() + else + threat:Hide() + end + + if(threat.PostUpdate) then + return threat:PostUpdate(unit, status, r, g, b) + end +end + +local Path = function(self, ...) + return (self.Threat.Override or Update) (self, ...) +end + +local ForceUpdate = function(element) + return Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local Enable = function(self) + local threat = self.Threat + if(threat) then + threat.__owner = self + threat.ForceUpdate = ForceUpdate + + self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + + if(threat:IsObjectType"Texture" and not threat:GetTexture()) then + threat:SetTexture[[Interface\Minimap\ObjectIcons]] + threat:SetTexCoord(6/8, 7/8, 1/8, 2/8) + end + + return true + end +end + +local Disable = function(self) + local threat = self.Threat + if(threat) then + threat:Hide() + self:UnregisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + end +end + +oUF:AddElement('Threat', Path, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/elements/totems.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/totems.lua new file mode 100644 index 0000000..bf19e90 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/elements/totems.lua @@ -0,0 +1,177 @@ +--[[ Element: Totem Indicator + + Handles updating and visibility of Shaman totems, Druid mushrooms and Death + Knight ghouls. + + Widget + + Totems - A table to hold sub-widgets. + + Sub-Widgets + + Totem - Any UI widget. + .Icon - A Texture representing the totem icon. + .Cooldown - A Cooldown representing the duration of the totem. + + Notes + + OnEnter and OnLeave will be set to display the default Tooltip, if the + `Totem` widget is mouse enabled. + + Options + + :UpdateTooltip - The function that should populate the tooltip, when the + `Totem` widget is hovered. A default function, which calls + `:SetTotem(id)`, will be used if none is defined. + + Examples + + local Totems = {} + for index = 1, MAX_TOTEMS do + -- Position and size of the totem indicator + local Totem = CreateFrame('Button', nil, self) + Totem:SetSize(40, 40) + Totem:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Totem:GetWidth(), 0) + + local Icon = Totem:CreateTexture(nil, "OVERLAY") + Icon:SetAllPoints() + + local Cooldown = CreateFrame("Cooldown", nil, Totem, "CooldownFrameTemplate") + Cooldown:SetAllPoints() + + Totem.Icon = Icon + Totem.Cooldown = Cooldown + + Totems[index] = Totem + end + + -- Register with oUF + self.Totems = Totems + + Hooks + + Override(self) - Used to completely override the internal update function. + Removing the table key entry will make the element fall-back + to its internal function again. +]] + +local parent, ns = ... +local oUF = ns.oUF + +-- Order the list based upon the default UIs priorities. +local priorities = STANDARD_TOTEM_PRIORITIES +if(select(2, UnitClass'player') == 'SHAMAN') then + priorities = SHAMAN_TOTEM_PRIORITIES +end + +local UpdateTooltip = function(self) + GameTooltip:SetTotem(self:GetID()) +end + +local OnEnter = function(self) + if(not self:IsVisible()) then return end + + GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') + self:UpdateTooltip() +end + +local OnLeave = function() + GameTooltip:Hide() +end + +local UpdateTotem = function(self, event, slot) + if(slot > MAX_TOTEMS) then return end + local totems = self.Totems + + if(totems.PreUpdate) then totems:PreUpdate(priorities[slot]) end + + local totem = totems[priorities[slot]] + local haveTotem, name, start, duration, icon = GetTotemInfo(slot) + if(duration > 0) then + if(totem.Icon) then + totem.Icon:SetTexture(icon) + end + + if(totem.Cooldown) then + totem.Cooldown:SetCooldown(start, duration) + end + + totem:Show() + else + totem:Hide() + end + + if(totems.PostUpdate) then + return totems:PostUpdate(priorities[slot], haveTotem, name, start, duration, icon) + end +end + +local Path = function(self, ...) + return (self.Totems.Override or UpdateTotem) (self, ...) +end + +local Update = function(self, event) + for i = 1, MAX_TOTEMS do + Path(self, event, i) + end +end + +local ForceUpdate = function(element) + return Update(element.__owner, 'ForceUpdate') +end + +local Enable = function(self) + local totems = self.Totems + + if(totems) then + totems.__owner = self + totems.__map = { unpack(priorities) } + totems.ForceUpdate = ForceUpdate + + for i = 1, MAX_TOTEMS do + local totem = totems[i] + + totem:SetID(priorities[i]) + + if(totem:IsMouseEnabled()) then + totem:SetScript('OnEnter', OnEnter) + totem:SetScript('OnLeave', OnLeave) + + if(not totem.UpdateTooltip) then + totem.UpdateTooltip = UpdateTooltip + end + end + end + + self:RegisterEvent('PLAYER_TOTEM_UPDATE', Path, true) + + TotemFrame.Show = TotemFrame.Hide + TotemFrame:Hide() + + TotemFrame:UnregisterEvent"PLAYER_TOTEM_UPDATE" + TotemFrame:UnregisterEvent"PLAYER_ENTERING_WORLD" + TotemFrame:UnregisterEvent"UPDATE_SHAPESHIFT_FORM" + TotemFrame:UnregisterEvent"PLAYER_TALENT_UPDATE" + + return true + end +end + +local Disable = function(self) + if(self.Totems) then + for i = 1, MAX_TOTEMS do + self.Totems[i]:Hide() + end + TotemFrame.Show = nil + TotemFrame:Show() + + TotemFrame:RegisterEvent"PLAYER_TOTEM_UPDATE" + TotemFrame:RegisterEvent"PLAYER_ENTERING_WORLD" + TotemFrame:RegisterEvent"UPDATE_SHAPESHIFT_FORM" + TotemFrame:RegisterEvent"PLAYER_TALENT_UPDATE" + + self:UnregisterEvent('PLAYER_TOTEM_UPDATE', Path) + end +end + +oUF:AddElement("Totems", Update, Enable, Disable) diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/events.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/events.lua new file mode 100644 index 0000000..553dab6 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/events.lua @@ -0,0 +1,127 @@ +local parent, ns = ... +local oUF = ns.oUF +local Private = oUF.Private + +local argcheck = Private.argcheck +local error = Private.error +local frame_metatable = Private.frame_metatable + +-- Original event methods +local RegisterEvent = frame_metatable.__index.RegisterEvent +local RegisterUnitEvent = frame_metatable.__index.RegisterUnitEvent +local UnregisterEvent = frame_metatable.__index.UnregisterEvent +local IsEventRegistered = frame_metatable.__index.IsEventRegistered + +local unitEvents = {} + +Private.UpdateUnits = function(frame, unit, realUnit) + if unit == realUnit then + realUnit = nil + end + if frame.unit ~= unit or frame.realUnit ~= realUnit then + for event in next, unitEvents do + -- IsEventRegistered returns the units in case of an event + -- registered with RegisterUnitEvent + local registered, unit1 = IsEventRegistered(frame, event) + if registered and unit1 ~= unit then + -- RegisterUnitEvent erases previously registered units so + -- do not bother to unregister it + RegisterUnitEvent(frame, event, unit, realUnit) + end + end + frame.unit = unit + frame.realUnit = realUnit + frame.id = unit:match'^.-(%d+)' + return true + end +end + +local OnEvent = function(self, event, ...) + if self:IsVisible() then + return self[event](self, event, ...) + end +end + +local event_metatable = { + __call = function(funcs, self, ...) + for _, func in next, funcs do + func(self, ...) + end + end, +} + +function frame_metatable.__index:RegisterEvent(event, func, unitless) + -- Block OnUpdate polled frames from registering events. + if(self.__eventless) then return end + + argcheck(event, 2, 'string') + + if(type(func) == 'string' and type(self[func]) == 'function') then + func = self[func] + end + + -- TODO: should warn the user. + if not unitless and not (unitEvents[event] or event:match'^UNIT_') then + unitless = true + end + + local curev = self[event] + local kind = type(curev) + if(curev and func) then + if(kind == 'function' and curev ~= func) then + self[event] = setmetatable({curev, func}, event_metatable) + elseif(kind == 'table') then + for _, infunc in next, curev do + if(infunc == func) then return end + end + + table.insert(curev, func) + end + elseif(IsEventRegistered(self, event)) then + return + else + if(type(func) == 'function') then + self[event] = func + elseif(not self[event]) then + return error("Style [%s] attempted to register event [%s] on unit [%s] with a handler that doesn't exist.", self.style, event, self.unit or 'unknown') + end + + if not self:GetScript('OnEvent') then + self:SetScript('OnEvent', OnEvent) + end + + if unitless then + RegisterEvent(self, event) + else + unitEvents[event] = true + RegisterUnitEvent(self, event, self.unit) + end + end +end + +function frame_metatable.__index:UnregisterEvent(event, func) + argcheck(event, 2, 'string') + + local curev = self[event] + if(type(curev) == 'table' and func) then + for k, infunc in next, curev do + if(infunc == func) then + table.remove(curev, k) + + local n = #curev + if(n == 1) then + local _, handler = next(curev) + self[event] = handler + elseif(n == 0) then + -- This should not happen + UnregisterEvent(self, event) + end + + break + end + end + elseif(curev == func) then + self[event] = nil + UnregisterEvent(self, event) + end +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/factory.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/factory.lua new file mode 100644 index 0000000..348c61a --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/factory.lua @@ -0,0 +1,48 @@ +local parent, ns = ... +local oUF = ns.oUF +local Private = oUF.Private + +local argcheck = Private.argcheck + +local _QUEUE = {} +local _FACTORY = CreateFrame'Frame' +_FACTORY:SetScript('OnEvent', function(self, event, ...) + return self[event](self, event, ...) +end) + +_FACTORY:RegisterEvent'PLAYER_LOGIN' +_FACTORY.active = true + +function _FACTORY:PLAYER_LOGIN() + if(not self.active) then return end + + for _, func in next, _QUEUE do + func(oUF) + end + + -- Avoid creating dupes. + wipe(_QUEUE) +end + +function oUF:Factory(func) + argcheck(func, 2, 'function') + + -- Call the function directly if we're active and logged in. + if(IsLoggedIn() and _FACTORY.active) then + return func(self) + else + table.insert(_QUEUE, func) + end +end + +function oUF:EnableFactory() + _FACTORY.active = true +end + +function oUF:DisableFactory() + _FACTORY.active = nil +end + +function oUF:RunFactoryQueue() + _FACTORY:PLAYER_LOGIN() +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/finalize.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/finalize.lua new file mode 100644 index 0000000..9355d19 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/finalize.lua @@ -0,0 +1,4 @@ +local parent, ns = ... + +-- It's named Private for a reason! +ns.oUF.Private = nil diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/init.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/init.lua new file mode 100644 index 0000000..46aef44 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/init.lua @@ -0,0 +1,3 @@ +local parent, ns = ... +ns.oUF = {} +ns.oUF.Private = {} diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.toc b/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.toc new file mode 100644 index 0000000..5ad1c03 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.toc @@ -0,0 +1,11 @@ +## Interface: 70000 +## Title: oUF +## Author: Haste +## Version: 1.6.9 +## OptionalDeps: Clique +## X-eMail: troeks@gmail.com +## X-oUF: oUF +## Notes: Unit frame framework. Does nothing by itself. +## Notes-ruRU: Каркас для модификации фреймов игроков. Сам по себе не делает ничего. + +oUF.xml diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.xml b/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.xml new file mode 100644 index 0000000..9acb6f5 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/oUF.xml @@ -0,0 +1,101 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/"> + <Script file='init.lua' /> + <Script file='private.lua' /> + <Script file='ouf.lua' /> + <Script file='events.lua'/> + <Script file='factory.lua' /> + <Script file='blizzard.lua' /> + <Script file='units.lua' /> + <Script file='colors.lua' /> + <Script file='finalize.lua' /> + + <Script file='elements\power.lua' /> + <Script file='elements\aura.lua' /> + <Script file='elements\health.lua' /> + <Script file='elements\cpoints.lua' /> + <Script file='elements\ricons.lua' /> + <Script file='elements\leader.lua' /> + <Script file='elements\combat.lua' /> + <Script file='elements\resting.lua' /> + <Script file='elements\pvp.lua' /> + <Script file='elements\portraits.lua' /> + <Script file='elements\range.lua' /> + <Script file='elements\castbar.lua' /> + <Script file='elements\threat.lua' /> + <Script file='elements\tags.lua' /> + <Script file='elements\masterlooter.lua' /> + <Script file='elements\assistant.lua' /> + <Script file='elements\runebar.lua' /> + <Script file='elements\lfdrole.lua' /> + <Script file='elements\healprediction.lua' /> + <Script file='elements\powerprediction.lua' /> + <Script file='elements\picon.lua' /> + <Script file='elements\readycheck.lua' /> + <Script file='elements\qicon.lua' /> + <Script file='elements\altpowerbar.lua' /> + <Script file='elements\totems.lua' /> + <Script file='elements\resurrect.lua' /> + <Script file='elements\druidmana.lua' /> + <Script file='elements\classicons.lua' /> + <Script file='elements\stagger.lua' /> + + <!-- Clique support --> + <Button name="oUF_ClickCastUnitTemplate" virtual="true" inherits="SecureUnitButtonTemplate,SecureHandlerEnterLeaveTemplate"> + <Attributes> + <Attribute name="_onenter" type="string" value="local snippet = self:GetAttribute('clickcast_onenter'); if snippet then self:Run(snippet) end"/> + <Attribute name="_onleave" type="string" value="local snippet = self:GetAttribute('clickcast_onleave'); if snippet then self:Run(snippet) end"/> + </Attributes> + </Button> + + <!-- Pet Battle Hider Frame --> + <Frame name="oUF_PetBattleFrameHider" inherits="SecureHandlerStateTemplate" parent="UIParent" setAllPoints="true"> + <Scripts> + <OnLoad> + RegisterStateDriver(self, "visibility", "[petbattle] hide; show") + </OnLoad> + </Scripts> + </Frame> + + <!-- + Sub-object as a child of the parent unit frame: + <Button name="oUF_HeaderTargetTemplate" inherits="SecureUnitButtonTemplate" virtual="true"> + <Frames> + <Button name="$parentTarget" inherits="SecureUnitButtonTemplate"> + <Attributes> + <Attribute name="unitsuffix" type="string" value="target"/> + <Attribute name="useparent-unit" type="boolean" value="true"/> + </Attributes> + </Button> + </Frames> + </Button> + + Separate unit template example: + <Button name="oUF_HeaderSeparateSubOjectsTemplate" inherits="SecureUnitButtonTemplate" virtual="true"> + <Attributes> + <Attribute name="oUF-onlyProcessChildren" type="boolean" value="true"/> + </Attributes> + + <Frames> + <Button name="$parentUnit" inherits="SecureUnitButtonTemplate"> + <Attributes> + <Attribute name="useparent-unit" type="boolean" value="true"/> + </Attributes> + </Button> + + <Button name="$parentPet" inherits="SecureUnitButtonTemplate"> + <Attributes> + <Attribute name="unitsuffix" type="string" value="pet"/> + <Attribute name="useparent-unit" type="boolean" value="true"/> + </Attributes> + </Button> + + <Button name="$parentTarget" inherits="SecureUnitButtonTemplate"> + <Attributes> + <Attribute name="unitsuffix" type="string" value="target"/> + <Attribute name="useparent-unit" type="boolean" value="true"/> + </Attributes> + </Button> + </Frames> + </Button> + --> +</Ui> diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/ouf.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/ouf.lua new file mode 100644 index 0000000..1b7253b --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/ouf.lua @@ -0,0 +1,587 @@ +local parent, ns = ... +local global = GetAddOnMetadata(parent, 'X-oUF') +local _VERSION = GetAddOnMetadata(parent, 'version') + +local oUF = ns.oUF +local Private = oUF.Private + +local argcheck = Private.argcheck + +local print = Private.print +local error = Private.error + +local styles, style = {} +local callback, objects, headers = {}, {}, {} + +local elements = {} +local activeElements = {} + +-- updating of "invalid" units. +local enableTargetUpdate = function(object) + object.onUpdateFrequency = object.onUpdateFrequency or .5 + object.__eventless = true + + local total = 0 + object:SetScript('OnUpdate', function(self, elapsed) + if(not self.unit) then + return + elseif(total > self.onUpdateFrequency) then + self:UpdateAllElements'OnUpdate' + total = 0 + end + + total = total + elapsed + end) +end +Private.enableTargetUpdate = enableTargetUpdate + +local updateActiveUnit = function(self, event, unit) + -- Calculate units to work with + local realUnit, modUnit = SecureButton_GetUnit(self), SecureButton_GetModifiedUnit(self) + + -- _GetUnit() doesn't rewrite playerpet -> pet like _GetModifiedUnit does. + if(realUnit == 'playerpet') then + realUnit = 'pet' + elseif(realUnit == 'playertarget') then + realUnit = 'target' + end + + if(modUnit == "pet" and realUnit ~= "pet") then + modUnit = "vehicle" + end + + -- Drop out if the event unit doesn't match any of the frame units. + if(not UnitExists(modUnit) or unit and unit ~= realUnit and unit ~= modUnit) then return end + + -- Change the active unit and run a full update. + if Private.UpdateUnits(self, modUnit, realUnit) then + self:UpdateAllElements('RefreshUnit') + + return true + end +end + +local iterateChildren = function(...) + for l = 1, select("#", ...) do + local obj = select(l, ...) + + if(type(obj) == 'table' and obj.isChild) then + updateActiveUnit(obj, "iterateChildren") + end + end +end + +local OnAttributeChanged = function(self, name, value) + if(name == "unit" and value) then + if(self.hasChildren) then + iterateChildren(self:GetChildren()) + end + + if(not self:GetAttribute'oUF-onlyProcessChildren') then + updateActiveUnit(self, "OnAttributeChanged") + end + end +end + +local frame_metatable = { + __index = CreateFrame"Button" +} +Private.frame_metatable = frame_metatable + +for k, v in pairs{ + EnableElement = function(self, name, unit) + argcheck(name, 2, 'string') + argcheck(unit, 3, 'string', 'nil') + + local element = elements[name] + if(not element or self:IsElementEnabled(name)) then return end + + if(element.enable(self, unit or self.unit)) then + activeElements[self][name] = true + + if(element.update) then + table.insert(self.__elements, element.update) + end + end + end, + + DisableElement = function(self, name) + argcheck(name, 2, 'string') + + local enabled = self:IsElementEnabled(name) + if(not enabled) then return end + + local update = elements[name].update + for k, func in next, self.__elements do + if(func == update) then + table.remove(self.__elements, k) + break + end + end + + activeElements[self][name] = nil + + -- We need to run a new update cycle in-case we knocked ourself out of sync. + -- The main reason we do this is to make sure the full update is completed + -- if an element for some reason removes itself _during_ the update + -- progress. + self:UpdateAllElements('DisableElement', name) + + return elements[name].disable(self) + end, + + IsElementEnabled = function(self, name) + argcheck(name, 2, 'string') + + local element = elements[name] + if(not element) then return end + + local active = activeElements[self] + return active and active[name] + end, + + Enable = RegisterUnitWatch, + Disable = function(self) + UnregisterUnitWatch(self) + self:Hide() + end, + + UpdateAllElements = function(self, event) + local unit = self.unit + if(not UnitExists(unit)) then return end + + if(self.PreUpdate) then + self:PreUpdate(event) + end + + for _, func in next, self.__elements do + func(self, event, unit) + end + + if(self.PostUpdate) then + self:PostUpdate(event) + end + end, +} do + frame_metatable.__index[k] = v +end + +local OnShow = function(self) + if(not updateActiveUnit(self, 'OnShow')) then + return self:UpdateAllElements'OnShow' + end +end + +local UpdatePet = function(self, event, unit) + local petUnit + if(unit == 'target') then + return + elseif(unit == 'player') then + petUnit = 'pet' + else + -- Convert raid26 -> raidpet26 + petUnit = unit:gsub('^(%a+)(%d+)', '%1pet%2') + end + + if(self.unit ~= petUnit) then return end + if(not updateActiveUnit(self, event)) then + return self:UpdateAllElements(event) + end +end + +local initObject = function(unit, style, styleFunc, header, ...) + local num = select('#', ...) + for i=1, num do + local object = select(i, ...) + local objectUnit = object:GetAttribute'oUF-guessUnit' or unit + local suffix = object:GetAttribute'unitsuffix' + + object.__elements = {} + object.style = style + object = setmetatable(object, frame_metatable) + + -- Expose the frame through oUF.objects. + table.insert(objects, object) + + -- We have to force update the frames when PEW fires. + object:RegisterEvent("PLAYER_ENTERING_WORLD", object.UpdateAllElements) + + -- Handle the case where someone has modified the unitsuffix attribute in + -- oUF-initialConfigFunction. + if(suffix and not objectUnit:match(suffix)) then + objectUnit = objectUnit .. suffix + end + + if(not (suffix == 'target' or objectUnit and objectUnit:match'target')) then + object:RegisterEvent('UNIT_ENTERED_VEHICLE', updateActiveUnit, true) + object:RegisterEvent('UNIT_EXITED_VEHICLE', updateActiveUnit, true) + + -- We don't need to register UNIT_PET for the player unit. We register it + -- mainly because UNIT_EXITED_VEHICLE and UNIT_ENTERED_VEHICLE doesn't always + -- have pet information when they fire for party and raid units. + if(objectUnit ~= 'player') then + object:RegisterEvent('UNIT_PET', UpdatePet, true) + end + end + + if(not header) then + -- No header means it's a frame created through :Spawn(). + object:SetAttribute("*type1", "target") + object:SetAttribute('*type2', 'togglemenu') + + -- No need to enable this for *target frames. + if(not (unit:match'target' or suffix == 'target')) then + object:SetAttribute('toggleForVehicle', true) + end + + -- Other boss and target units are handled by :HandleUnit(). + if(suffix == 'target') then + enableTargetUpdate(object) + else + oUF:HandleUnit(object) + end + else + -- Used to update frames when they change position in a group. + object:RegisterEvent('GROUP_ROSTER_UPDATE', object.UpdateAllElements) + + if(num > 1) then + if(object:GetParent() == header) then + object.hasChildren = true + else + object.isChild = true + end + end + + if(suffix == 'target') then + enableTargetUpdate(object) + end + end + + Private.UpdateUnits(object, objectUnit) + + styleFunc(object, objectUnit, not header) + + object:SetScript("OnAttributeChanged", OnAttributeChanged) + object:SetScript("OnShow", OnShow) + + activeElements[object] = {} + for element in next, elements do + object:EnableElement(element, objectUnit) + end + + for _, func in next, callback do + func(object) + end + + -- Make Clique happy + _G.ClickCastFrames = ClickCastFrames or {} + ClickCastFrames[object] = true + end +end + +local walkObject = function(object, unit) + local parent = object:GetParent() + local style = parent.style or style + local styleFunc = styles[style] + + local header = parent:GetAttribute'oUF-headerType' and parent + + -- Check if we should leave the main frame blank. + if(object:GetAttribute'oUF-onlyProcessChildren') then + object.hasChildren = true + object:SetScript('OnAttributeChanged', OnAttributeChanged) + return initObject(unit, style, styleFunc, header, object:GetChildren()) + end + + return initObject(unit, style, styleFunc, header, object, object:GetChildren()) +end + +function oUF:RegisterInitCallback(func) + table.insert(callback, func) +end + +function oUF:RegisterMetaFunction(name, func) + argcheck(name, 2, 'string') + argcheck(func, 3, 'function', 'table') + + if(frame_metatable.__index[name]) then + return + end + + frame_metatable.__index[name] = func +end + +function oUF:RegisterStyle(name, func) + argcheck(name, 2, 'string') + argcheck(func, 3, 'function', 'table') + + if(styles[name]) then return error("Style [%s] already registered.", name) end + if(not style) then style = name end + + styles[name] = func +end + +function oUF:SetActiveStyle(name) + argcheck(name, 2, 'string') + if(not styles[name]) then return error("Style [%s] does not exist.", name) end + + style = name +end + +do + local function iter(_, n) + -- don't expose the style functions. + return (next(styles, n)) + end + + function oUF.IterateStyles() + return iter, nil, nil + end +end + +local getCondition +do + local conditions = { + raid40 = '[@raid26,exists] show;', + raid25 = '[@raid11,exists] show;', + raid10 = '[@raid6,exists] show;', + raid = '[group:raid] show;', + party = '[group:party,nogroup:raid] show;', + solo = '[@player,exists,nogroup:party] show;', + } + + function getCondition(...) + local cond = '' + + for i=1, select('#', ...) do + local short = select(i, ...) + + local condition = conditions[short] + if(condition) then + cond = cond .. condition + end + end + + return cond .. 'hide' + end +end + +local generateName = function(unit, ...) + local name = 'oUF_' .. style:gsub('[^%a%d_]+', '') + + local raid, party, groupFilter + for i=1, select('#', ...), 2 do + local att, val = select(i, ...) + if(att == 'showRaid') then + raid = true + elseif(att == 'showParty') then + party = true + elseif(att == 'groupFilter') then + groupFilter = val + end + end + + local append + if(raid) then + if(groupFilter) then + if(type(groupFilter) == 'number' and groupFilter > 0) then + append = groupFilter + elseif(groupFilter:match'TANK') then + append = 'MainTank' + elseif(groupFilter:match'ASSIST') then + append = 'MainAssist' + else + local _, count = groupFilter:gsub(',', '') + if(count == 0) then + append = 'Raid' .. groupFilter + else + append = 'Raid' + end + end + else + append = 'Raid' + end + elseif(party) then + append = 'Party' + elseif(unit) then + append = unit:gsub("^%l", string.upper) + end + + if(append) then + name = name .. append + end + + -- Change oUF_LilyRaidRaid into oUF_LilyRaid + name = name:gsub('(%u%l+)([%u%l]*)%1', '%1') + -- Change oUF_LilyTargettarget into oUF_LilyTargetTarget + name = name:gsub('t(arget)', 'T%1') + + local base = name + local i = 2 + while(_G[name]) do + name = base .. i + i = i + 1 + end + + return name +end + +do + local styleProxy = function(self, frame, ...) + return walkObject(_G[frame]) + end + + -- There has to be an easier way to do this. + local initialConfigFunction = [[ + local header = self:GetParent() + local frames = table.new() + table.insert(frames, self) + self:GetChildList(frames) + for i=1, #frames do + local frame = frames[i] + local unit + -- There's no need to do anything on frames with onlyProcessChildren + if(not frame:GetAttribute'oUF-onlyProcessChildren') then + RegisterUnitWatch(frame) + + -- Attempt to guess what the header is set to spawn. + local groupFilter = header:GetAttribute'groupFilter' + + if(type(groupFilter) == 'string' and groupFilter:match('MAIN[AT]')) then + local role = groupFilter:match('MAIN([AT])') + if(role == 'T') then + unit = 'maintank' + else + unit = 'mainassist' + end + elseif(header:GetAttribute'showRaid') then + unit = 'raid' + elseif(header:GetAttribute'showParty') then + unit = 'party' + end + + local headerType = header:GetAttribute'oUF-headerType' + local suffix = frame:GetAttribute'unitsuffix' + if(unit and suffix) then + if(headerType == 'pet' and suffix == 'target') then + unit = unit .. headerType .. suffix + else + unit = unit .. suffix + end + elseif(unit and headerType == 'pet') then + unit = unit .. headerType + end + + frame:SetAttribute('*type1', 'target') + frame:SetAttribute('*type2', 'togglemenu') + frame:SetAttribute('toggleForVehicle', true) + frame:SetAttribute('oUF-guessUnit', unit) + end + + local body = header:GetAttribute'oUF-initialConfigFunction' + if(body) then + frame:Run(body, unit) + end + end + + header:CallMethod('styleFunction', self:GetName()) + + local clique = header:GetFrameRef("clickcast_header") + if(clique) then + clique:SetAttribute("clickcast_button", self) + clique:RunAttribute("clickcast_register") + end + ]] + + function oUF:SpawnHeader(overrideName, template, visibility, ...) + if(not style) then return error("Unable to create frame. No styles have been registered.") end + + template = (template or 'SecureGroupHeaderTemplate') + + local isPetHeader = template:match'PetHeader' + local name = overrideName or generateName(nil, ...) + local header = CreateFrame('Frame', name, oUF_PetBattleFrameHider, template) + + header:SetAttribute("template", "oUF_ClickCastUnitTemplate") + for i=1, select("#", ...), 2 do + local att, val = select(i, ...) + if(not att) then break end + header:SetAttribute(att, val) + end + + header.style = style + header.styleFunction = styleProxy + + -- Expose the header through oUF.headers. + table.insert(headers, header) + + -- We set it here so layouts can't directly override it. + header:SetAttribute('initialConfigFunction', initialConfigFunction) + header:SetAttribute('oUF-headerType', isPetHeader and 'pet' or 'group') + + if(Clique) then + SecureHandlerSetFrameRef(header, 'clickcast_header', Clique.header) + end + + if(header:GetAttribute'showParty') then + self:DisableBlizzard'party' + end + + if(visibility) then + local type, list = string.split(' ', visibility, 2) + if(list and type == 'custom') then + RegisterAttributeDriver(header, 'state-visibility', list) + else + local condition = getCondition(string.split(',', visibility)) + RegisterAttributeDriver(header, 'state-visibility', condition) + end + end + + return header + end +end + +function oUF:Spawn(unit, overrideName) + argcheck(unit, 2, 'string') + if(not style) then return error("Unable to create frame. No styles have been registered.") end + + unit = unit:lower() + + local name = overrideName or generateName(unit) + local object = CreateFrame("Button", name, oUF_PetBattleFrameHider, "SecureUnitButtonTemplate") + Private.UpdateUnits(object, unit) + + self:DisableBlizzard(unit) + walkObject(object, unit) + + object:SetAttribute("unit", unit) + RegisterUnitWatch(object) + + return object +end + +function oUF:AddElement(name, update, enable, disable) + argcheck(name, 2, 'string') + argcheck(update, 3, 'function', 'nil') + argcheck(enable, 4, 'function', 'nil') + argcheck(disable, 5, 'function', 'nil') + + if(elements[name]) then return error('Element [%s] is already registered.', name) end + elements[name] = { + update = update; + enable = enable; + disable = disable; + } +end + +oUF.version = _VERSION +oUF.objects = objects +oUF.headers = headers + +if(global) then + if(parent ~= 'oUF' and global == 'oUF') then + error("%s is doing it wrong and setting its global to oUF.", parent) + else + _G[global] = oUF + end +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/private.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/private.lua new file mode 100644 index 0000000..c73b873 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/private.lua @@ -0,0 +1,22 @@ +local parent, ns = ... +local Private = ns.oUF.Private + +function Private.argcheck(value, num, ...) + assert(type(num) == 'number', "Bad argument #2 to 'argcheck' (number expected, got "..type(num)..")") + + for i=1,select("#", ...) do + if type(value) == select(i, ...) then return end + end + + local types = strjoin(", ", ...) + local name = string.match(debugstack(2,2,0), ": in function [`<](.-)['>]") + error(("Bad argument #%d to '%s' (%s expected, got %s"):format(num, name, types, type(value)), 3) +end + +function Private.print(...) + print("|cff33ff99oUF:|r", ...) +end + +function Private.error(...) + Private.print("|cffff0000Error:|r "..string.format(...)) +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/units.lua b/SVUI_UnitFrames/libs/oUF_1.6.9/units.lua new file mode 100644 index 0000000..f90361a --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/units.lua @@ -0,0 +1,23 @@ +local parent, ns = ... +local oUF = ns.oUF +local Private = oUF.Private + +local enableTargetUpdate = Private.enableTargetUpdate + +-- Handles unit specific actions. +function oUF:HandleUnit(object, unit) + local unit = object.unit or unit + + if(unit == 'target') then + object:RegisterEvent('PLAYER_TARGET_CHANGED', object.UpdateAllElements) + elseif(unit == 'mouseover') then + object:RegisterEvent('UPDATE_MOUSEOVER_UNIT', object.UpdateAllElements) + elseif(unit == 'focus') then + object:RegisterEvent('PLAYER_FOCUS_CHANGED', object.UpdateAllElements) + elseif(unit:match'(boss)%d?$' == 'boss') then + object:RegisterEvent('INSTANCE_ENCOUNTER_ENGAGE_UNIT', object.UpdateAllElements, true) + object:RegisterEvent('UNIT_TARGETABLE_CHANGED', object.UpdateAllElements) + elseif(unit:match'%w+target') then + enableTargetUpdate(object) + end +end diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/utils/changelog b/SVUI_UnitFrames/libs/oUF_1.6.9/utils/changelog new file mode 100644 index 0000000..fdafa94 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/utils/changelog @@ -0,0 +1,84 @@ +#!/usr/bin/env lua + +local tags = {} +do + for tag in io.popen('git tag'):lines() do + local split = tag:gmatch('[^.]+') + local release, api, bugfix = split(), split(), split() or 0 + table.insert( + tags, + { + string = tag, + release = release, + api = api, + bugfix = bugfix, + } + ) + end + + table.sort(tags, function(a,b) + a = a.release * 1e4 + a.api * 100 + a.bugfix + b = b.release * 1e4 + b.api * 100 + b.bugfix + + return a > b + end) +end + +local generateLog = function(prevTag, currentTag) + local ti = table.insert + local sf = string.format + + local out = {} + + ti(out, sf('[b]Changes in %s:[/b]', currentTag)) + ti(out, '[list]') + + for line in io.popen(sf('git shortlog %s..%s', prevTag, currentTag)):lines() do + if(line:sub(1, 6) == ' ') then + local offset = line:match('() ', 7) + if(offset) then + line = line:sub(7, offset - 1) + else + line = line:sub(7) + end + + ti(out, sf(' [*] %s', line)) + elseif(#line == 0) then + ti(out, ' [/list]') + else + ti(out, sf(' [*][i]%s[/i]', line)) + ti(out, ' [list=1]') + end + end + + ti(out, '[/list]') + + local p = assert(io.popen(sf('git diff --shortstat %s..%s', prevTag, currentTag))) + local stat = p:read'*a' + p:close() + + ti(out, sf('[indent]%s[/indent]', stat:sub(2, -2))) + + return table.concat(out, '\n') +end + +local stop +local to = ... +if(to) then + for i=1, #tags do + if(tags[i].string == to) then + stop = i + 1 + end + end + + if(not stop) then stop = #tags end +else + stop = #tags +end + +for i=2, stop do + local current, prev = tags[i -1], tags[i] + print(generateLog(prev.string, current.string)) +end + +-- vim: set filetype=lua : diff --git a/SVUI_UnitFrames/libs/oUF_1.6.9/utils/docs b/SVUI_UnitFrames/libs/oUF_1.6.9/utils/docs new file mode 100644 index 0000000..662b1d3 --- /dev/null +++ b/SVUI_UnitFrames/libs/oUF_1.6.9/utils/docs @@ -0,0 +1,254 @@ +#!/usr/bin/env lua +-- docs +-- oUF documentation generator +-- +-- This is really just a quick and dirty way of generating documentation for +-- oUF[1]. The syntax is inspired by TomDoc[2], but a lot of the non-oUF and +-- non-Lua things aren't implemented. +-- +-- Why implement my own documentation generator? +-- It was mainly done because oUF is kind-of special, but also because the +-- available alternatives aren't good enough or have issues I can't workaround. +-- +-- Things that need fixing: +-- - No highlighting of Lua code. +-- - Doesn't validate that comments are documentation strings. +-- - Doesn't parse its own documentation header. +-- - Close to zero error handling. +-- +-- Usage +-- +-- docs [docs path] [file...] +-- +-- Links +-- +-- [1] https://github.com/haste/oUF +-- [2] http://tomdoc.org/ + +local out +local lines + +local tisf = function(fmt, ...) + table.insert(out, fmt:format(...)) +end + +local trim = function(str) + return str:match('^()%s*$') and '' or str:match('^%s*(.*%S)') +end + +local findNextEmpty = function(start, stop) + for i=start, stop or #lines do + if(lines[i] == '') then + return i + end + end +end + +local findNextHeader = function(offest) + for i=offest, #lines do + local pre, header, post = unpack(lines, i, i + 2) + -- Single lines without punctuation are headers. + if(pre == '' and post == '' and not header:match'%.') then + return i + 1 + end + end +end + +local findNextArguent = function(start, stop, padding, pattern) + for i=start, stop do + local match, pad = lines[i]:match(pattern) + if(match and pad == padding) then + return i + end + end +end + +local replaceMarkup = function(str) + return str + -- `in-line code` to <code>in-line code</code> + :gsub('`([^`]+)`', '<code>%1</code>') + -- [Link](http://example.com) to <a href="http://example.com">Link</a> + :gsub('%[([^%]]+)%]%(([^)]+)%)', '<a href="%2">%1</a>') +end + +local handleArguments = function(start, stop, pattern) + tisf('<dl>') + repeat + -- Tear out the argument name and offset of where the description begins. + local def, padding, offset = lines[start]:match(pattern) + tisf('<dt>%s</dt>', def) + + -- Insert the first line of the description. + tisf('<dd>') + tisf(lines[start]:sub(offset)) + + -- Find the next argument in the list or continue to the end of the + -- current section. + local nextarg = findNextArguent(start + 1, stop, padding, pattern) + nextarg = (nextarg or stop + 1) - 1 + for i=start + 1, nextarg do + tisf(trim(lines[i])) + end + tisf('</dd>') + + start = nextarg + 1 + until start > stop + tisf('</dl>') +end + +local handleExamples = function(start, stop) + -- An extra line gets added if we don't do this. + tisf('<pre><code>%s', lines[start]:sub(3)) + for i=start + 1, stop do + tisf(lines[i]:sub(3)) + end + tisf('</code></pre>') +end + +local handleParagraph = function(start, stop) + tisf('<p>') + for i=start, stop do + tisf(trim(lines[i])) + end + tisf('</p>') +end + +local handleSection = function(start, stop) + while(start) do + -- Find the next empty line or continue until the end of the section. + -- findNextEmpty() returns the position of the empty line, so we need to + -- subtract one from it. + local nextEmpty = findNextEmpty(start + 1, stop) + if(nextEmpty) then + nextEmpty = nextEmpty - 1 + else + nextEmpty = stop + end + + local line = lines[start] + if(not line) then + return + elseif(line:match('^%S+%s*%- ')) then + handleArguments(start, nextEmpty, '(%S+)%s*()%- ()') + elseif(line:sub(1, 2) == ' ') then + handleExamples(start, nextEmpty) + else + handleParagraph(start, nextEmpty) + end + + start = findNextEmpty(nextEmpty, stop) + if(start) then start = start + 1 end + end +end + +local generateDocs = function(str, level) + lines = {} + out = {} + + for line in str:gmatch('([^\n]*)\n') do + table.insert(lines, line:gsub('\t*', ''):sub(2)) + end + + -- The first line is always the main header. + tisf('<h%d>%s</h%d>', level, lines[1], level) + + -- Then comes the main description. + local offset = findNextHeader(1) + + -- Continue until two lines before the header or to the end of the comment. + if(offset) then + offset = offset - 2 + else + offset = #lines + end + + local init = findNextEmpty(1) + 1 + if(init > offset) then + init = 2 + end + + handleSection(init, offset) + + while(true) do + offset = findNextHeader(offset) + if(not offset) then break end + + -- Every section has a header. + tisf('<h%d>%s</h%d>', level + 1, lines[offset], level + 1) + + -- Find out the size of the section. + local start = findNextEmpty(offset) + 1 + if(not lines[start]) then + -- There's no section here, only a headline. + break + end + + local stop + local nextHeader = findNextHeader(start) + if(nextHeader) then + stop = nextHeader - 2 + else + local nextEmpty = findNextEmpty(start) + if(nextEmpty) then + stop = nextEmpty - 1 + else + stop = #lines + end + end + + handleSection(start, stop) + offset = stop + 1 + end + + return table.concat(out, '\n') +end + +local handleFile = function(path) + local file = io.open(path, 'r') + local content = file:read'*a' + file:close() + + local out = {} + local init = 1 + repeat + local _, comStart, depth = content:find('%-%-%[(=*)%[ ', init) + if(comStart) then + local comEnd = content:find('%]' .. depth .. '%]', comStart) + local comment = content:sub(comStart, comEnd - 1) + + -- Convert markup to html. + comment = replaceMarkup(comment) + + -- The first comment uses h1 and h2, while the subsequent ones uses h3 + -- and h4. + local level = init == 1 and 1 or 3 + table.insert(out, generateDocs(comment, init == 1 and 1 or 3)) + + init = comEnd + end + until not comStart + + return table.concat(out, '\n') +end + +local destination = (...) +for i=2, select('#', ...) do + local file = select(i, ...) + local path, filename = file:match('(.+)/(.+)$') + + if(path:sub(1,3) == '../') then + path = path:sub(4) + end + + if(#path == 0) then path = nil end + filename = filename:gsub('lua', 'html') + + local doc = handleFile(file) + if(doc) then + local dfPath = string.format('%s/%s', destination, path or '') + os.execute(string.format('mkdir -p %s', dfPath)) + local docFile = io.open(string.format('%s/%s', dfPath, filename), 'w+') + docFile:write(doc) + docFile:close() + end +end