WoWInterface SVN StunWatch

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

StunWatch/Libs/LibCandyBar/LibCandyBar.lua New file
0,0 → 1,1758
local major, minor = "LibCandyBar", "$Revision: 67072 $"
 
local lib, oldMinor = LibStub:NewLibrary(major, minor)
if not lib then return end
 
if not lib.frame then
lib.frame = CreateFrame("Frame")
lib.frame.name = "CandyBar-2.1 Frame"
lib.frame:Hide()
end
 
lib.handlers = lib.handlers or {}
lib.groups = lib.groups or {}
lib.framepool = lib.framepool or {}
lib.addons = lib.addons or {}
lib.embeds = lib.embeds or {}
 
local function print(text)
ChatFrame1:AddMessage(text)
end
 
local paint
 
local mixins = {
"RegisterCandyBar",
"UnregisterCandyBar",
"IsCandyBarRegistered",
"StartCandyBar",
"StopCandyBar",
"PauseCandyBar",
"CandyBarStatus",
"SetCandyBarTexture",
"SetCandyBarTime",
"SetCandyBarColor",
"SetCandyBarText",
"SetCandyBarIcon",
"SetCandyBarIconPosition",
"SetCandyBarWidth",
"SetCandyBarHeight",
"SetCandyBarBackgroundColor",
"SetCandyBarTextColor",
"SetCandyBarTimerTextColor",
"SetCandyBarFontSize",
"SetCandyBarPoint",
"GetCandyBarPoint",
"GetCandyBarCenter",
"GetCandyBarOffsets",
"GetCandyBarEffectiveScale",
"SetCandyBarGradient",
"SetCandyBarScale",
"SetCandyBarTimeFormat",
"SetCandyBarTimeLeft",
"SetCandyBarCompletion",
"SetCandyBarFade",
"RegisterCandyBarGroup",
"UnregisterCandyBarGroup",
"IsCandyBarGroupRegistered",
"SetCandyBarGroupPoint",
"SetCandyBarGroupGrowth",
"SetCandyBarGroupVerticalSpacing",
"UpdateCandyBarGroup",
"GetCandyBarNextBarPointInGroup",
"RegisterCandyBarWithGroup",
"UnregisterCandyBarWithGroup",
"IsCandyBarRegisteredWithGroup",
"SetCandyBarReversed",
"IsCandyBarReversed",
"SetCandyBarOnClick",
"SetCandyBarOnSizeGroup",
}
 
local defaults = {
texture = "Interface\\TargetingFrame\\UI-StatusBar",
width = 200,
height = 16,
scale = 1,
point = "CENTER",
rframe = UIParent,
rpoint = "CENTER",
iconpos = "LEFT",
xoffset = 0,
yoffset = 0,
fontsize = 11,
color = {1, 0, 1, 1},
bgcolor = {0, 0.5, 0.5, 0.5},
textcolor = {1, 1, 1, 1},
timertextcolor = {1, 1, 1, 1},
stayonscreen = false,
}
 
local getArgs
do
local numargs
local function _get(t, str, i, ...)
if i<=numargs then
return t[format("%s%d", str, i)], _get(t, str, i+1, ...)
end
return ...
end
 
function getArgs(t, str, ...)
numargs = t[str.."#" or 0]
return _get(t,str,1, ...)
end
end
 
local function setArgs(t, str, ...)
local n = select("#", ...)
for i=1,n do
t[format("%s%d",str,i)]=select(i,...)
end
for i=n+1, (t[str.."#"] or 0) do
t[format("%s%d",str,i)]=nil
end
t[str.."#"] = n
end
 
local new, del
do
local cache = setmetatable({},{__mode='k'})
function new()
local t = next(cache)
if t then
cache[t] = nil
return t
else
return {}
end
end
function del(t)
for k in pairs(t) do
t[k] = nil
end
cache[t] = true
return nil
end
end
 
 
function lib:argCheck(var, nr, ...)
local total = select("#", ...)
local ok = false
for i=1,total do
if type(var) == select(i,...) then
ok = true
end
end
if not ok then
error("Wrong type for argument "..nr, 2)
end
end
 
 
-- Registers a new candy bar
-- name - A unique identifier for your bar.
-- time - Time for the bar
-- text - text displayed on the bar [defaults to the name if not set]
-- icon - icon off the bar [optional]
-- c1 - c10 - color of the bar [optional]
-- returns true on a succesful register
function lib:Register(name, time, text, icon, c1, c2, c3, c4, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(time, 3, "number")
lib:argCheck(text, 4, "string", "nil")
lib:argCheck(icon, 5, "string", "nil")
lib:argCheck(c1, 6, "string", "number", "nil")
lib:argCheck(c2, 7, "string", "number", "nil")
lib:argCheck(c3, 8, "string", "number", "nil")
lib:argCheck(c4, 9, "string", "number", "nil")
if not text then text = name end
if lib.handlers[name] then
self:Unregister(name)
end
local handler = new()
handler.name, handler.time, handler.text, handler.icon = name, time, text or name, icon
handler.texture = defaults.texture
local c1Type = type(c1)
if c1Type ~= "number" and not paint then
error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
end
if c1Type == "nil" or (c1Type ~= "number" and paint and not paint:GetRGBPercent(c1)) then
c1 = "green"
end
handler.color = new()
if c1Type == "number" then
handler.color[1] = c1
handler.color[2] = c2
handler.color[3] = c3
else
handler.color[1], handler.color[2], handler.color[3] = select(2, paint:GetRGBPercent(c1))
end
handler.color[4] = 1
handler.running = nil
handler.endtime = 0
handler.reversed = nil
lib.handlers[name] = handler
handler.frame = lib:AcquireBarFrame(name)
if (c1Type == "number" and c4) or (c1Type == "string" and c2) then
lib:SetGradient(name, c1, c2, c3, c4, ...)
end
handler.stayonscreen = defaults.stayonscreen
return true
end
 
 
-- Removes a candy bar
-- a1 - a10 handlers that you wish to remove
-- returns true upon sucessful removal
function lib:Unregister(a1, ...)
lib:argCheck(a1, 2, "string")
if not lib.handlers[a1] then
return
end
lib:UnregisterWithGroup(a1)
lib:ReleaseBarFrame(a1)
local handler = lib.handlers[a1]
lib.handlers[a1] = nil
if handler.color then
handler.color = del(handler.color)
end
if handler.bgcolor then
handler.bgcolor = del(handler.bgcolor)
end
if handler.textcolor then
handler.textcolor = del(handler.textcolor)
end
if handler.timertextcolor then
handler.timertextcolor = del(handler.timertextcolor)
end
if handler.gradienttable then
for i,v in ipairs(handler.gradienttable) do
v = del(v)
end
handler.gradienttable = del(handler.gradienttable)
end
handler = del(handler)
if ... then
lib:Unregister(...)
elseif not lib:HasHandlers() then
lib.frame:Hide()
end
return true
end
 
-- Checks if a candy bar is registered
-- Args: name - name of the candybar
-- returns true if a the candybar is registered
function lib:IsRegistered(name)
lib:argCheck(name, 2, "string")
if lib.handlers[name] then
return true
end
return false
end
 
-- Start a bar
-- Args: name - the candybar you want to start
-- fireforget [optional] - pass true if you want the bar to unregister upon completion
-- returns true if succesful
function lib:Start(name, fireforget)
lib:argCheck(name, 2, "string")
lib:argCheck(fireforget, 3, "boolean", "nil")
local handler = lib.handlers[name]
if not handler then
return
end
local t = GetTime()
if handler.paused then
local pauseoffset = t - handler.pausetime
handler.endtime = handler.endtime + pauseoffset
handler.starttime = handler.starttime + pauseoffset
elseif handler.elapsed and not handler.running then
handler.endtime = t + handler.time - handler.elapsed
handler.starttime = t - handler.elapsed
else
-- bar hasn't elapsed a second.
handler.elapsed = 0
handler.endtime = t + handler.time
handler.starttime = t
end
handler.fireforget = fireforget
handler.running = true
handler.paused = nil
handler.fading = nil
lib:AcquireBarFrame(name) -- this will reset the barframe incase we were fading out when it was restarted
handler.frame:Show()
if handler.group then
lib:UpdateGroup(handler.group) -- update the group
end
lib.frame:Show()
return true
end
 
-- Stop a bar
-- Args: name - the candybar you want to stop
-- returns true if succesful
function lib:Stop(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
 
if not handler then
return
end
 
handler.running = nil
handler.paused = nil
handler.elapsed = 0
 
if handler.fadeout then
handler.frame.spark:Hide()
if not handler.stayonscreen then
handler.fading = true
handler.fadeelapsed = 0
local t = GetTime()
if handler.endtime > t then
handler.endtime = t
end
end
else
handler.frame:Hide()
handler.starttime = nil
handler.endtime = 0
if handler.group then
lib:UpdateGroup(handler.group)
end
if handler.fireforget then
return lib:Unregister(name)
end
end
if not lib:HasHandlers() then
lib.frame:Hide()
end
return true
end
 
-- Pause a bar
-- Name - the candybar you want to pause
-- returns true if succesful
function lib:Pause(name)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
handler.pausetime = GetTime()
handler.paused = true
handler.running = nil
end
 
-- Query a timer's status
-- Args: name - the schedule you wish to look up
-- Returns: registered - true if a schedule exists with this name
-- time - time for this bar
-- elapsed - time elapsed for this bar
-- running - true if this schedule is currently running
function lib:Status(name)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
return true, handler.time, handler.elapsed, handler.running, handler.paused
end
 
 
-- Set the time for a bar.
-- Args: name - the candybar name
-- time - the new time for this bar
-- returns true if succesful
function lib:SetTime(name, time)
lib:argCheck(name, 2, "string")
lib:argCheck(time, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
handler.time = time
if handler.starttime and handler.endtime then
handler.endtime = handler.starttime + time
end
return true
end
 
-- Set the time left for a bar.
-- Args: name - the candybar name
-- time - time left on the bar
-- returns true if succesful
 
function lib:SetTimeLeft(name, time)
lib:argCheck(name, 2, "string")
lib:argCheck(time, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
if handler.time < time or time < 0 then
return
end
 
local e = handler.time - time
if handler.starttime and handler.endtime then
local d = handler.elapsed - e
handler.starttime = handler.starttime + d
handler.endtime = handler.endtime + d
end
 
handler.elapsed = e
 
if handler.group then
lib:UpdateGroup(handler.group)
end
 
return true
end
 
-- Sets smooth coloring of the bar depending on time elapsed
-- Args: name - the candybar name
-- c1 - c10 color order of the gradient
-- returns true when succesful
local cachedgradient = {}
function lib:SetGradient(name, c1, c2, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(c1, 3, "string", "number", "nil")
lib:argCheck(c2, 4, "string", "number", "nil")
 
local handler = lib.handlers[name]
 
if not handler then
return
end
 
local gtable = new()
local gradientid = nil
 
-- We got string values passed in, which means they're not rgb values
-- directly, but a color most likely registered with paintchips
if type(c1) == "string" then
if not paint then
error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
end
if not paint:GetRGBPercent(c1) then c1 = "green" end
if not paint:GetRGBPercent(c2) then c2 = "red" end
 
gtable[1] = new()
gtable[2] = new()
 
gradientid = c1 .. "_" .. c2
 
gtable[1][1], gtable[1][2], gtable[1][3] = select(2, paint:GetRGBPercent(c1))
gtable[2][1], gtable[2][2], gtable[2][3] = select(2, paint:GetRGBPercent(c2))
for i = 1, select('#', ...) do
local c = select(i, ...)
if not c or not paint:GetRGBPercent(c) then
break
end
local t = new()
t[1], t[2], t[3] = select(2, paint:GetRGBPercent(c))
table.insert(gtable, t)
gradientid = gradientid .. "_" .. c
end
elseif type(c1) == "number" then
-- It's a number, which means we should expect r,g,b values
local n = select("#", ...)
if n < 4 then error("Not enough extra arguments to :SetGradient, need at least 2 RGB pairs.") end
gtable[1] = new()
gtable[1][1] = c1
gtable[1][2] = c2
gtable[1][3] = select(1, ...)
gradientid = string.format("%d%d%d", c1, c2, gtable[1][3])
 
for i = 2, n, 3 do
local r, g, b = select(i, ...)
if r and g and b then
local t = new()
t[1], t[2], t[3] = r, g, b
table.insert(gtable, t)
gradientid = string.format("%s_%d%d%d", gradientid, r, g, b)
else
break
end
end
end
 
local max = #gtable
for i = 1, max do
if not gtable[i][4] then
gtable[i][4] = 1
end
gtable[i][5] = (i-1) / (max-1)
end
if handler.gradienttable then
for i,v in ipairs(handler.gradienttable) do
v = del(v)
end
handler.gradienttable = del(handler.gradienttable)
end
handler.gradienttable = gtable
handler.gradient = true
handler.gradientid = gradientid
if not cachedgradient[gradientid] then
cachedgradient[gradientid] = {}
end
 
handler.frame.statusbar:SetStatusBarColor(unpack(gtable[1], 1, 4))
return true
end
 
local function setColor(color, alpha, b, a)
lib:argCheck(color, 3, "string", "number")
local ctable = nil
if type(color) == "string" then
if not paint then
error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
end
if not paint:GetRGBPercent(color) then
return
end
lib:argCheck(alpha, 4, "number", "nil")
ctable = new()
ctable[1], ctable[2], ctable[3] = select(2, paint:GetRGBPercent(color))
if alpha then
ctable[4] = alpha
else
ctable[4] = 1
end
else
lib:argCheck(alpha, 4, "number")
lib:argCheck(b, 5, "number")
lib:argCheck(a, 6, "number", "nil")
ctable = new()
ctable[1], ctable[2], ctable[3] = color, alpha, b
if a then
ctable[4] = a
else
ctable[4] = 1
end
end
return ctable
end
 
-- Set the color of the bar
-- Args: name - the candybar name
-- color - new color of the bar
-- alpha - new alpha of the bar
-- Setting the color will override smooth settings.
function lib:SetColor(name, color, alpha, b, a)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
local t = setColor(color, alpha, b, a)
if not t then return end
 
if handler.color then
handler.color = del(handler.color)
end
handler.color = t
handler.gradient = nil
 
handler.frame.statusbar:SetStatusBarColor(unpack(t, 1, 4))
return true
end
 
-- Set the color of background of the bar
-- Args: name - the candybar name
-- color - new color of the bar
-- alpha - new alpha of the bar
-- Setting the color will override smooth settings.
function lib:SetBackgroundColor(name, color, alpha, b, a)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
 
local t = setColor(color, alpha, b, a)
if not t then return end
 
if handler.bgcolor then
handler.bgcolor = del(handler.bgcolor)
end
handler.bgcolor = t
--handler.frame.statusbarbg:SetStatusBarColor(unpack(t, 1, 4))
 
return true
end
 
-- Set the color for the bar text
-- Args: name - name of the candybar
-- color - new color of the text
-- alpha - new alpha of the text
-- returns true when succesful
function lib:SetTextColor(name, color, alpha, b, a)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
 
local t = setColor(color, alpha, b, a)
if not t then return end
 
if handler.textcolor then
handler.textcolor = del(handler.textcolor)
end
handler.textcolor = t
handler.frame.text:SetTextColor(unpack(t, 1, 4))
 
return true
end
 
-- Set the color for the timer text
-- Args: name - name of the candybar
-- color - new color of the text
-- alpha - new alpha of the text
-- returns true when succesful
function lib:SetTimerTextColor(name, color, alpha, b, a)
lib:argCheck(name, 2, "string")
local handler = lib.handlers[name]
if not handler then
return
end
 
local t = setColor(color, alpha, b, a)
if not t then return end
 
if handler.timertextcolor then
handler.timertextcolor = del(handler.timertextcolor)
end
handler.timertextcolor = t
handler.frame.timertext:SetTextColor(unpack(t, 1, 4))
 
return true
end
 
-- Set the text for the bar
-- Args: name - name of the candybar
-- text - text to set it to
-- returns true when succesful
function lib:SetText(name, text)
lib:argCheck(name, 2, "string")
lib:argCheck(text, 3, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.text = text
handler.frame.text:SetText(text)
 
return true
end
 
-- Set the fontsize
-- Args: name - name of the candybar
-- fontsize - new fontsize
-- returns true when succesful
function lib:SetFontSize(name, fontsize)
lib:argCheck(name, 2, "string")
lib:argCheck(fontsize, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
local font, _, style = GameFontHighlight:GetFont()
local timertextwidth = fontsize * 3.6
local width = handler.width or defaults.width
local f = handler.frame
 
handler.fontsize = fontsize
f.timertext:SetFont(font, fontsize, style)
f.text:SetFont(font, fontsize, style)
f.timertext:SetWidth(timertextwidth)
f.text:SetWidth((width - timertextwidth) * .9)
 
return true
end
 
 
-- Set the point where a bar should be anchored
-- Args: name -- name of the bar
-- point -- anchor point
-- rframe -- relative frame
-- rpoint -- relative point
-- xoffset -- x offset
-- yoffset -- y offset
-- returns true when succesful
function lib:SetPoint(name, point, rframe, rpoint, xoffset, yoffset)
lib:argCheck(name, 2, "string")
lib:argCheck(point, 3, "string")
lib:argCheck(rframe, 4, "table", "string", "nil")
lib:argCheck(rpoint, 5, "string", "nil")
lib:argCheck(xoffset, 6, "number", "nil")
lib:argCheck(yoffset, 7, "number", "nil")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.point = point
handler.rframe = rframe
handler.rpoint = rpoint
handler.xoffset = xoffset
handler.yoffset = yoffset
 
handler.frame:ClearAllPoints()
handler.frame:SetPoint(point, rframe, rpoint, xoffset, yoffset)
 
return true
end
 
function lib:GetPoint(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
return handler.point, handler.rframe, handler.rpoint, handler.xoffset, handler.yoffset
end
 
function lib:GetCenter(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
return handler.frame:GetCenter()
end
 
function lib:GetOffsets(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
local bottom = handler.frame:GetBottom()
local top = handler.frame:GetTop()
local left = handler.frame:GetLeft()
local right = handler.frame:GetRight()
 
return left, top, bottom, right
end
 
function lib:GetEffectiveScale(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
return handler.frame:GetEffectiveScale()
end
 
-- Set the width for a bar
-- Args: name - name of the candybar
-- width - new width of the candybar
-- returns true when succesful
function lib:SetWidth(name, width)
lib:argCheck(name, 2, "string")
lib:argCheck(width, 3, "number")
 
local handler = lib.handlers[name]
if not lib.handlers[name] then
return
end
 
local height = handler.height or defaults.height
local fontsize = handler.fontsize or defaults.fontsize
local timertextwidth = fontsize * 3.6
local f = handler.frame
f:SetWidth(width + 10)
f.statusbar:SetWidth(width)
--f.statusbarbg:SetWidth(width)
 
f.timertext:SetWidth(timertextwidth)
f.text:SetWidth((width - timertextwidth) * .9)
 
handler.width = width
 
return true
end
 
-- Set the height for a bar
-- Args: name - name of the candybar
-- height - new height for the bar
-- returs true when succesful
function lib:SetHeight(name, height)
lib:argCheck(name, 2, "string")
lib:argCheck(height, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
local width = handler.width or defaults.width
local f = handler.frame
 
f:SetWidth(width + 10)
f:SetHeight(height + 10)
--f.icon:SetWidth(height)
--f.icon:SetHeight(height)
f.statusbar:SetHeight(height)
--f.statusbarbg:SetHeight(height)
--f.spark:SetHeight(height)
 
--f.statusbarbg:SetPoint("TOPLEFT", f, "TOPLEFT", height, 0)
f.statusbar:SetPoint("TOPLEFT", f, "TOPLEFT", height, 0)
 
handler.height = height
 
return true
end
 
-- Set the scale for a bar
-- Args: name - name of the candybar
-- scale - new scale of the bar
-- returns true when succesful
function lib:SetScale(name, scale)
lib:argCheck(name, 2, "string")
lib:argCheck(scale, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.scale = scale
 
handler.frame:SetScale(scale)
 
return true
end
 
-- Set the time formatting function for a bar
-- Args: name - name of the candybar
-- func - function that returns the formatted string
-- a1-a10 - optional arguments to that function
-- returns true when succesful
 
function lib:SetTimeFormat(name, func, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(func, 3, "function")
 
local handler = lib.handlers[name]
 
if not handler then
return
end
handler.timeformat = func
setArgs(handler, "timeformat", ...)
 
return true
end
 
-- Set the completion function for a bar
-- Args: name - name of the candybar
-- func - function to call upon ending of the bar
-- a1 - a10 - arguments to pass to the function
-- returns true when succesful
function lib:SetCompletion(name, func, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(func, 3, "function")
 
local handler = lib.handlers[name]
 
if not handler then
return
end
handler.completion = func
setArgs(handler, "completion", ...)
 
return true
end
 
local function onClick()
lib:OnClick()
end
 
-- Set the on click function for a bar
-- Args: name - name of the candybar
-- func - function to call when the bar is clicked
-- a1 - a10 - arguments to pass to the function
-- returns true when succesful
function lib:SetOnClick(name, func, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(func, 3, "function", "nil")
 
local handler = lib.handlers[name]
 
if not handler then
return
end
handler.onclick = func
setArgs(handler, "onclick", ...)
 
local frame = handler.frame
if func then
-- enable mouse
frame:EnableMouse(true)
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
frame:SetScript("OnClick", onClick)
frame.icon:EnableMouse(true)
frame.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
frame.icon:SetScript("OnClick", onClick)
else
frame:EnableMouse(false)
frame:RegisterForClicks()
frame:SetScript("OnClick", nil)
frame.icon:EnableMouse(false)
frame.icon:RegisterForClicks()
frame.icon:SetScript("OnClick", nil)
end
 
return true
 
end
 
-- Set the "on size" function for a group
-- Args: name - name of the candybar
-- func - function to call when a group changes size
-- ... - arguments to pass to the function
-- (the new size of the bar, in pixels, will be appended last)
-- returns true when succesful
function lib:SetOnSizeGroup(name, func, ...)
lib:argCheck(name, 2, "string")
lib:argCheck(func, 3, "function", "nil")
 
local group = assert(lib.groups[name])
 
group.onsize = func
setArgs(group, "onsize", ...)
end
 
 
-- Set the texture for a bar
-- Args: name - name of the candybar
-- texture - new texture, if passed nil, the texture is reset to default
-- returns true when succesful
function lib:SetTexture(name, texture)
lib:argCheck(name, 2, "string")
lib:argCheck(texture, 3, "string", "nil")
 
local handler = lib.handlers[name]
if not handler then
return
end
if not texture then
texture = defaults.texture
end
 
handler.texture = texture
 
handler.frame.statusbar:SetStatusBarTexture(texture)
--handler.frame.statusbarbg:SetStatusBarTexture(texture)
 
return true
end
 
-- Set the icon on a bar
-- Args: name - name of the candybar
-- icon - icon path, nil removes the icon
-- left, right, top, bottom - optional texture coordinates
-- returns true when succesful
function lib:SetIcon(name, icon, left, right, top, bottom)
lib:argCheck(name, 2, "string")
lib:argCheck(icon, 3, "string", "nil")
lib:argCheck(left, 4, "number", "nil")
lib:argCheck(right, 5, "number", "nil")
lib:argCheck(top, 6, "number", "nil")
lib:argCheck(bottom, 7, "number", "nil")
 
local handler = lib.handlers[name]
if not handler then
return
end
handler.icon = icon
 
if not icon then
handler.frame.icon:Hide()
else
left = left or 0.07
right = right or 0.93
top = top or 0.07
bottom = bottom or 0.93
handler.frame.icon:SetNormalTexture(icon)
handler.frame.icon:GetNormalTexture():SetTexCoord(left, right, top, bottom)
handler.frame.icon:Show()
end
 
return true
end
 
-- Set the icon position on bar
-- Args: name - name of the candybar
-- position - icon position, "LEFT" or "RIGHT"
-- returns true when succesful
function lib:SetIconPosition(name, position)
lib:argCheck(name, 2, "string")
lib:argCheck(position, 3, "string", "LEFT", "RIGHT")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.iconpos = position
if handler.running then
handler.frame.icon:SetPoint("LEFT", handler.frame, position, 0, 0)
end
return true
end
 
-- Sets the fading style of a candybar
-- args: name - name of the candybar
-- time - duration of the fade (default .5 seconds), negative to keep the bar on screen
-- returns true when succesful
function lib:SetFade(name, time)
lib:argCheck(name, 2, "string")
lib:argCheck(time, 3, "number")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.fadetime = time
handler.fadeout = true
handler.stayonscreen = (handler.fadetime < 0)
 
return true
end
 
function lib:SetReversed(name, reversed)
lib:argCheck(name, 2, "string")
lib:argCheck(reversed, 3, "string")
 
local tmpdata = nil
if reversed == "1" then
tmpdata = true
elseif reversed == nil then
tmpdata = false
end
 
local handler = lib.handlers[name]
if not handler then
return
end
 
handler.reversed = tmpdata
return true
end
 
function lib:IsReversed(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
 
return handler.reversed
end
 
 
-- Registers a candybar with a certain candybar group
-- args: name - name of the candybar
-- group - group to register the bar with
-- returns true when succesful
function lib:RegisterWithGroup(name, group)
lib:argCheck(name, 2, "string")
lib:argCheck(group, 3, "string")
 
local handler = lib.handlers[name]
local gtable = lib.groups[group]
if not handler or not gtable then
return
end
 
lib:UnregisterWithGroup(name)
 
table.insert(gtable.bars, name)
-- lib.groups[group].bars[name] = name
handler.group = group
lib:UpdateGroup(group)
 
return true
end
 
-- Unregisters a candybar from its group
-- args: name - name of the candybar
-- returns true when succesful
 
function lib:UnregisterWithGroup(name)
lib:argCheck(name, 2, "string")
 
local handler = lib.handlers[name]
if not handler then
return
end
--if not lib.handlers[name].group then return end
 
local group = handler.group
local gtable = lib.groups[group]
if not gtable then
return
end
 
for k,v in pairs(gtable.bars) do
if v == name then
table.remove(gtable.bars, k)
end
end
-- lib.groups[group].bars[name] = nil
handler.group = nil
 
lib:UpdateGroup(group)
 
return true
end
 
-- Register a Candybar group
-- Args: name - name of the candybar group
-- returns true when succesful
function lib:RegisterGroup(name)
lib:argCheck(name, 2, "string")
 
if lib.groups[name] then
return
end
 
local t = new()
 
t.point = "CENTER"
t.rframe = UIParent
t.rpoint = "CENTER"
t.xoffset = 0
t.yoffset = 0
t.bars = new()
t.height = -1
 
lib.groups[name] = t
return true
end
 
-- Unregister a candybar group
-- Args: a1-a2 candybar group ids
-- returns true when succesful
function lib:UnregisterGroup(a1, ...)
lib:argCheck(a1, 2, "string")
if not lib.groups[a1] then
return
end
lib.groups[a1].bars = del(lib.groups[a1].bars)
lib.groups[a1] = del(lib.groups[a1])
 
if ... then
lib:UnregisterGroup(...)
end
 
return true
end
 
-- Checks if a group is registered
-- Args: name - Candybar group
-- returns true if the candybar group is registered
function lib:IsGroupRegistered(name)
lib:argCheck(name, 2, "string")
return lib.groups[name] and true or false
end
 
-- Checks if a bar is registered with a group
-- Args: name - Candybar name
-- group - group id [optional]
-- returns true is the candybar is registered with a/the group
function lib:IsRegisteredWithGroup(name, group)
lib:argCheck(name, 2, "string")
lib:argCheck(group, 3, "string", "nil")
local handler = lib.handlers[name]
if not handler then
return
end
 
if group then
if not lib.groups[group] then
return false
end
if handler.group == group then
return true
end
elseif handler.group then
return true
end
return false
end
 
 
-- Set the point for a CandyBargroup
-- point -- anchor point
-- rframe -- relative frame
-- rpoint -- relative point
-- xoffset [optional] -- x offset
-- yoffset [optional] -- y offset
-- The first bar of the group will be anchored at the anchor.
-- returns true when succesful
function lib:SetGroupPoint(name, point, rframe, rpoint, xoffset, yoffset)
lib:argCheck(name, 2, "string")
lib:argCheck(point, 3, "string")
lib:argCheck(rframe, 4, "string", "table", "nil")
lib:argCheck(rpoint, 5, "string", "nil")
lib:argCheck(xoffset, 6, "number", "nil")
lib:argCheck(yoffset, 6, "number", "nil")
 
local group = lib.groups[name]
if not group then
return
end
 
group.point = point
group.rframe = rframe
group.rpoint = rpoint
group.xoffset = xoffset
group.yoffset = yoffset
lib:UpdateGroup(name)
return true
end
 
-- SetGroupGrowth - sets the group to grow up or down
-- Args: name - name of the candybar group
-- growup - true if growing up, false for growing down
-- returns true when succesful
function lib:SetGroupGrowth(name, growup)
lib:argCheck(name, 2, "string")
lib:argCheck(growup, 3, "boolean")
 
local group = lib.groups[name]
if not group then
return
end
 
group.growup = growup
 
lib:UpdateGroup(name)
 
return true
end
 
-- SetGroupVerticalSpacing - sets a vertical spacing between the bars of the group
-- Args: name - name of the candybar group
-- spacing - y offset for the bars
-- returns true when succesful
function lib:SetGroupVerticalSpacing(name, spacing)
lib:argCheck(name, 2, "string");
lib:argCheck(spacing, 3, "number");
 
local group = lib.groups[name]
if not group then
return
end
 
group.vertspacing = spacing;
 
lib:UpdateGroup(name)
 
return true
end
 
local mysort = function(a, b)
return lib.handlers[a].endtime < lib.handlers[b].endtime
end
function lib:SortGroup(name)
local group = lib.groups[name]
if not group then
return
end
table.sort(group.bars, mysort)
end
 
-- internal method
-- UpdateGroup - updates the location of bars in a group
-- Args: name - name of the candybar group
-- returns true when succesful
 
function lib:UpdateGroup(name)
local group = lib.groups[name]
if not lib.groups[name] then
return
end
 
local point = group.point
local rframe = group.rframe
local rpoint = group.rpoint
local xoffset = group.xoffset
local yoffset = group.yoffset
local m = -1
if group.growup then
m = 1
end
local vertspacing = group.vertspacing or 0
 
local bar = 0
local barh = 0
 
lib:SortGroup(name)
 
for c,n in pairs(group.bars) do
local handler = lib.handlers[n]
if handler then
if handler.frame:IsShown() then
lib:SetPoint(n, point, rframe, rpoint, xoffset, yoffset + (m * bar))
barh = handler.height + 7 or defaults.height
bar = bar + barh + vertspacing
end
end
end
 
if group.height ~= bar then
group.height = bar
if group.onsize then
group.onsize(getArgs(group, "onsize", bar))
end
end
 
return true
end
 
function lib:GetNextBarPointInGroup(name)
lib:argCheck(name, 2, "string")
 
local group = lib.groups[name]
if not lib.groups[name] then
return
end
 
local xoffset = group.xoffset
local yoffset = group.yoffset
local m = -1
if group.growup then
m = 1
end
 
local bar = 0
local barh = 0
 
local vertspacing = group.vertspacing or 0
 
for c,n in pairs(group.bars) do
local handler = lib.handlers[n]
if handler then
if handler.frame:IsShown() then
barh = handler.height or defaults.height
bar = bar + barh + vertspacing
end
end
end
 
return xoffset, yoffset + (m * bar)
end
 
-- Internal Method
-- Update a bar on screen
function lib:Update(name)
local handler = lib.handlers[name]
if not handler then
return
end
 
local t = handler.time - handler.elapsed
handler.slow = t>11
 
local timetext
if handler.timeformat then
timetext = handler.timeformat(t, getArgs(handler, "timeformat"))
else
local h = floor(t/3600)
local m = t - (h*3600)
m = floor(m/60)
local s = t - ((h*3600) + (m*60))
if h > 0 then
timetext = ("%d:%02d"):format(h, m)
elseif m > 0 then
timetext = string.format("%d:%02d", m, floor(s))
elseif s < 10 then
timetext = string.format("%1.1f", s)
else
timetext = string.format("%.0f", floor(s))
end
end
handler.frame.timertext:SetText(timetext)
 
local perc = t / handler.time
 
local reversed = handler.reversed
handler.frame.statusbar:SetValue(reversed and 1-perc or perc)
 
local width = handler.width or defaults.width
 
local sp = width * perc
sp = reversed and -sp or sp
handler.frame.spark:SetPoint("CENTER", handler.frame.statusbar, reversed and "RIGHT" or "LEFT", sp, 0)
 
if handler.gradient then
local p = floor( (handler.elapsed / handler.time) * 100 ) / 100
if not cachedgradient[handler.gradientid][p] then
-- find the appropriate start/end
local gstart, gend, gp
for i = 1, #handler.gradienttable - 1 do
if handler.gradienttable[i][5] < p and p <= handler.gradienttable[i+1][5] then
-- the bounds are to assure no divide by zero error here.
 
gstart = handler.gradienttable[i]
gend = handler.gradienttable[i+1]
gp = (p - gstart[5]) / (gend[5] - gstart[5])
end
end
if gstart and gend then
-- calculate new gradient
cachedgradient[handler.gradientid][p] = new()
local i
for i = 1, 4 do
-- these may be the same.. but I'm lazy to make sure.
cachedgradient[handler.gradientid][p][i] = gstart[i]*(1-gp) + gend[i]*(gp)
end
end
end
if cachedgradient[handler.gradientid][p] then
handler.frame.statusbar:SetStatusBarColor(unpack(cachedgradient[handler.gradientid][p], 1, 4))
end
end
end
 
-- Intenal Method
-- Fades the bar out when it's complete.
function lib:UpdateFade(name)
local handler = lib.handlers[name]
if not handler then
return
end
if not handler.fading then
return
end
if handler.stayonscreen then
return
end
 
-- if the fade is done go and keel the bar.
if handler.fadeelapsed > handler.fadetime then
handler.fading = nil
handler.starttime = nil
handler.endtime = 0
handler.frame:Hide()
if handler.group then
lib:UpdateGroup(handler.group)
end
if handler.fireforget then
return lib:Unregister(name)
end
else -- we're fading, set the alpha for the texts, statusbar and background. fade from default to 0 in the time given.
local t = handler.fadetime - lib.handlers[name].fadeelapsed
local p = t / handler.fadetime
local color = handler.color or defaults.color
local bgcolor = handler.bgcolor or defaults.bgcolor
local textcolor = handler.textcolor or defaults.textcolor
local timertextcolor = handler.timertextcolor or defaults.timertextcolor
local colora = color[4] * p
local bgcolora = bgcolor[4] * p
local textcolora = textcolor[4] * p
local timertextcolora = timertextcolor[4] * p
 
handler.frame.statusbarbg:SetStatusBarColor(bgcolor[1], bgcolor[2], bgcolor[3], bgcolora)
handler.frame.statusbar:SetStatusBarColor(color[1], color[2], color[3], colora)
handler.frame.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolora)
handler.frame.timertext:SetTextColor(timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolora)
handler.frame.icon:SetAlpha(p)
end
return true
end
 
-- Internal Method
-- Create and return a new bar frame, recycles where needed
-- Name - which candybar is this for
-- Returns the frame
function lib:AcquireBarFrame(name)
local handler = lib.handlers[name]
if (not handler) then return; end
 
local f = handler.frame;
----------------------------------------
local color, bgcolor = handler.color or defaults.color, handler.bgcolor or defaults.bgcolor;
local icon, iconpos = handler.icon or nil, handler.iconpos or defaults.iconpos;
local texture = handler.texture or defaults.texture;
local width, height = handler.width or defaults.width, handler.height or defaults.height;
 
local point, rpoint = handler.point or defaults.point, handler.rpoint or defaults.rpoint;
local rframe = handler.rframe or defaults.rframe;
local xoffset, yoffset = handler.xoffset or defaults.xoffset, handler.yoffset or defaults.yoffset;
 
local text = handler.text or defaults.text
local fontsize = handler.fontsize or defaults.fontsize
local textcolor = handler.textcolor or defaults.textcolor
local timertextcolor = handler.timertextcolor or defaults.timertextcolor
local scale = handler.scale or defaults.scale
----------------------------------------
if (not scale) then scale = 1; end
local timertextwidth = fontsize * 3.6;
local font, _, style = GameFontHighlight:GetFont();
----------------------------------------
if (not f) and (#lib.framepool > 0) then f = table.remove(lib.framepool); end
if (not f) then f = CreateFrame("Button", nil, UIParent) end
f:Hide(); f.owner = name;
f:SetWidth(width+10); f:SetHeight(height+10); f:ClearAllPoints();
f:SetPoint(point, rframe, rpoint, xoffset, yoffset); f:EnableMouse(false);
f:RegisterForClicks(); f:SetScript("OnClick", nil); f:SetScale(scale);
f:SetBackdrop{bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16,
edgeSize = 16, insets = {left = 5, right = 5, top = 5, bottom = 5}};
f:SetBackdropColor(0,0,0,0.35);
----------------------------------------
if (not f.statusbar) then f.statusbar = CreateFrame("StatusBar", nil, f); end
f.statusbar:ClearAllPoints();
f.statusbar:SetHeight(height); f.statusbar:SetWidth(width);
f.statusbar:SetPoint("CENTER",f,"CENTER",0,0);
f.statusbar:SetStatusBarTexture(texture);
f.statusbar:SetStatusBarColor(color[1], color[2], color[3], color[4]);
f.statusbar:SetMinMaxValues(0,1); f.statusbar:SetValue(1);
----------------------------------------
if (not f.icon) then f.icon = CreateFrame("Button", nil, f); end
f.icon:ClearAllPoints(); f.icon.owner = name;
f.icon:EnableMouse(false); f.icon:RegisterForClicks(); f.icon:SetScript("OnClick", nil);
f.icon:SetHeight(height); f.icon:SetWidth(height);
if (iconpos == "LEFT") then f.icon:SetPoint("RIGHT",f,"LEFT",0,0); else f.icon:SetPoint("LEFT",f,"RIGHT",0,0); end
f.icon:SetNormalTexture(icon);
if (f.icon:GetNormalTexture()) then f.icon:GetNormalTexture():SetTexCoord(0.07,0.93,0.07,0.93); end
f.icon:SetAlpha(1); f.icon:Show();
----------------------------------------
if (not f.spark) then f.spark = f.statusbar:CreateTexture(nil, "OVERLAY"); end
f.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark");
f.spark:SetWidth(32); f.spark:SetHeight(32);
f.spark:SetBlendMode("ADD"); f.spark:Show();
----------------------------------------
if (not f.timertext) then f.timertext = f.statusbar:CreateFontString(nil, "OVERLAY"); end
f.timertext:SetFontObject(GameFontHighlight)
f.timertext:SetFont(font, fontsize, style)
f.timertext:SetHeight(height)
f.timertext:SetWidth(timertextwidth)
if (iconpos == "LEFT") then
f.timertext:SetPoint("LEFT",f,"RIGHT",4,0);
f.timertext:SetJustifyH("LEFT");
else
f.timertext:SetPoint("RIGHT", f, "LEFT", -4, 0);
f.timertext:SetJustifyH("RIGHT");
end
f.timertext:SetText("")
f.timertext:SetTextColor(timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolor[4]);
----------------------------------------
if (not f.text) then f.text = f.statusbar:CreateFontString(nil, "OVERLAY"); end
f.text:SetFontObject(GameFontHighlight);
f.text:SetFont(font, fontsize, style);
f.text:SetHeight(height); f.text:SetWidth(width);
f.text:SetPoint("CENTER", f.statusbar, "CENTER", 0, 0);
f.text:SetJustifyH("CENTER"); f.text:SetText(text);
f.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolor[4]);
----------------------------------------
if (handler.onclick) then
f:EnableMouse(true);
f:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up");
f:SetScript("OnClick", onClick);
f.icon:EnableMouse(true);
f.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up");
f.icon:SetScript("OnClick", onClick);
end
return f;
end
 
-- Internal Method
-- Releases a bar frame into the pool
-- Name - which candybar's frame are we're releasing
-- Returns true when succesful
function lib:ReleaseBarFrame(name)
local handler = lib.handlers[name]
if not handler then
return
end
if not handler.frame then
return
end
handler.frame:Hide()
table.insert(lib.framepool, handler.frame)
return true
end
 
-- Internal Method
-- Executes the OnClick function of a bar
function lib:OnClick()
if not this.owner then
return
end
local handler = lib.handlers[this.owner]
if not handler then
return
end
if not handler.onclick then
return
end
-- pass the name of the handlers first, and the button clicked as the second argument
local button = arg1
handler.onclick(this.owner, button, getArgs(handler, "onclick"))
return true
end
 
-- Internal Method
-- on update handler
local lastSlow = 0
function lib.OnUpdate(self, elapsed)
local doslow
lastSlow = lastSlow + elapsed
if lastSlow > 0.04 then
doslow = true
lastSlow = 0
end
 
local t
for i,v in pairs(lib.handlers) do
if not t then t = GetTime() end
if (not doslow) and v.slow then
-- nada
elseif v.running then
v.elapsed = t - v.starttime
if v.endtime <= t then
local c = lib.handlers[i]
if c.completion then
if not c.completion(getArgs(c, "completion")) then
lib:Stop(i)
end
else
lib:Stop(i)
end
else
lib:Update(i)
end
elseif v.fading and not v.stayonscreen then
v.fadeelapsed = (t - v.endtime)
lib:UpdateFade(i)
end
end
end
 
-- Internal Method
-- returns true if we have any handlers
function lib:HasHandlers()
return next(lib.handlers) and true
end
 
------------------------------
-- Mixins Methods --
------------------------------
 
lib.IsCandyBarRegistered = lib.IsRegistered
lib.StartCandyBar = lib.Start
lib.StopCandyBar = lib.Stop
lib.PauseCandyBar = lib.Pause
lib.CandyBarStatus = lib.Status
lib.SetCandyBarTexture = lib.SetTexture
lib.SetCandyBarTime = lib.SetTime
lib.SetCandyBarColor = lib.SetColor
lib.SetCandyBarText = lib.SetText
lib.SetCandyBarIcon = lib.SetIcon
lib.SetCandyBarIconPosition = lib.SetIconPosition
lib.SetCandyBarBackgroundColor = lib.SetBackgroundColor
lib.SetCandyBarTextColor = lib.SetTextColor
lib.SetCandyBarTimerTextColor = lib.SetTimerTextColor
lib.SetCandyBarFontSize = lib.SetFontSize
lib.SetCandyBarPoint = lib.SetPoint
lib.GetCandyBarPoint = lib.GetPoint
lib.GetCandyBarCenter = lib.GetCenter
lib.GetCandyBarOffsets = lib.GetOffsets
lib.GetCandyBarEffectiveScale = lib.GetEffectiveScale
lib.SetCandyBarScale = lib.SetScale
lib.SetCandyBarTimeFormat = lib.SetTimeFormat
lib.SetCandyBarTimeLeft = lib.SetTimeLeft
lib.SetCandyBarCompletion = lib.SetCompletion
lib.RegisterCandyBarGroup = lib.RegisterGroup
lib.UnregisterCandyBarGroup = lib.UnregisterGroup
lib.IsCandyBarGroupRegistered = lib.IsGroupRegistered
lib.SetCandyBarGroupPoint = lib.SetGroupPoint
lib.SetCandyBarGroupGrowth = lib.SetGroupGrowth
lib.SetCandyBarGroupVerticalSpacing = lib.SetGroupVerticalSpacing
lib.UpdateCandyBarGroup = lib.UpdateGroup
lib.GetCandyBarNextBarPointInGroup = lib.GetNextBarPointInGroup
lib.SetCandyBarOnClick = lib.SetOnClick
lib.SetCandyBarFade = lib.SetFade
lib.RegisterCandyBarWithGroup = lib.RegisterWithGroup
lib.UnregisterCandyBarWithGroup = lib.UnregisterWithGroup
lib.IsCandyBarRegisteredWithGroup = lib.IsRegisteredWithGroup
lib.SetCandyBarReversed = lib.SetReversed
lib.IsCandyBarReversed = lib.IsReversed
lib.SetCandyBarOnClick = lib.SetOnClick
lib.SetCandyBarHeight = lib.SetHeight
lib.SetCandyBarWidth = lib.SetWidth
lib.SetCandyBarOnSizeGroup = lib.SetOnSizeGroup
 
function lib:RegisterCandyBar(name, time, text, icon, ...)
if not lib.addons[self] then
lib.addons[self] = new()
end
lib.addons[self][name] = lib:Register(name, time, text, icon, ...)
end
 
function lib:UnregisterCandyBar(a1, ...)
lib:argCheck(a1, 2, "string")
if lib.addons[self] then
lib.addons[self][a1] = nil
end
lib:Unregister(a1)
if ... then
self:UnregisterCandyBar(...)
end
end
 
function lib:OnEmbedDisable(target)
if self.addons[target] then
for i in pairs(self.addons[target]) do
self:Unregister(i)
end
end
end
 
function lib:Embed(target)
for k, v in pairs(mixins) do
target[v] = lib[v]
end
self.embeds[target] = true
return target
end
 
-- last step of upgrading
 
lib.frame:SetScript("OnUpdate", lib.OnUpdate)
 
for target, v in pairs(lib.embeds) do
lib:Embed(target)
end
 
 
StunWatch/Libs/LibCandyBar/Readme.txt New file
0,0 → 1,3
This LibCandyBar has been edited slightly to work well with the original design of StunWatch pre2.4
 
ALL credit goes to Ammo the creator of CandyBar
\ No newline at end of file
StunWatch/Libs/LibCandyBar/LibCandyBar.toc New file
0,0 → 1,8
## Interface: 20400
## Title: Lib: CandyBar-2.1
## Notes: Timerbar embeddable library
## Version: 2.1
## Author: Ammo
 
LibStub.lua
LibCandyBar.lua
StunWatch/Libs/LibCandyBar/LibStub.lua New file
0,0 → 1,30
-- 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]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
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
 
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
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
StunWatch/Libs/LibStub/LibStub.lua New file
0,0 → 1,30
-- 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]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
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
 
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
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
StunWatch/Libs/LibStub/LibStub.toc New file
0,0 → 1,9
## Interface: 20100
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS | http://www.wowace.com/wiki/LibStub
## X-Category: Library
## X-License: Public Domain
 
LibStub.lua
StunWatch/StunWatch.lua New file
0,0 → 1,239
---------------------------------------------
-- StunWatch v2.1 BETA2
-- Changes:
----Removed Realm name from Cross Realm Players
----Changed the way SpellDB works
----Added option for Grow up/down
----Implemented blizzard interface options
 
-- TODO:
----Add Diminishing returns
---------------------------------------------
StunWatchDB = StunWatchDB or { Lock = 1, Invert = "1", Growth = 0, }
 
local StunWatchFrame
local StunWatchName = "StunWatchBars"
local StunWatchActiveCP = 0
local candy = LibStub:GetLibrary("LibCandyBar")
---------------------------------------------
-- Spell DB
-- Only need Rank 1 as we take the Name of the SpellDB Id and compare it to the Name of the combat event ID
-- Hack for sap atm, for different durations
---------------------------------------------
local SpellDBName = { }
local SpellDB = {
-- Cheap Shot
[1833] = { Duration = 4 },
-- Kidney Shot
[408] = { Duration = 1, Combo = true },
-- Mace Stun
[5530] = { Duration = 3 },
-- Blade Twisting
[31124] = { Duration = 8},
-- Blind
[2094] = { Duration = 10 },
-- Gouge
[1776] = { Duration = 4 },
-- Sap
[6770] = { Duration = 25, PVPDur = 8 },
[2070] = { Duration = 35, PVPDur = 8 },
[11297] = { Duration = 45, PVPDur = 8 },
-- Expose Armor
[8647] = { Duration = 30 },
-- Rupture
[1943] = { Duration = 6, Combo = true },
-- Garrote
[703] = { Duration = 18 },
}
for k, v in pairs(SpellDB) do
SpellDBName[GetSpellInfo(k)] = v
end
---------------------------------------------
-- KillTimer
---------------------------------------------
function KillTimer(self, id)
if (candy:IsCandyBarRegistered(StunWatchName..id)) then
candy:StopCandyBar(StunWatchName..id)
candy:UnregisterCandyBar(StunWatchName..id)
end
end
---------------------------------------------
-- StartTimer
---------------------------------------------
function StartTimer(self, id, time, srcName, spellName, invert)
if (candy:IsCandyBarRegistered(StunWatchName..id)) then
candy:SetCandyBarTimeLeft(StunWatchName..id, time)
else
candy:RegisterCandyBar(StunWatchName..id, time, spellName..": "..srcName, nil, 1, 1, 0)
candy:SetCandyBarReversed(StunWatchName..id, invert)
candy:RegisterCandyBarWithGroup(StunWatchName..id, StunWatchName)
candy:SetWidth(StunWatchName..id, 160)
candy:SetHeight(StunWatchName..id, 10)
candy:StartCandyBar(StunWatchName..id, true)
end
end
---------------------------------------------
-- FindImpGouge
---------------------------------------------
function FindImpGouge()
local _, texture, _, _, rank, _, _, _ = GetTalentInfo(2, 1)
if (texture) then
SpellDB[1776].Duration = 4 + rank * 0.5
end
end
---------------------------------------------
-- Blizzard Interface Options
---------------------------------------------
function StunWatch_CreateOptions(self, title)
local panel = CreateFrame("Frame", "StunWatchOptions", self)
panel.name = "StunWatch"
--Create Lock checkbox
local LockButton = CreateFrame("CheckButton", "LockCheck", panel, "OptionsCheckButtonTemplate")
LockCheckText:SetText("Lock StunWatch Bars")
LockCheckText:SetTextColor(1, 1, 1)
LockButton:SetPoint("TOPLEFT", panel, "TOPLEFT", 10, -30)
LockButton:SetScript("OnShow", function(self) self:SetChecked(StunWatchDB.Lock) end)
LockButton:SetScript("OnClick", function(self)
StunWatchDB.Lock = self:GetChecked()
if (StunWatchDB.Lock) then
StunWatchFrame:EnableMouse(false)
StunWatchFrame:Hide()
else
StunWatchFrame:EnableMouse(true)
StunWatchFrame:Show()
end
end)
--Create Invert checkbox
local InvertButton = CreateFrame("CheckButton", "InvertCheck", panel, "OptionsCheckButtonTemplate")
InvertCheckText:SetText("Invert Bars")
InvertCheckText:SetTextColor(1,1,1)
InvertButton:SetPoint("TOPLEFT", LockButton, "TOPLEFT", 0, -25)
InvertButton:SetScript("OnShow", function(self) self:SetChecked(StunWatchDB.Invert) end)
InvertButton:SetScript("OnClick", function(self)
StunWatchDB.Invert = tostring(self:GetChecked())
end)
--Create Growth checkbox
local GrowButton = CreateFrame("CheckButton", "GrowCheck", panel, "OptionsCheckButtonTemplate")
GrowCheckText:SetText("Grow Up")
GrowCheckText:SetTextColor(1,1,1)
GrowButton:SetPoint("TOPLEFT", InvertButton, "TOPLEFT", 0, -25)
GrowButton:SetScript("OnShow", function(self) self:SetChecked(StunWatchDB.Growth) end)
GrowButton:SetScript("OnClick", function(self) --????????wtf at this part
StunWatchDB.Growth = self:GetChecked()
if (StunWatchDB.Growth) then -- /sigh
candy:SetCandyBarGroupGrowth(StunWatchName, true)
else
candy:SetCandyBarGroupGrowth(StunWatchName, false)
end
end)
--Create Header Text
local HeaderText = panel:CreateFontString(nil, panel)
HeaderText:SetFontObject("GameFontNormal")
HeaderText:SetTextHeight(22)
local ver = GetAddOnMetadata("StunWatch", "Version")
HeaderText:SetText("StunWatch v"..ver)
HeaderText:SetPoint("CENTER", panel, "TOPLEFT", 85, -15)
--Create Info Text
local InfoText = panel:CreateFontString(nil, panel)
InfoText:SetFontObject("GameFontNormal")
InfoText:SetTextHeight(14)
InfoText:SetTextColor(1,1,1)
InfoText:SetText("StunWatch displays progress bars for Rogue stuns.\n\nOptions:\nLock - Lock/Unlock position of bars\nInvert - Invert filling of bar\nGrow up - Grow new bars up or down")
InfoText:SetPoint("TOPLEFT", "GrowCheck", "TOPLEFT", 0, -35)
InterfaceOptions_AddCategory(panel)
end
---------------------------------------------
-- OnLoad
---------------------------------------------
function StunWatch_OnLoad(self)
if (not StunWatchDB.Lock) then StunWatchDB.Lock = 1 end
if (not StunWatchDB.Invert) then StunWatchDB.Invert = "1" end
if (not StunWatchDB.Growth) then StunWatchDB.Growth = 0 end
--Register slash cmd
StunWatch_CreateOptions(UIParent, "lols")
SlashCmdList["StunWatch"] = function()
InterfaceOptionsFrame_OpenToFrame(_G["StunWatchOptions"])
end
SLASH_StunWatch1 = "/sw"
SLASH_StunWatch2 = "/stunwatch"
--Print Version
local ver = GetAddOnMetadata("StunWatch", "Version")
ChatFrame1:AddMessage("StunWatch Ver: "..ver.. " Loaded! /sw or /stunwatch for options!", 0, 1, 0)
--Add Anchor to StunWatchFrame
StunWatchFrame:SetWidth("170")
StunWatchFrame:SetHeight("20")
StunWatchFrame:SetBackdrop({
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
tile = true,
tileSize = 16,
edgeSize = 0,
insets = { left = 0, right = 0, top = 0, bottom = 0 },
})
StunWatchFrame:SetClampedToScreen(true)
StunWatchFrame:SetMovable(true)
StunWatchFrame:EnableMouse(true) --hack until options are done..
StunWatchFrame:SetPoint("CENTER", UIParent, "CENTER", 0 ,0)
StunWatchFrame.Text = StunWatchFrame:CreateFontString(nil, "OVERLAY")
StunWatchFrame.Text:SetFontObject("GameFontNormal")
StunWatchFrame.Text:SetWidth(170)
StunWatchFrame.Text:SetHeight(15)
StunWatchFrame.Text:SetPoint("CENTER")
StunWatchFrame.Text:SetText(StunWatchName)
--SetScripts
StunWatchFrame:SetScript("OnMouseDown", function(self, button) if (button == "LeftButton") then self:StartMoving(); end end)
StunWatchFrame:SetScript("OnMouseUp", function(self, button) if (button == "LeftButton") then self:StopMovingOrSizing(); end end)
if (not StunWatchDB.Lock) then StunWatchFrame:Show() else StunWatchFrame:Hide() end
--Register CandyBars
candy:RegisterCandyBarGroup(StunWatchName)
candy:SetCandyBarGroupPoint(StunWatchName, "BOTTOM", StunWatchFrame, "BOTTOM", 0, 0)
if (StunWatchDB.Growth) then candy:SetCandyBarGroupGrowth(StunWatchName, true) else
candy:SetCandyBarGroupGrowth(StunWatchName, false) end
--Find Improved gouge
FindImpGouge()
end
---------------------------------------------
-- OnEvent
---------------------------------------------
function StunWatch_OnEvent(self, event, ...)
if (event == "VARIABLES_LOADED") then
StunWatch_OnLoad(self)
elseif (event == "COMBAT_LOG_EVENT_UNFILTERED") then
local _, cmbEvent, srcGUID, srcName, _, dstGUID, dstName, _ = select(1, ...)
if (cmbEvent == "SPELL_AURA_APPLIED") then
local spellID = arg9
local name = GetSpellInfo(spellID)
local tname = string.match(dstName, "[^-]*")
--Combo Point check
if (GetComboPoints() > 0) then StunWatchActiveCP = GetComboPoints() end
if (UnitGUID("target") == dstGUID) then
if (SpellDBName[name]) then
if (UnitIsPlayer("target") and SpellDBName[name].PVPDur) then
StartTimer(StunWatchName, spellID, SpellDBName[name].PVPDur, tname, name, StunWatchDB.Invert) --Update to StunWatchDB.Invert
elseif (StunWatchActiveCP and SpellDBName[name].Combo) then --ghetto hack for combo points..
if (GetSpellInfo(spellID) == "Kidney Shot") then
StartTimer(StunWatchName, spellID, SpellDBName[name].Duration + StunWatchActiveCP, tname, name, StunWatchDB.Invert)
elseif (GetSpellInfo(spellID) == "Rupture") then
StartTimer(StunWatchName, spellID, SpellDBName[name].Duration + StunWatchActiveCP + StunWatchActiveCP, tname, name, StunWatchDB.Invert)
end
else
StartTimer(StunWatchName, spellID, SpellDBName[name].Duration, tname, name, StunWatchDB.Invert) --Update to StunWatchDB.Invert
end
end
end
elseif (cmbEvent == "SPELL_AURA_REMOVED" or cmbEvent == "SPELL_AURA_DISPELLED") then
local spellID = arg9
if (SpellDB[spellID]) then
KillTimer(StunWatchName, spellID)
end
end
else
return
end
end
---------------------------------------------
-- CreateFrame
---------------------------------------------
StunWatchFrame = CreateFrame("Frame", "StunWatchMainFrame", UIParent)
StunWatchFrame:RegisterEvent("VARIABLES_LOADED")
StunWatchFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
StunWatchFrame:SetScript("OnEvent", StunWatch_OnEvent)
\ No newline at end of file
StunWatch/StunWatch.toc New file
0,0 → 1,10
## Interface: 20400
## Title: StunWatch
## Author: Macca
## Version: 2.1
## Notes: Displays a progress bar for Rogue abilites
## SavedVariables: StunWatchDB
 
Libs\LibStub\LibStub.lua
Libs\LibCandyBar\LibCandyBar.lua
StunWatch.lua