Files
coa-leatrix-plus/Leatrix_Plus_Library.lua
T
Sattva be0b158b4e fix and mod Automate Gossip, delete whole lib code
had to use some LibCompat assistance, to retrieve UnitGUID
started to populate Quest NPC IDs to automate gossip without alt-click
also removed whole Leatrix Plus lib as it's conflicting with another addons
2023-05-21 03:39:39 +03:00

1678 lines
58 KiB
Lua

-- -- L00: Leatrix Plus Library
-- ----------------------------------------------------------------------
-- -- LibDBIcon 10.0.1:
-- -- 11: LibStub: (?s)-- LibStubStart\R?\K.*?(?=-- LibStubEnd)
-- -- 12: LibCallbackHandler: (?s)-- CallbackStart\R?\K.*?(?=-- CallbackEnd)
-- -- 13: LibDataBroker: (?s)-- DataBrokerStart\R?\K.*?(?=-- DataBrokerEnd)
-- -- 14: LibDBIcon: (?s)-- LibDBIconStart\R?\K.*?(?=-- LibDBIconEnd)
-- -- LibChatAnims 10.0.1:
-- -- 15: LibChatAnims: (?s)-- LibChatAnimsStart\R?\K.*?(?=-- LibChatAnimsEnd)
-- -- LibCandyBar 10.0.1:
-- -- 16: LibCandyBar: (?s)-- LibCandyBarStart\R?\K.*?(?=-- LibCandyBarEnd)
-- local void, Leatrix_Plus = ...
-- ----------------------------------------------------------------------
-- -- L11: LibDBIcon: LibStub
-- ----------------------------------------------------------------------
-- local function LeaLibStub()
-- -- LibStubStart
-- -- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $
-- -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- -- LibStub is hereby placed in the Public Domain
-- -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
-- local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
-- local LibStub = _G[LIBSTUB_MAJOR]
-- -- Check to see is this version of the stub is obsolete
-- if not LibStub or LibStub.minor < LIBSTUB_MINOR then
-- LibStub = LibStub or {libs = {}, minors = {} }
-- _G[LIBSTUB_MAJOR] = LibStub
-- LibStub.minor = LIBSTUB_MINOR
-- -- LibStub:NewLibrary(major, minor)
-- -- major (string) - the major version of the library
-- -- minor (string or number ) - the minor version of the library
-- --
-- -- returns nil if a newer or same version of the lib is already present
-- -- returns empty library object or old library object if upgrade is needed
-- function LibStub:NewLibrary(major, minor)
-- assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
-- minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
-- local oldminor = self.minors[major]
-- if oldminor and oldminor >= minor then return nil end
-- self.minors[major], self.libs[major] = minor, self.libs[major] or {}
-- return self.libs[major], oldminor
-- end
-- -- LibStub:GetLibrary(major, [silent])
-- -- major (string) - the major version of the library
-- -- silent (boolean) - if true, library is optional, silently return nil if its not found
-- --
-- -- throws an error if the library can not be found (except silent is set)
-- -- returns the library object if found
-- function LibStub:GetLibrary(major, silent)
-- if not self.libs[major] and not silent then
-- error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
-- end
-- return self.libs[major], self.minors[major]
-- end
-- -- LibStub:IterateLibraries()
-- --
-- -- Returns an iterator for the currently registered libraries
-- function LibStub:IterateLibraries()
-- return pairs(self.libs)
-- end
-- setmetatable(LibStub, { __call = LibStub.GetLibrary })
-- end
-- -- LibStubEnd
-- end
-- LeaLibStub()
-- ----------------------------------------------------------------------
-- -- L12: LibDBIcon: CallbackHandler
-- ----------------------------------------------------------------------
-- local function LeaCallbackHandler()
-- -- CallbackStart
-- --[[ $Id: CallbackHandler-1.0.lua 26 2022-12-12 15:09:39Z nevcairiel $ ]]
-- local MAJOR, MINOR = "CallbackHandler-1.0", 8
-- local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
-- if not CallbackHandler then return end -- No upgrade needed
-- local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- -- Lua APIs
-- local securecallfunction, error = securecallfunction, error
-- local setmetatable, rawget = setmetatable, rawget
-- local next, select, pairs, type, tostring = next, select, pairs, type, tostring
-- local function Dispatch(handlers, ...)
-- local index, method = next(handlers)
-- if not method then return end
-- repeat
-- securecallfunction(method, ...)
-- index, method = next(handlers, index)
-- until not method
-- end
-- --------------------------------------------------------------------------
-- -- CallbackHandler:New
-- --
-- -- target - target object to embed public APIs in
-- -- RegisterName - name of the callback registration API, default "RegisterCallback"
-- -- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- -- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
-- function CallbackHandler.New(_self, target, RegisterName, UnregisterName, UnregisterAllName)
-- RegisterName = RegisterName or "RegisterCallback"
-- UnregisterName = UnregisterName or "UnregisterCallback"
-- if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
-- UnregisterAllName = "UnregisterAllCallbacks"
-- end
-- -- we declare all objects and exported APIs inside this closure to quickly gain access
-- -- to e.g. function names, the "target" parameter, etc
-- -- Create the registry object
-- local events = setmetatable({}, meta)
-- local registry = { recurse=0, events=events }
-- -- registry:Fire() - fires the given event/message into the registry
-- function registry:Fire(eventname, ...)
-- if not rawget(events, eventname) or not next(events[eventname]) then return end
-- local oldrecurse = registry.recurse
-- registry.recurse = oldrecurse + 1
-- Dispatch(events[eventname], eventname, ...)
-- registry.recurse = oldrecurse
-- if registry.insertQueue and oldrecurse==0 then
-- -- Something in one of our callbacks wanted to register more callbacks; they got queued
-- for event,callbacks in pairs(registry.insertQueue) do
-- local first = not rawget(events, event) or not next(events[event]) -- test for empty before. not test for one member after. that one member may have been overwritten.
-- for object,func in pairs(callbacks) do
-- events[event][object] = func
-- -- fire OnUsed callback?
-- if first and registry.OnUsed then
-- registry.OnUsed(registry, target, event)
-- first = nil
-- end
-- end
-- end
-- registry.insertQueue = nil
-- end
-- end
-- -- Registration of a callback, handles:
-- -- self["method"], leads to self["method"](self, ...)
-- -- self with function ref, leads to functionref(...)
-- -- "addonId" (instead of self) with function ref, leads to functionref(...)
-- -- all with an optional arg, which, if present, gets passed as first argument (after self if present)
-- target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
-- if type(eventname) ~= "string" then
-- error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
-- end
-- method = method or eventname
-- local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
-- if type(method) ~= "string" and type(method) ~= "function" then
-- error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
-- end
-- local regfunc
-- if type(method) == "string" then
-- -- self["method"] calling style
-- if type(self) ~= "table" then
-- error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
-- elseif self==target then
-- error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
-- elseif type(self[method]) ~= "function" then
-- error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
-- end
-- if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
-- local arg=select(1,...)
-- regfunc = function(...) self[method](self,arg,...) end
-- else
-- regfunc = function(...) self[method](self,...) end
-- end
-- else
-- -- function ref with self=object or self="addonId" or self=thread
-- if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
-- error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
-- end
-- if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
-- local arg=select(1,...)
-- regfunc = function(...) method(arg,...) end
-- else
-- regfunc = method
-- end
-- end
-- if events[eventname][self] or registry.recurse<1 then
-- -- if registry.recurse<1 then
-- -- we're overwriting an existing entry, or not currently recursing. just set it.
-- events[eventname][self] = regfunc
-- -- fire OnUsed callback?
-- if registry.OnUsed and first then
-- registry.OnUsed(registry, target, eventname)
-- end
-- else
-- -- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
-- registry.insertQueue = registry.insertQueue or setmetatable({},meta)
-- registry.insertQueue[eventname][self] = regfunc
-- end
-- end
-- -- Unregister a callback
-- target[UnregisterName] = function(self, eventname)
-- if not self or self==target then
-- error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
-- end
-- if type(eventname) ~= "string" then
-- error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
-- end
-- if rawget(events, eventname) and events[eventname][self] then
-- events[eventname][self] = nil
-- -- Fire OnUnused callback?
-- if registry.OnUnused and not next(events[eventname]) then
-- registry.OnUnused(registry, target, eventname)
-- end
-- end
-- if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
-- registry.insertQueue[eventname][self] = nil
-- end
-- end
-- -- OPTIONAL: Unregister all callbacks for given selfs/addonIds
-- if UnregisterAllName then
-- target[UnregisterAllName] = function(...)
-- if select("#",...)<1 then
-- error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
-- end
-- if select("#",...)==1 and ...==target then
-- error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
-- end
-- for i=1,select("#",...) do
-- local self = select(i,...)
-- if registry.insertQueue then
-- for eventname, callbacks in pairs(registry.insertQueue) do
-- if callbacks[self] then
-- callbacks[self] = nil
-- end
-- end
-- end
-- for eventname, callbacks in pairs(events) do
-- if callbacks[self] then
-- callbacks[self] = nil
-- -- Fire OnUnused callback?
-- if registry.OnUnused and not next(callbacks) then
-- registry.OnUnused(registry, target, eventname)
-- end
-- end
-- end
-- end
-- end
-- end
-- return registry
-- end
-- -- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- -- try to upgrade old implicit embeds since the system is selfcontained and
-- -- relies on closures to work.
-- -- CallbackEnd
-- end
-- LeaCallbackHandler()
-- ----------------------------------------------------------------------
-- -- L13: LibDBIcon: LibDataBroker
-- ----------------------------------------------------------------------
-- local function LeaDataBroker()
-- -- DataBrokerStart
-- assert(LibStub, "LibDataBroker-1.1 requires LibStub")
-- assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
-- local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
-- if not lib then return end
-- oldminor = oldminor or 0
-- lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
-- lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
-- local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
-- if oldminor < 2 then
-- lib.domt = {
-- __metatable = "access denied",
-- __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
-- }
-- end
-- if oldminor < 3 then
-- lib.domt.__newindex = function(self, key, value)
-- if not attributestorage[self] then attributestorage[self] = {} end
-- if attributestorage[self][key] == value then return end
-- attributestorage[self][key] = value
-- local name = namestorage[self]
-- if not name then return end
-- callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
-- callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
-- callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
-- callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
-- end
-- end
-- if oldminor < 2 then
-- function lib:NewDataObject(name, dataobj)
-- if self.proxystorage[name] then return end
-- if dataobj then
-- assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
-- self.attributestorage[dataobj] = {}
-- for i,v in pairs(dataobj) do
-- self.attributestorage[dataobj][i] = v
-- dataobj[i] = nil
-- end
-- end
-- dataobj = setmetatable(dataobj or {}, self.domt)
-- self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
-- self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
-- return dataobj
-- end
-- end
-- if oldminor < 1 then
-- function lib:DataObjectIterator()
-- return pairs(self.proxystorage)
-- end
-- function lib:GetDataObjectByName(dataobjectname)
-- return self.proxystorage[dataobjectname]
-- end
-- function lib:GetNameByDataObject(dataobject)
-- return self.namestorage[dataobject]
-- end
-- end
-- if oldminor < 4 then
-- local next = pairs(attributestorage)
-- function lib:pairs(dataobject_or_name)
-- local t = type(dataobject_or_name)
-- assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
-- local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
-- assert(attributestorage[dataobj], "Data object not found")
-- return next, attributestorage[dataobj], nil
-- end
-- local ipairs_iter = ipairs(attributestorage)
-- function lib:ipairs(dataobject_or_name)
-- local t = type(dataobject_or_name)
-- assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
-- local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
-- assert(attributestorage[dataobj], "Data object not found")
-- return ipairs_iter, attributestorage[dataobj], 0
-- end
-- end
-- -- DataBrokerEnd
-- end
-- LeaDataBroker()
-- ----------------------------------------------------------------------
-- -- L14: LibDBIcon: LibDBIcon
-- ----------------------------------------------------------------------
-- local function LeaLibDBIcon()
-- -- LibDBIconStart
-- --@curseforge-project-slug: libdbicon-1-0@
-- -----------------------------------------------------------------------
-- -- LibDBIcon-1.0
-- --
-- -- Allows addons to easily create a lightweight minimap icon as an alternative to heavier LDB displays.
-- --
-- local DBICON10 = "LibDBIcon-1.0"
-- local DBICON10_MINOR = 45 -- Bump on changes
-- if not LibStub then error(DBICON10 .. " requires LibStub.") end
-- local ldb = LibStub("LibDataBroker-1.1", true)
-- if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
-- local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
-- if not lib then return end
-- lib.objects = lib.objects or {}
-- lib.callbackRegistered = lib.callbackRegistered or nil
-- lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
-- lib.notCreated = lib.notCreated or {}
-- lib.radius = lib.radius or 5
-- local next, Minimap, CreateFrame = next, Minimap, CreateFrame
-- lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate")
-- local isDraggingButton = false
-- function lib:IconCallback(event, name, key, value)
-- if lib.objects[name] then
-- if key == "icon" then
-- lib.objects[name].icon:SetTexture(value)
-- elseif key == "iconCoords" then
-- lib.objects[name].icon:UpdateCoord()
-- elseif key == "iconR" then
-- local _, g, b = lib.objects[name].icon:GetVertexColor()
-- lib.objects[name].icon:SetVertexColor(value, g, b)
-- elseif key == "iconG" then
-- local r, _, b = lib.objects[name].icon:GetVertexColor()
-- lib.objects[name].icon:SetVertexColor(r, value, b)
-- elseif key == "iconB" then
-- local r, g = lib.objects[name].icon:GetVertexColor()
-- lib.objects[name].icon:SetVertexColor(r, g, value)
-- end
-- end
-- end
-- if not lib.callbackRegistered then
-- ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
-- ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
-- ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconR", "IconCallback")
-- ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconG", "IconCallback")
-- ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconB", "IconCallback")
-- lib.callbackRegistered = true
-- end
-- local function getAnchors(frame)
-- local x, y = frame:GetCenter()
-- if not x or not y then return "CENTER" end
-- local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
-- local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
-- return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
-- end
-- local function onEnter(self)
-- if isDraggingButton then return end
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Stop()
-- button:SetAlpha(1)
-- end
-- end
-- local obj = self.dataObject
-- if obj.OnTooltipShow then
-- lib.tooltip:SetOwner(self, "ANCHOR_NONE")
-- lib.tooltip:SetPoint(getAnchors(self))
-- obj.OnTooltipShow(lib.tooltip)
-- lib.tooltip:Show()
-- elseif obj.OnEnter then
-- obj.OnEnter(self)
-- end
-- end
-- local function onLeave(self)
-- lib.tooltip:Hide()
-- if not isDraggingButton then
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Play()
-- end
-- end
-- end
-- local obj = self.dataObject
-- if obj.OnLeave then
-- obj.OnLeave(self)
-- end
-- end
-- --------------------------------------------------------------------------------
-- local onDragStart, updatePosition
-- do
-- local minimapShapes = {
-- ["ROUND"] = {true, true, true, true},
-- ["SQUARE"] = {false, false, false, false},
-- ["CORNER-TOPLEFT"] = {false, false, false, true},
-- ["CORNER-TOPRIGHT"] = {false, false, true, false},
-- ["CORNER-BOTTOMLEFT"] = {false, true, false, false},
-- ["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
-- ["SIDE-LEFT"] = {false, true, false, true},
-- ["SIDE-RIGHT"] = {true, false, true, false},
-- ["SIDE-TOP"] = {false, false, true, true},
-- ["SIDE-BOTTOM"] = {true, true, false, false},
-- ["TRICORNER-TOPLEFT"] = {false, true, true, true},
-- ["TRICORNER-TOPRIGHT"] = {true, false, true, true},
-- ["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
-- ["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
-- }
-- local rad, cos, sin, sqrt, max, min = math.rad, math.cos, math.sin, math.sqrt, math.max, math.min
-- function updatePosition(button, position)
-- local angle = rad(position or 225)
-- local x, y, q = cos(angle), sin(angle), 1
-- if x < 0 then q = q + 1 end
-- if y > 0 then q = q + 2 end
-- local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
-- local quadTable = minimapShapes[minimapShape]
-- local w = (Minimap:GetWidth() / 2) + lib.radius
-- local h = (Minimap:GetHeight() / 2) + lib.radius
-- if quadTable[q] then
-- x, y = x*w, y*h
-- else
-- local diagRadiusW = sqrt(2*(w)^2)-10
-- local diagRadiusH = sqrt(2*(h)^2)-10
-- x = max(-w, min(x*diagRadiusW, w))
-- y = max(-h, min(y*diagRadiusH, h))
-- end
-- button:SetPoint("CENTER", Minimap, "CENTER", x, y)
-- end
-- end
-- local function onClick(self, b)
-- if self.dataObject.OnClick then
-- self.dataObject.OnClick(self, b)
-- end
-- end
-- local function onMouseDown(self)
-- self.isMouseDown = true
-- self.icon:UpdateCoord()
-- end
-- local function onMouseUp(self)
-- self.isMouseDown = false
-- self.icon:UpdateCoord()
-- end
-- do
-- local deg, atan2 = math.deg, math.atan2
-- local function onUpdate(self)
-- local mx, my = Minimap:GetCenter()
-- local px, py = GetCursorPosition()
-- local scale = Minimap:GetEffectiveScale()
-- px, py = px / scale, py / scale
-- local pos = 225
-- if self.db then
-- pos = deg(atan2(py - my, px - mx)) % 360
-- self.db.minimapPos = pos
-- else
-- pos = deg(atan2(py - my, px - mx)) % 360
-- self.minimapPos = pos
-- end
-- updatePosition(self, pos)
-- end
-- function onDragStart(self)
-- self:LockHighlight()
-- self.isMouseDown = true
-- self.icon:UpdateCoord()
-- self:SetScript("OnUpdate", onUpdate)
-- isDraggingButton = true
-- lib.tooltip:Hide()
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Stop()
-- button:SetAlpha(1)
-- end
-- end
-- end
-- end
-- local function onDragStop(self)
-- self:SetScript("OnUpdate", nil)
-- self.isMouseDown = false
-- self.icon:UpdateCoord()
-- self:UnlockHighlight()
-- isDraggingButton = false
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Play()
-- end
-- end
-- end
-- local defaultCoords = {0, 1, 0, 1}
-- local function updateCoord(self)
-- local coords = self:GetParent().dataObject.iconCoords or defaultCoords
-- local deltaX, deltaY = 0, 0
-- if not self:GetParent().isMouseDown then
-- deltaX = (coords[2] - coords[1]) * 0.05
-- deltaY = (coords[4] - coords[3]) * 0.05
-- end
-- self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
-- end
-- local function createButton(name, object, db)
-- local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
-- button.dataObject = object
-- button.db = db
-- button:SetFrameStrata("MEDIUM")
-- -- button:SetFixedFrameStrata(true)
-- button:SetFrameLevel(8)
-- -- button:SetFixedFrameLevel(true)
-- button:SetSize(31, 31)
-- button:RegisterForClicks("anyUp")
-- button:RegisterForDrag("LeftButton")
-- button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight"
-- if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
-- local overlay = button:CreateTexture(nil, "OVERLAY")
-- overlay:SetSize(50, 50)
-- overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder"
-- overlay:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0)
-- local background = button:CreateTexture(nil, "BACKGROUND")
-- background:SetSize(24, 24)
-- background:SetTexture(136467) --"Interface\\Minimap\\UI-Minimap-Background"
-- background:SetPoint("CENTER", button, "CENTER", 0, 1)
-- local icon = button:CreateTexture(nil, "ARTWORK")
-- icon:SetSize(18, 18)
-- icon:SetTexture(object.icon)
-- icon:SetPoint("CENTER", button, "CENTER", 0, 1)
-- button.icon = icon
-- else
-- local overlay = button:CreateTexture(nil, "OVERLAY")
-- overlay:SetSize(53, 53)
-- overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder"
-- overlay:SetPoint("TOPLEFT")
-- local background = button:CreateTexture(nil, "BACKGROUND")
-- background:SetSize(20, 20)
-- background:SetTexture(136467) --"Interface\\Minimap\\UI-Minimap-Background"
-- background:SetPoint("TOPLEFT", 7, -5)
-- local icon = button:CreateTexture(nil, "ARTWORK")
-- icon:SetSize(17, 17)
-- icon:SetTexture(object.icon)
-- icon:SetPoint("TOPLEFT", 7, -6)
-- button.icon = icon
-- end
-- button.isMouseDown = false
-- local r, g, b = button.icon:GetVertexColor()
-- button.icon:SetVertexColor(object.iconR or r, object.iconG or g, object.iconB or b)
-- button.icon.UpdateCoord = updateCoord
-- button.icon:UpdateCoord()
-- button:SetScript("OnEnter", onEnter)
-- button:SetScript("OnLeave", onLeave)
-- button:SetScript("OnClick", onClick)
-- if not db or not db.lock then
-- button:SetScript("OnDragStart", onDragStart)
-- button:SetScript("OnDragStop", onDragStop)
-- end
-- button:SetScript("OnMouseDown", onMouseDown)
-- button:SetScript("OnMouseUp", onMouseUp)
-- button.fadeOut = button:CreateAnimationGroup()
-- local animOut = button.fadeOut:CreateAnimation("Alpha")
-- -- animOut:SetOrder(1)
-- -- animOut:SetDuration(0.2)
-- -- animOut:SetFromAlpha(1)
-- -- animOut:SetToAlpha(0)
-- -- animOut:SetStartDelay(1)
-- -- button.fadeOut:SetToFinalAlpha(true)
-- lib.objects[name] = button
-- if lib.loggedIn then
-- updatePosition(button, db and db.minimapPos)
-- if not db or not db.hide then
-- button:Show()
-- else
-- button:Hide()
-- end
-- end
-- lib.callbacks:Fire("LibDBIcon_IconCreated", button, name) -- Fire 'Icon Created' callback
-- end
-- -- We could use a metatable.__index on lib.objects, but then we'd create
-- -- the icons when checking things like :IsRegistered, which is not necessary.
-- local function check(name)
-- if lib.notCreated[name] then
-- createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
-- lib.notCreated[name] = nil
-- end
-- end
-- -- Wait a bit with the initial positioning to let any GetMinimapShape addons
-- -- load up.
-- if not lib.loggedIn then
-- local f = CreateFrame("Frame")
-- f:SetScript("OnEvent", function(f)
-- for _, button in next, lib.objects do
-- updatePosition(button, button.db and button.db.minimapPos)
-- if not button.db or not button.db.hide then
-- button:Show()
-- else
-- button:Hide()
-- end
-- end
-- lib.loggedIn = true
-- f:SetScript("OnEvent", nil)
-- end)
-- f:RegisterEvent("PLAYER_LOGIN")
-- end
-- local function getDatabase(name)
-- return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
-- end
-- function lib:Register(name, object, db)
-- if not object.icon then error("Can't register LDB objects without icons set!") end
-- if lib.objects[name] or lib.notCreated[name] then error(DBICON10.. ": Object '".. name .."' is already registered.") end
-- if not db or not db.hide then
-- createButton(name, object, db)
-- else
-- lib.notCreated[name] = {object, db}
-- end
-- end
-- function lib:Lock(name)
-- if not lib:IsRegistered(name) then return end
-- if lib.objects[name] then
-- lib.objects[name]:SetScript("OnDragStart", nil)
-- lib.objects[name]:SetScript("OnDragStop", nil)
-- end
-- local db = getDatabase(name)
-- if db then
-- db.lock = true
-- end
-- end
-- function lib:Unlock(name)
-- if not lib:IsRegistered(name) then return end
-- if lib.objects[name] then
-- lib.objects[name]:SetScript("OnDragStart", onDragStart)
-- lib.objects[name]:SetScript("OnDragStop", onDragStop)
-- end
-- local db = getDatabase(name)
-- if db then
-- db.lock = nil
-- end
-- end
-- function lib:Hide(name)
-- if not lib.objects[name] then return end
-- lib.objects[name]:Hide()
-- end
-- function lib:Show(name)
-- check(name)
-- local button = lib.objects[name]
-- if button then
-- button:Show()
-- updatePosition(button, button.db and button.db.minimapPos or button.minimapPos)
-- end
-- end
-- function lib:IsRegistered(name)
-- return (lib.objects[name] or lib.notCreated[name]) and true or false
-- end
-- function lib:Refresh(name, db)
-- check(name)
-- local button = lib.objects[name]
-- if db then
-- button.db = db
-- end
-- updatePosition(button, button.db and button.db.minimapPos or button.minimapPos)
-- if not button.db or not button.db.hide then
-- button:Show()
-- else
-- button:Hide()
-- end
-- if not button.db or not button.db.lock then
-- button:SetScript("OnDragStart", onDragStart)
-- button:SetScript("OnDragStop", onDragStop)
-- else
-- button:SetScript("OnDragStart", nil)
-- button:SetScript("OnDragStop", nil)
-- end
-- end
-- function lib:GetMinimapButton(name)
-- return lib.objects[name]
-- end
-- do
-- local function OnMinimapEnter()
-- if isDraggingButton then return end
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Stop()
-- button:SetAlpha(1)
-- end
-- end
-- end
-- local function OnMinimapLeave()
-- if isDraggingButton then return end
-- for _, button in next, lib.objects do
-- if button.showOnMouseover then
-- button.fadeOut:Play()
-- end
-- end
-- end
-- Minimap:HookScript("OnEnter", OnMinimapEnter)
-- Minimap:HookScript("OnLeave", OnMinimapLeave)
-- function lib:ShowOnEnter(name, value)
-- local button = lib.objects[name]
-- if button then
-- if value then
-- button.showOnMouseover = true
-- button.fadeOut:Stop()
-- button:SetAlpha(0)
-- else
-- button.showOnMouseover = false
-- button.fadeOut:Stop()
-- button:SetAlpha(1)
-- end
-- end
-- end
-- end
-- function lib:GetButtonList()
-- local t = {}
-- for name in next, lib.objects do
-- t[#t+1] = name
-- end
-- return t
-- end
-- function lib:SetButtonRadius(radius)
-- if type(radius) == "number" then
-- lib.radius = radius
-- for _, button in next, lib.objects do
-- updatePosition(button, button.db and button.db.minimapPos or button.minimapPos)
-- end
-- end
-- end
-- function lib:SetButtonToPosition(button, position)
-- updatePosition(lib.objects[button] or button, position)
-- end
-- -- Upgrade!
-- for name, button in next, lib.objects do
-- local db = getDatabase(name)
-- if not db or not db.lock then
-- button:SetScript("OnDragStart", onDragStart)
-- button:SetScript("OnDragStop", onDragStop)
-- end
-- button:SetScript("OnEnter", onEnter)
-- button:SetScript("OnLeave", onLeave)
-- button:SetScript("OnClick", onClick)
-- button:SetScript("OnMouseDown", onMouseDown)
-- button:SetScript("OnMouseUp", onMouseUp)
-- if not button.fadeOut then -- Upgrade to 39
-- button.fadeOut = button:CreateAnimationGroup()
-- local animOut = button.fadeOut:CreateAnimation("Alpha")
-- animOut:SetOrder(1)
-- animOut:SetDuration(0.2)
-- animOut:SetFromAlpha(1)
-- animOut:SetToAlpha(0)
-- animOut:SetStartDelay(1)
-- button.fadeOut:SetToFinalAlpha(true)
-- end
-- end
-- lib:SetButtonRadius(lib.radius) -- Upgrade to 40
-- -- LibDBIconEnd
-- end
-- -- LeaLibDBIcon() -- disabled in 3.3.5, was causing red things
-- ----------------------------------------------------------------------
-- -- L15: LibChatAnims (load on demand)
-- ----------------------------------------------------------------------
-- function Leatrix_Plus:LeaPlusLCA()
-- -- LibChatAnimsStart
-- --@curseforge-project-slug: libchatanims@
-- local MAJOR, MINOR = "LibChatAnims", 4 -- Bump minor on changes
-- local LCA = LibStub:NewLibrary(MAJOR, MINOR)
-- if not LCA then return end -- No upgrade needed
-- LCA.animations = LCA.animations or {} -- Animation storage
-- LCA.alerting = LCA.alerting or {} -- Chat tab alerting storage
-- local anims = LCA.animations
-- local alerting = LCA.alerting
-- function LCA:IsAlerting(tab)
-- if alerting[tab] then
-- return true
-- end
-- end
-- ----------------------------------------------------
-- -- Note, most of this code is simply replicated from
-- -- Blizzard's FloatingChatFrame.lua file.
-- -- The only real changes are the creation and use
-- -- of animations vs the use of UIFrameFlash.
-- --
-- --FCFDockOverflowButton_UpdatePulseState = function(self)
-- -- local dock = self:GetParent()
-- -- local shouldPulse = false
-- -- for _, chatFrame in pairs(FCFDock_GetChatFrames(dock)) do
-- -- local chatTab = _G[chatFrame:GetName().."Tab"]
-- -- if ( not chatFrame.isStaticDocked and chatTab.alerting) then
-- -- -- Make sure the rects are valid. (Not always the case when resizing the WoW client
-- -- if ( not chatTab:GetRight() or not dock.scrollFrame:GetRight() ) then
-- -- return false
-- -- end
-- -- -- Check if it's off the screen.
-- -- local DELTA = 3 -- Chosen through experimentation
-- -- if ( chatTab:GetRight() < (dock.scrollFrame:GetLeft() + DELTA) or chatTab:GetLeft() > (dock.scrollFrame:GetRight() - DELTA) ) then
-- -- shouldPulse = true
-- -- break
-- -- end
-- -- end
-- -- end
-- --
-- -- local tex = self:GetHighlightTexture()
-- -- if shouldPulse then
-- -- if not anims[tex] then
-- -- anims[tex] = tex:CreateAnimationGroup()
-- --
-- -- local fade1 = anims[tex]:CreateAnimation("Alpha")
-- -- fade1:SetDuration(1)
-- -- fade1:SetFromAlpha(0)
-- -- fade1:SetToAlpha(1)
-- -- fade1:SetOrder(1)
-- --
-- -- local fade2 = anims[tex]:CreateAnimation("Alpha")
-- -- fade2:SetDuration(1)
-- -- fade2:SetFromAlpha(1)
-- -- fade2:SetToAlpha(0)
-- -- fade2:SetOrder(2)
-- -- end
-- -- tex:Show()
-- -- tex:SetAlpha(0)
-- -- anims[tex]:SetLooping("REPEAT")
-- -- anims[tex]:Play()
-- --
-- -- self:LockHighlight()
-- -- self.alerting = true
-- -- else
-- -- if anims[tex] then
-- -- anims[tex]:Stop()
-- -- end
-- -- self:UnlockHighlight()
-- -- tex:SetAlpha(1)
-- -- tex:Show()
-- -- self.alerting = false
-- -- end
-- --
-- -- if self.list:IsShown() then
-- -- FCFDockOverflowList_Update(self.list, dock)
-- -- end
-- -- return true
-- --end
-- --FCFDockOverflowListButton_SetValue = function(button, chatFrame)
-- -- local chatTab = _G[chatFrame:GetName().."Tab"]
-- -- button.chatFrame = chatFrame
-- -- button:SetText(chatFrame.name)
-- --
-- -- local colorTable = chatTab.selectedColorTable or DEFAULT_TAB_SELECTED_COLOR_TABLE
-- --
-- -- if chatTab.selectedColorTable then
-- -- button:GetFontString():SetTextColor(colorTable.r, colorTable.g, colorTable.b)
-- -- else
-- -- button:GetFontString():SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
-- -- end
-- --
-- -- button.glow:SetVertexColor(colorTable.r, colorTable.g, colorTable.b)
-- --
-- -- if chatTab.conversationIcon then
-- -- button.conversationIcon:SetVertexColor(colorTable.r, colorTable.g, colorTable.b)
-- -- button.conversationIcon:Show()
-- -- else
-- -- button.conversationIcon:Hide()
-- -- end
-- --
-- -- if chatTab.alerting then
-- -- button.alerting = true
-- -- if not anims[button.glow] then
-- -- anims[button.glow] = button.glow:CreateAnimationGroup()
-- --
-- -- local fade1 = anims[button.glow]:CreateAnimation("Alpha")
-- -- fade1:SetDuration(1)
-- -- fade1:SetFromAlpha(0)
-- -- fade1:SetToAlpha(1)
-- -- fade1:SetOrder(1)
-- --
-- -- local fade2 = anims[button.glow]:CreateAnimation("Alpha")
-- -- fade2:SetDuration(1)
-- -- fade2:SetFromAlpha(1)
-- -- fade2:SetToAlpha(0)
-- -- fade2:SetOrder(2)
-- -- end
-- -- button.glow:Show()
-- -- button.glow:SetAlpha(0)
-- -- anims[button.glow]:SetLooping("REPEAT")
-- -- anims[button.glow]:Play()
-- -- else
-- -- button.alerting = false
-- -- if anims[button.glow] then
-- -- anims[button.glow]:Stop()
-- -- end
-- -- button.glow:Hide()
-- -- end
-- -- button:Show()
-- --end
-- FCF_StartAlertFlash = function(chatFrame)
-- local chatTab = _G[chatFrame:GetName().."Tab"]
-- if chatFrame.minFrame then
-- if not anims[chatFrame.minFrame] then
-- anims[chatFrame.minFrame] = chatFrame.minFrame.glow:CreateAnimationGroup()
-- local fade1 = anims[chatFrame.minFrame]:CreateAnimation("Alpha")
-- fade1:SetDuration(1)
-- fade1:SetFromAlpha(0)
-- fade1:SetToAlpha(1)
-- fade1:SetOrder(1)
-- local fade2 = anims[chatFrame.minFrame]:CreateAnimation("Alpha")
-- fade2:SetDuration(1)
-- fade2:SetFromAlpha(1)
-- fade2:SetToAlpha(0)
-- fade2:SetOrder(2)
-- end
-- chatFrame.minFrame.glow:Show()
-- chatFrame.minFrame.glow:SetAlpha(0)
-- anims[chatFrame.minFrame]:SetLooping("REPEAT")
-- anims[chatFrame.minFrame]:Play()
-- --chatFrame.minFrame.alerting = true
-- alerting[chatFrame.minFrame] = true
-- end
-- if not anims[chatTab.glow] then
-- anims[chatTab.glow] = chatTab.glow:CreateAnimationGroup()
-- local fade1 = anims[chatTab.glow]:CreateAnimation("Alpha")
-- fade1:SetDuration(1)
-- fade1:SetFromAlpha(0)
-- fade1:SetToAlpha(1)
-- fade1:SetOrder(1)
-- local fade2 = anims[chatTab.glow]:CreateAnimation("Alpha")
-- fade2:SetDuration(1)
-- fade2:SetFromAlpha(1)
-- fade2:SetToAlpha(0)
-- fade2:SetOrder(2)
-- end
-- chatTab.glow:Show()
-- chatTab.glow:SetAlpha(0)
-- anims[chatTab.glow]:SetLooping("REPEAT")
-- anims[chatTab.glow]:Play()
-- --chatTab.alerting = true
-- alerting[chatTab] = true
-- -- START function FCFTab_UpdateAlpha(chatFrame)
-- local mouseOverAlpha, noMouseAlpha = 0, 0
-- if not chatFrame.isDocked or chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) then
-- mouseOverAlpha = 1.0 --CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA
-- noMouseAlpha = 0.4 -- CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA
-- else
-- mouseOverAlpha = 1.0 -- CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA
-- noMouseAlpha = 1.0 -- CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA
-- end
-- if chatFrame.hasBeenFaded then
-- chatTab:SetAlpha(mouseOverAlpha)
-- else
-- chatTab:SetAlpha(noMouseAlpha)
-- end
-- --END function FCFTab_UpdateAlpha(chatFrame)
-- --FCFDockOverflowButton_UpdatePulseState(GENERAL_CHAT_DOCK.overflowButton)
-- end
-- FCF_StopAlertFlash = function(chatFrame)
-- local chatTab = _G[chatFrame:GetName().."Tab"]
-- if chatFrame.minFrame then
-- if anims[chatFrame.minFrame] then
-- anims[chatFrame.minFrame]:Stop()
-- end
-- chatFrame.minFrame.glow:Hide()
-- --chatFrame.minFrame.alerting = false
-- alerting[chatFrame.minFrame] = nil
-- end
-- if anims[chatTab.glow] then
-- anims[chatTab.glow]:Stop()
-- end
-- chatTab.glow:Hide()
-- --chatTab.alerting = false
-- alerting[chatTab] = nil
-- -- START function FCFTab_UpdateAlpha(chatFrame)
-- local mouseOverAlpha, noMouseAlpha = 0, 0
-- if not chatFrame.isDocked or chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) then
-- mouseOverAlpha = 1.0 --CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA
-- noMouseAlpha = 0.4 -- CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA
-- else
-- mouseOverAlpha = 0.6 --CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA
-- noMouseAlpha = 0.2 --CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA
-- end
-- if chatFrame.hasBeenFaded then
-- chatTab:SetAlpha(mouseOverAlpha)
-- else
-- chatTab:SetAlpha(noMouseAlpha)
-- end
-- --END function FCFTab_UpdateAlpha(chatFrame)
-- --FCFDockOverflowButton_UpdatePulseState(GENERAL_CHAT_DOCK.overflowButton)
-- end
-- -- LibChatAnimsEnd
-- end
-- ----------------------------------------------------------------------
-- -- L16: LibDBIcon: LibCandyBar
-- ----------------------------------------------------------------------
-- function Leatrix_Plus:LeaPlusCandyBar()
-- -- LibCandyBarStart
-- --@curseforge-project-slug: libcandybar-3-0@
-- --- **LibCandyBar-3.0** provides elegant timerbars with icons for use in addons.
-- -- It is based of the original ideas of the CandyBar and CandyBar-2.0 library.
-- -- In contrary to the earlier libraries LibCandyBar-3.0 provides you with a timerbar object with a simple API.
-- --
-- -- Creating a new timerbar using the ':New' function will return a new timerbar object. This timerbar object inherits all of the barPrototype functions listed here. \\
-- --
-- -- @usage
-- -- local candy = LibStub("LibCandyBar-3.0")
-- -- local texture = "Interface\\AddOns\\MyAddOn\\statusbar"
-- -- local mybar = candy:New(texture, 100, 16)
-- -- mybar:SetLabel("Yay!")
-- -- mybar:SetDuration(60)
-- -- mybar:Start()
-- -- @class file
-- -- @name LibCandyBar-3.0
-- local GetTime, floor, next = GetTime, floor, next
-- local CreateFrame, error, setmetatable, UIParent = CreateFrame, error, setmetatable, UIParent
-- if not LibStub then error("LibCandyBar-3.0 requires LibStub.") end
-- local cbh = LibStub:GetLibrary("CallbackHandler-1.0")
-- if not cbh then error("LibCandyBar-3.0 requires CallbackHandler-1.0") end
-- local lib = LibStub:NewLibrary("LibCandyBar-3.0", 100) -- Bump minor on changes
-- if not lib then return end
-- lib.callbacks = lib.callbacks or cbh:New(lib)
-- local cb = lib.callbacks
-- lib.dummyFrame = lib.dummyFrame or CreateFrame("Frame")
-- lib.barFrameMT = lib.barFrameMT or {__index = lib.dummyFrame}
-- lib.barPrototype = lib.barPrototype or setmetatable({}, lib.barFrameMT)
-- lib.barPrototype_mt = lib.barPrototype_mt or {__index = lib.barPrototype}
-- lib.barCache = lib.barCache or {}
-- local barPrototype = lib.barPrototype
-- local barPrototype_meta = lib.barPrototype_mt
-- local barCache = lib.barCache
-- local scripts = {
-- "OnUpdate", "OnDragStart", "OnDragStop",
-- "OnEnter", "OnLeave", "OnHide",
-- "OnShow", "OnMouseDown", "OnMouseUp",
-- "OnMouseWheel", "OnSizeChanged", "OnEvent"
-- }
-- local numScripts = #scripts
-- local GameFontHighlightSmallOutline = GameFontHighlightSmallOutline
-- local _fontName, _fontSize = GameFontHighlightSmallOutline:GetFont()
-- local _fontShadowX, _fontShadowY = GameFontHighlightSmallOutline:GetShadowOffset()
-- local _fontShadowR, _fontShadowG, _fontShadowB, _fontShadowA = GameFontHighlightSmallOutline:GetShadowColor()
-- local SetWidth, SetHeight, SetSize = lib.dummyFrame.SetWidth, lib.dummyFrame.SetHeight, lib.dummyFrame.SetSize
-- local function stopBar(bar)
-- bar.updater:Stop()
-- bar.data = nil
-- bar.funcs = nil
-- bar.running = nil
-- bar.paused = nil
-- bar:Hide()
-- bar:SetParent(UIParent)
-- end
-- local tformat1 = "%d:%02d:%02d"
-- local tformat2 = "%d:%02d"
-- local tformat3 = "%.1f"
-- local tformat4 = "%.0f"
-- local function barUpdate(updater)
-- local bar = updater.parent
-- local t = GetTime()
-- if t >= bar.exp then
-- bar:Stop()
-- else
-- local time = bar.exp - t
-- bar.remaining = time
-- bar.candyBarBar:SetValue(bar.fill and (t-bar.start)+bar.gap or time)
-- if time > 3599.9 then -- > 1 hour
-- local h = floor(time/3600)
-- local m = floor((time - (h*3600))/60)
-- local s = (time - (m*60)) - (h*3600)
-- bar.candyBarDuration:SetFormattedText(tformat1, h, m, s)
-- elseif time > 59.9 then -- 1 minute to 1 hour
-- local m = floor(time/60)
-- local s = time - (m*60)
-- bar.candyBarDuration:SetFormattedText(tformat2, m, s)
-- elseif time < 10 then -- 0 to 10 seconds
-- bar.candyBarDuration:SetFormattedText(tformat3, time)
-- else -- 10 seconds to one minute
-- bar.candyBarDuration:SetFormattedText(tformat4, time)
-- end
-- if bar.funcs then
-- for i = 1, #bar.funcs do
-- bar.funcs[i](bar)
-- end
-- end
-- end
-- end
-- local atformat1 = "~%d:%02d:%02d"
-- local atformat2 = "~%d:%02d"
-- local atformat3 = "~%.1f"
-- local atformat4 = "~%.0f"
-- local function barUpdateApprox(updater)
-- local bar = updater.parent
-- local t = GetTime()
-- if t >= bar.exp then
-- bar:Stop()
-- else
-- local time = bar.exp - t
-- bar.remaining = time
-- bar.candyBarBar:SetValue(bar.fill and (t-bar.start)+bar.gap or time)
-- if time > 3599.9 then -- > 1 hour
-- local h = floor(time/3600)
-- local m = floor((time - (h*3600))/60)
-- local s = (time - (m*60)) - (h*3600)
-- bar.candyBarDuration:SetFormattedText(atformat1, h, m, s)
-- elseif time > 59.9 then -- 1 minute to 1 hour
-- local m = floor(time/60)
-- local s = time - (m*60)
-- bar.candyBarDuration:SetFormattedText(atformat2, m, s)
-- elseif time < 10 then -- 0 to 10 seconds
-- bar.candyBarDuration:SetFormattedText(atformat3, time)
-- else -- 10 seconds to one minute
-- bar.candyBarDuration:SetFormattedText(atformat4, time)
-- end
-- if bar.funcs then
-- for i = 1, #bar.funcs do
-- bar.funcs[i](bar)
-- end
-- end
-- end
-- end
-- -- ------------------------------------------------------------------------------
-- -- Bar functions
-- --
-- local function restyleBar(self)
-- if not self.running then return end
-- self.candyBarIconFrame:ClearAllPoints()
-- self.candyBarBar:ClearAllPoints()
-- -- In the past we used a :GetTexture check here, but as of WoW v5 it randomly returns nil, so use our own trustworthy variable.
-- if self.candyBarIconFrame.icon then
-- self.candyBarIconFrame:SetWidth(self.height)
-- if self.iconPosition == "RIGHT" then
-- self.candyBarIconFrame:SetPoint("TOPRIGHT", self)
-- self.candyBarIconFrame:SetPoint("BOTTOMRIGHT", self)
-- self.candyBarBar:SetPoint("TOPRIGHT", self.candyBarIconFrame, "TOPLEFT")
-- self.candyBarBar:SetPoint("BOTTOMRIGHT", self.candyBarIconFrame, "BOTTOMLEFT")
-- self.candyBarBar:SetPoint("TOPLEFT", self)
-- self.candyBarBar:SetPoint("BOTTOMLEFT", self)
-- else
-- self.candyBarIconFrame:SetPoint("TOPLEFT")
-- self.candyBarIconFrame:SetPoint("BOTTOMLEFT")
-- self.candyBarBar:SetPoint("TOPLEFT", self.candyBarIconFrame, "TOPRIGHT")
-- self.candyBarBar:SetPoint("BOTTOMLEFT", self.candyBarIconFrame, "BOTTOMRIGHT")
-- self.candyBarBar:SetPoint("TOPRIGHT", self)
-- self.candyBarBar:SetPoint("BOTTOMRIGHT", self)
-- end
-- self.candyBarIconFrame:Show()
-- else
-- self.candyBarBar:SetPoint("TOPLEFT", self)
-- self.candyBarBar:SetPoint("BOTTOMRIGHT", self)
-- self.candyBarIconFrame:Hide()
-- end
-- if self.showLabel and self.candyBarLabel.text then
-- self.candyBarLabel:Show()
-- else
-- self.candyBarLabel:Hide()
-- end
-- if self.showTime then
-- self.candyBarDuration:Show()
-- else
-- self.candyBarDuration:Hide()
-- end
-- end
-- --- Set whether the bar should drain (default) or fill up.
-- -- @param fill Boolean true/false
-- function barPrototype:SetFill(fill)
-- self.fill = fill
-- end
-- --- Adds a function to the timerbar. The function will run every update and will receive the bar as a parameter.
-- -- @param func Function to run every update.
-- -- @usage
-- -- -- The example below will print the time remaining to the chatframe every update. Yes, that's a whole lot of spam
-- -- mybar:AddUpdateFunction( function(bar) print(bar.remaining) end )
-- function barPrototype:AddUpdateFunction(func) if not self.funcs then self.funcs = {} end; self.funcs[#self.funcs+1] = func end
-- --- Sets user data in the timerbar object.
-- -- @param key Key to use for the data storage.
-- -- @param data Data to store.
-- function barPrototype:Set(key, data) if not self.data then self.data = {} end; self.data[key] = data end
-- --- Retrieves user data from the timerbar object.
-- -- @param key Key to retrieve
-- function barPrototype:Get(key) return self.data and self.data[key] end
-- --- Sets the color of the bar.
-- -- This is basically a wrapper to SetStatusBarColor.
-- -- @paramsig r, g, b, a
-- -- @param r Red component (0-1)
-- -- @param g Green component (0-1)
-- -- @param b Blue component (0-1)
-- -- @param a Alpha (0-1)
-- function barPrototype:SetColor(...) self.candyBarBar:SetStatusBarColor(...) end
-- --- Sets the color of the bar label and bar duration text.
-- -- @paramsig r, g, b, a
-- -- @param r Red component (0-1)
-- -- @param g Green component (0-1)
-- -- @param b Blue component (0-1)
-- -- @param a Alpha (0-1)
-- function barPrototype:SetTextColor(...)
-- self.candyBarLabel:SetTextColor(...)
-- self.candyBarDuration:SetTextColor(...)
-- end
-- --- Sets the shadow color of the bar label and bar duration text.
-- -- @paramsig r, g, b, a
-- -- @param r Red component (0-1)
-- -- @param g Green component (0-1)
-- -- @param b Blue component (0-1)
-- -- @param a Alpha (0-1)
-- function barPrototype:SetShadowColor(...)
-- self.candyBarLabel:SetShadowColor(...)
-- self.candyBarDuration:SetShadowColor(...)
-- end
-- --- Sets the texture of the bar.
-- -- This should only be needed on running bars that get changed on the fly.
-- -- @param texture Path to the bar texture.
-- function barPrototype:SetTexture(texture)
-- self.candyBarBar:SetStatusBarTexture(texture)
-- self.candyBarBackground:SetTexture(texture)
-- end
-- --- Sets the width of the bar.
-- -- This should only be needed on running bars that get changed on the fly.
-- -- @param width Width of the bar.
-- function barPrototype:SetWidth(width)
-- self.width = width
-- SetWidth(self, width)
-- end
-- --- Sets the height of the bar.
-- -- This should only be needed on running bars that get changed on the fly.
-- -- @param height Height of the bar.
-- function barPrototype:SetHeight(height)
-- self.height = height
-- SetHeight(self, height)
-- restyleBar(self)
-- end
-- --- Sets the size of the bar.
-- -- This should only be needed on running bars that get changed on the fly.
-- -- @param width Width of the bar.
-- -- @param height Height of the bar.
-- function barPrototype:SetSize(width, height)
-- self.width = width
-- self.height = height
-- SetSize(self, width, height)
-- restyleBar(self)
-- end
-- --- Returns the label (text) currently set on the bar.
-- function barPrototype:GetLabel()
-- return self.candyBarLabel.text
-- end
-- --- Sets the label on the bar.
-- -- @param text Label text.
-- function barPrototype:SetLabel(text)
-- self.candyBarLabel.text = text
-- self.candyBarLabel:SetText(text)
-- if text then
-- self.candyBarLabel:Show()
-- else
-- self.candyBarLabel:Hide()
-- end
-- end
-- --- Returns the icon texture path currently set on the bar, if it has an icon set.
-- function barPrototype:GetIcon()
-- return self.candyBarIconFrame.icon
-- end
-- --- Sets the icon next to the bar.
-- -- @param icon Path to the icon texture or nil to not display an icon.
-- -- @param ... Optional icon coordinates for texture trimming.
-- function barPrototype:SetIcon(icon, ...)
-- self.candyBarIconFrame.icon = icon
-- self.candyBarIconFrame:SetTexture(icon)
-- if ... then
-- self.candyBarIconFrame:SetTexCoord(...)
-- else
-- self.candyBarIconFrame:SetTexCoord(0.07, 0.93, 0.07, 0.93)
-- end
-- restyleBar(self)
-- end
-- --- Sets which side of the bar the icon should appear.
-- -- @param position Position of the icon according to the bar, either "LEFT" or "RIGHT" as a string. Set to "LEFT" by default.
-- function barPrototype:SetIconPosition(position)
-- self.iconPosition = position
-- restyleBar(self)
-- end
-- --- Sets wether or not the time indicator on the right of the bar should be shown.
-- -- Time is shown by default.
-- -- @param bool true to show the time, false/nil to hide the time.
-- function barPrototype:SetTimeVisibility(bool)
-- self.showTime = bool
-- if bool then
-- self.candyBarDuration:Show()
-- else
-- self.candyBarDuration:Hide()
-- end
-- end
-- --- Sets wether or not the label on the left of the bar should be shown.
-- -- label is shown by default.
-- -- @param bool true to show the label, false/nil to hide the label.
-- function barPrototype:SetLabelVisibility(bool)
-- self.showLabel = bool
-- if bool then
-- self.candyBarLabel:Show()
-- else
-- self.candyBarLabel:Hide()
-- end
-- end
-- --- Sets the duration of the bar.
-- -- This can also be used while the bar is running to adjust the time remaining, within the bounds of the original duration.
-- -- @param duration Duration of the bar in seconds.
-- -- @param isApprox Boolean. True if you wish the time display to be an approximate "~5" instead of "5"
-- function barPrototype:SetDuration(duration, isApprox) self.remaining = duration; self.isApproximate = isApprox end
-- --- Shows the bar and starts it.
-- -- @param maxValue Number. If you don't wish your bar to start full, you can set a max value. A maxValue of 10 on a bar with a duration of 5 would start it at 50%.
-- function barPrototype:Start(maxValue)
-- self.running = true
-- local time = self.remaining
-- self.gap = maxValue and maxValue-time or 0
-- restyleBar(self)
-- self.start = GetTime()
-- self.exp = self.start + time
-- self.candyBarBar:SetMinMaxValues(0, maxValue or time)
-- self.candyBarBar:SetValue(self.fill and 0 or time)
-- if self.isApproximate then
-- if time > 3599.9 then -- > 1 hour
-- local h = floor(time/3600)
-- local m = floor((time - (h*3600))/60)
-- local s = (time - (m*60)) - (h*3600)
-- self.candyBarDuration:SetFormattedText(atformat1, h, m, s)
-- elseif time > 59.9 then -- 1 minute to 1 hour
-- local m = floor(time/60)
-- local s = time - (m*60)
-- self.candyBarDuration:SetFormattedText(atformat2, m, s)
-- elseif time < 10 then -- 0 to 10 seconds
-- self.candyBarDuration:SetFormattedText(atformat3, time)
-- else -- 10 seconds to one minute
-- self.candyBarDuration:SetFormattedText(atformat4, time)
-- end
-- self.updater:SetScript("OnLoop", barUpdateApprox)
-- else
-- if time > 3599.9 then -- > 1 hour
-- local h = floor(time/3600)
-- local m = floor((time - (h*3600))/60)
-- local s = (time - (m*60)) - (h*3600)
-- self.candyBarDuration:SetFormattedText(tformat1, h, m, s)
-- elseif time > 59.9 then -- 1 minute to 1 hour
-- local m = floor(time/60)
-- local s = time - (m*60)
-- self.candyBarDuration:SetFormattedText(tformat2, m, s)
-- elseif time < 10 then -- 0 to 10 seconds
-- self.candyBarDuration:SetFormattedText(tformat3, time)
-- else -- 10 seconds to one minute
-- self.candyBarDuration:SetFormattedText(tformat4, time)
-- end
-- self.updater:SetScript("OnLoop", barUpdate)
-- end
-- self.updater:Play()
-- self:Show()
-- end
-- --- Pauses a running bar
-- function barPrototype:Pause()
-- if not self.paused then
-- self.updater:Pause()
-- self.paused = GetTime()
-- end
-- end
-- --- Resumes a paused bar
-- function barPrototype:Resume()
-- if self.paused then
-- local t = GetTime()
-- self.exp = t + self.remaining
-- self.start = self.start + (t-self.paused)
-- self.updater:Play()
-- self.paused = nil
-- end
-- end
-- --- Stops the bar.
-- -- This will stop the bar, fire the LibCandyBar_Stop callback, and recycle the bar into the candybar pool.
-- -- Note: make sure you remove all references to the bar in your addon upon receiving the LibCandyBar_Stop callback.
-- -- @usage
-- -- -- The example below shows the use of the LibCandyBar_Stop callback by printing the contents of the label in the chatframe
-- -- local function barstopped( callback, bar )
-- -- print( bar:GetLabel(), "stopped")
-- -- end
-- -- LibStub("LibCandyBar-3.0"):RegisterCallback(myaddonobject, "LibCandyBar_Stop", barstopped)
-- -- @param ... Optional args to pass across in the LibCandyBar_Stop callback.
-- function barPrototype:Stop(...)
-- cb:Fire("LibCandyBar_Stop", self, ...)
-- stopBar(self)
-- barCache[self] = true
-- end
-- -- ------------------------------------------------------------------------------
-- -- Library functions
-- --
-- --- Creates a new timerbar object and returns it. Don't forget to set the duration, label and :Start the timer bar after you get a hold of it!
-- -- @paramsig texture, width, height
-- -- @param texture Path to the texture used for the bar.
-- -- @param width Width of the bar.
-- -- @param height Height of the bar.
-- -- @usage
-- -- mybar = LibStub("LibCandyBar-3.0"):New("Interface\\AddOns\\MyAddOn\\media\\statusbar", 100, 16)
-- function lib:New(texture, width, height)
-- local bar = next(barCache)
-- if not bar then
-- local frame = CreateFrame("Frame", nil, UIParent)
-- bar = setmetatable(frame, barPrototype_meta)
-- local icon = bar:CreateTexture()
-- icon:SetPoint("TOPLEFT")
-- icon:SetPoint("BOTTOMLEFT")
-- icon:Show()
-- bar.candyBarIconFrame = icon
-- local statusbar = CreateFrame("StatusBar", nil, bar)
-- statusbar:SetPoint("TOPRIGHT")
-- statusbar:SetPoint("BOTTOMRIGHT")
-- bar.candyBarBar = statusbar
-- local bg = statusbar:CreateTexture(nil, "BACKGROUND")
-- bg:SetAllPoints()
-- bar.candyBarBackground = bg
-- local backdrop = CreateFrame("Frame", nil, bar, "BackdropTemplate") -- Used by bar stylers for backdrops
-- backdrop:SetFrameLevel(0)
-- bar.candyBarBackdrop = backdrop
-- local iconBackdrop = CreateFrame("Frame", nil, bar, "BackdropTemplate") -- Used by bar stylers for backdrops
-- iconBackdrop:SetFrameLevel(0)
-- bar.candyBarIconFrameBackdrop = iconBackdrop
-- local duration = statusbar:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmallOutline")
-- duration:SetPoint("TOPLEFT", statusbar, "TOPLEFT", 2, 0)
-- duration:SetPoint("BOTTOMRIGHT", statusbar, "BOTTOMRIGHT", -2, 0)
-- bar.candyBarDuration = duration
-- local label = statusbar:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmallOutline")
-- label:SetPoint("TOPLEFT", statusbar, "TOPLEFT", 2, 0)
-- label:SetPoint("BOTTOMRIGHT", statusbar, "BOTTOMRIGHT", -2, 0)
-- bar.candyBarLabel = label
-- local updater = bar:CreateAnimationGroup()
-- updater:SetLooping("REPEAT")
-- updater.parent = bar
-- local anim = updater:CreateAnimation()
-- anim:SetDuration(0.04)
-- bar.updater = updater
-- bar.repeater = anim
-- else
-- barCache[bar] = nil
-- end
-- bar:SetFrameStrata("MEDIUM")
-- bar:SetFrameLevel(100) -- Lots of room to create above or below this level
-- bar.candyBarBar:SetStatusBarTexture(texture)
-- bar.candyBarBackground:SetTexture(texture)
-- bar.width = width
-- bar.height = height
-- -- RESET ALL THE THINGS!
-- bar.fill = nil
-- bar.showTime = true
-- bar.showLabel = true
-- bar.iconPosition = nil
-- for i = 1, numScripts do -- Update if scripts table is changed, faster than doing #scripts
-- bar:SetScript(scripts[i], nil)
-- end
-- bar.candyBarBackground:SetVertexColor(0.5, 0.5, 0.5, 0.3)
-- bar.candyBarBar:SetStatusBarColor(0.5, 0.5, 0.5, 1)
-- bar:ClearAllPoints()
-- SetWidth(bar, width)
-- SetHeight(bar, height)
-- bar:SetMovable(1)
-- bar:SetScale(1)
-- bar:SetAlpha(1)
-- bar:SetClampedToScreen(false)
-- bar:EnableMouse(false)
-- bar.candyBarLabel:SetTextColor(1,1,1,1)
-- bar.candyBarLabel:SetJustifyH("LEFT")
-- bar.candyBarLabel:SetJustifyV("MIDDLE")
-- bar.candyBarLabel:SetFont(_fontName, _fontSize)
-- bar.candyBarLabel:SetShadowOffset(_fontShadowX, _fontShadowY)
-- bar.candyBarLabel:SetShadowColor(_fontShadowR, _fontShadowG, _fontShadowB, _fontShadowA)
-- bar.candyBarDuration:SetTextColor(1,1,1,1)
-- bar.candyBarDuration:SetJustifyH("RIGHT")
-- bar.candyBarDuration:SetJustifyV("MIDDLE")
-- bar.candyBarDuration:SetFont(_fontName, _fontSize)
-- bar.candyBarDuration:SetShadowOffset(_fontShadowX, _fontShadowY)
-- bar.candyBarDuration:SetShadowColor(_fontShadowR, _fontShadowG, _fontShadowB, _fontShadowA)
-- bar:SetLabel()
-- bar:SetIcon()
-- bar:SetDuration()
-- return bar
-- end
-- -- LibCandyBarEnd
-- end
-- -- L17: End