3359 lines
108 KiB
Lua
3359 lines
108 KiB
Lua
<<<<<<< HEAD
|
||
----------------------------------------------------------------------
|
||
-- 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
|
||
=======
|
||
----------------------------------------------------------------------
|
||
-- 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
|
||
>>>>>>> 0f3757ee7b0a1d6b3ed73a1e639c617c3b5acfd0
|