WoWInterface SVN pStats

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

pStats/Libs/LibDataBroker-1.1.lua New file
0,0 → 1,90
 
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
pStats/Libs/LibStub.lua New file
0,0 → 1,51
-- $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
pStats/Libs/CallbackHandler-1.0.lua New file
0,0 → 1,239
--[[ $Id: CallbackHandler-1.0.lua 3 2008-09-29 16:54:20Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 3
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}
 
local type = type
local pcall = pcall
local pairs = pairs
local assert = assert
local concat = table.concat
local loadstring = loadstring
local next = next
local select = select
local type = type
local xpcall = xpcall
 
local function errorhandler(err)
return geterrorhandler()(err)
end
 
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
 
local method, ARGS
local function call() method(ARGS) end
 
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
 
return dispatch
]]
 
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
 
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
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(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
 
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
 
Dispatchers[select('#', ...) + 1](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 eventname,callbacks in pairs(registry.insertQueue) do
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.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
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"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string 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.
 
pStats/Libs/LibSimpleOptions-1.0.lua New file
0,0 → 1,955
--[[
Name: LibSimpleOptions-1.0
Revision: $Rev: 81443 $
Author(s): ckknight (ckknight@gmail.com)
Website: http://ckknight.wowinterface.com/
Description: A library to provide a way to easily create controls for Blizzard's options system
License: MIT
]]
 
local MAJOR_VERSION = "LibSimpleOptions-1.0"
local MINOR_VERSION = tonumber(("$Revision: 81443 $"):match("(%d+)"))
 
if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end
 
-- #AUTODOC_NAMESPACE LibSimpleOptions
 
local LibSimpleOptions, oldLib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
if not LibSimpleOptions then
return
end
if oldLib then
oldLib = {}
for k, v in pairs(LibSimpleOptions) do
LibSimpleOptions[k] = nil
oldLib[k] = v
end
end
 
local getArgs, doneArgs
do
local tmp = {}
function getArgs(...)
assert(next(tmp) == nil)
for i = 1, select('#', ...), 2 do
local k, v = select(i, ...)
if type(k) ~= "string" then
error(("Received a bad key, must be a %q, got %q (%s)"):format("string", type(k), tostring(k)), 3)
elseif tmp[k] ~= nil then
error(("Received key %q twice"):format(k), 3)
end
tmp[k] = v
end
return tmp
end
function doneArgs(args)
assert(args == tmp)
for k in pairs(args) do
args[k] = nil
end
return nil
end
end
 
local WotLK = not not ToggleAchievementFrame
 
local panels
if oldLib then
panels = oldLib.panels or {}
else
panels = {}
end
LibSimpleOptions.panels = panels
 
local panelMeta
if oldLib then
panelMeta = oldLib.panelMeta or {}
else
panelMeta = {}
end
LibSimpleOptions.panelMeta = panelMeta
for funcName in pairs(panelMeta) do
for panel in pairs(panels) do
panel[funcName] = nil
end
panelMeta[funcName] = nil
end
 
do
local function update(control, ...)
if (...) ~= control.value then
control:SetValue(...)
end
end
--- Refresh a panel's controls
-- This updates any controls that provide a getFunc
-- When a panel is shown, this is automatically called
-- @name panel:Refresh
-- @usage panel:Refresh()
function panelMeta:Refresh()
for control in pairs(self.controls) do
if control.getFunc then
update(control, control.getFunc())
end
end
if self.refreshFunc then
self:refreshFunc()
end
end
local function panel_OnShow(self)
self:SetScript("OnShow", self.Refresh)
self:controlCreationFunc()
self.controlCreationFunc = nil
self:Refresh()
end
local function panel_okay(self)
for control in pairs(self.controls) do
control.oldValue = control.value
if control.okayFunc then
control.okayFunc()
end
end
end
local function panel_cancel(self)
for control in pairs(self.controls) do
control:SetValue(control.oldValue)
if control.cancelFunc then
control.cancelFunc()
end
end
end
local function panel_default(self)
for control in pairs(self.controls) do
control:SetValue(control.default)
if control.defaultFunc then
control.defaultFunc()
end
end
end
local function makePanel(name, parentName, controlCreationFunc)
local panel
if not parentName then
panel = CreateFrame("Frame", name .. "_Panel")
else
panel = CreateFrame("Frame", parentName .. "_Panel_" .. name)
end
panels[panel] = true
 
panel.name = name
panel.controls = {}
panel.parent = parentName
 
panel.okay = panel_okay
panel.cancel = panel_cancel
panel.default = panel_default
 
InterfaceOptions_AddCategory(panel)
 
panel.controlCreationFunc = controlCreationFunc
panel:SetScript("OnShow", panel_OnShow)
for k, v in pairs(panelMeta) do
panel[k] = v
end
end
 
--- Make a new options panel and add it to the Blizzard Interface Options
-- @param name name of your panel
-- @param controlCreationFunc function to call when the panel is first shown
-- @usage LibStub("LibSimpleOptions-1.0").AddOptionsPanel("My Options", function(panel) ... end)
-- @return the created panel
function LibSimpleOptions.AddOptionsPanel(name, controlCreationFunc)
return makePanel(name, nil, controlCreationFunc)
end
 
--- Make a new options panel that is a child of another options panel and add it to the Blizzard Interface Options
-- @param parentName name of the parent panel
-- @param name name of your panel
-- @param controlCreationFunc function to call when the panel is first shown
-- @usage LibStub("LibSimpleOptions-1.0").AddOptionsPanel("My Options", "My Suboptions", function(panel) ... end)
-- @return the created panel
function LibSimpleOptions.AddSuboptionsPanel(parentName, name, controlCreationFunc)
return makePanel(name, parentName, controlCreationFunc)
end
end
 
--- Return a new title text and sub-text for a panel.
-- Note that this automatically places the title and sub-text appropriately
-- @name panel:MakeTitleTextAndSubText
-- @param titleText the text to show as the title
-- @param subTextText the text to show as the sub-text
-- @usage local title, subText = panel:MakeTitleTextAndSubText("My Options", "These allow you to change assorted options")
-- @return the title FontString
-- @return the sub-text FontString
function panelMeta:MakeTitleTextAndSubText(titleText, subTextText)
local title = self:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
title:SetText(titleText)
title:SetJustifyH("LEFT")
title:SetJustifyV("TOP")
title:SetPoint("TOPLEFT", 16, -16)
 
local subText = self:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
subText:SetText(subTextText)
subText:SetNonSpaceWrap(true)
subText:SetJustifyH("LEFT")
subText:SetJustifyV("TOP")
subText:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
subText:SetPoint("RIGHT", -32, 0)
 
return title, subText
end
 
do
local backdrop = {
bgFile = [=[Interface\Buttons\WHITE8X8]=],
edgeFile = [=[Interface\Tooltips\UI-Tooltip-Border]=],
tile = true,
tileSize = 16,
edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 },
}
--- Return a scrollable frame to organize controls within
-- This is useful to create if you have too many controls to properly fit within one panel
-- @name panel:MakeScrollFrame
-- @usage local scrollFrame = panel:MakeScrollFrame()
-- @return the ScrollFrame
function panelMeta:MakeScrollFrame()
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_ScrollFrame" .. i
until not _G[name]
local scrollFrame = CreateFrame("ScrollFrame", name, self, "UIPanelScrollFrameTemplate")
scrollFrame:SetFrameLevel(scrollFrame:GetFrameLevel() + 1)
local bg = CreateFrame("Frame", nil, self)
bg:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", -3, 3)
bg:SetPoint("BOTTOMRIGHT", scrollFrame, "BOTTOMRIGHT", 3, -3)
bg:SetBackdrop(backdrop)
bg:SetBackdropColor(0, 0, 0, 0.25)
local scrollChild = CreateFrame("Frame", name .. "_Child", scrollFrame)
scrollFrame:SetScrollChild(scrollChild)
scrollChild:SetWidth(1)
scrollChild:SetHeight(1)
return scrollFrame, scrollChild
end
end
 
do
local function slider_OnValueChanged(self)
self.value = self:GetValue()
self:SetValue(self:GetValue())
end
 
local function slider_SetValue(self, value)
getmetatable(self).__index.SetValue(self, value)
self.value = value
self.changeFunc(value)
if self.currentText then
self.currentText:SetText(self.currentTextFunc(value))
end
end
 
--- Return a horizontal slider
-- This is primarily for manipulating numbers within a range
-- @name panel:MakeSlider
-- @param ... tuple of key-value pairs<br/>
-- name: What the slider displays above it<br/>
-- description: What the tooltip displays when hovering over<br/>
-- minText: What the slider shows on the left side<br/>
-- maxText: What the slider shows on the right side<br/>
-- minValue: The minimum value of the slider<br/>
-- maxValue: The maximum value of the slider<br/>
-- [optional] step: The amount that the slider steps between movements<br/>
-- default: The default value<br/>
-- current: The current value - can provide either this or getFunc<br/>
-- getFunc: Function to get the current value<br/>
-- setFunc: What is called when the value changes<br/>
-- [optional] currentTextFunc: What is called to get text value at the bottom<br/>
-- [optional] okayFunc: Called when the okay button is pressed<br/>
-- [optional] cancelFunc: Called when the cancel button is pressed<br/>
-- [optional] defaultFunc: Called when the default button is pressed
-- @usage panel:MakeSlider(
-- 'name', 'Range',
-- 'description', 'Specify your tooltip description',
-- 'minText', '0%',
-- 'maxText', '100%',
-- 'minValue', 0,
-- 'maxValue', 1,
-- 'step', 0.05,
-- 'default', 0.5,
-- 'current', db.currentRange,
-- 'setFunc', function(value) db.currentRange = value end,
-- 'currentTextFunc', function(value) return ("%.0f%%"):format(value * 100) end
-- )
-- @return the Slider
function panelMeta:MakeSlider(...)
local args = getArgs(...)
if type(args.name) ~= "string" then
error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2)
elseif type(args.description) ~= "string" then
error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2)
elseif type(args.minText) ~= "string" then
error(("minText must be %q, got %q (%s)"):format("string", type(args.minText), tostring(args.minText)), 2)
elseif type(args.maxText) ~= "string" then
error(("maxText must be %q, got %q (%s)"):format("string", type(args.maxText), tostring(args.maxText)), 2)
elseif type(args.minValue) ~= "number" then
error(("minValue must be %q, got %q (%s)"):format("number", type(args.minValue), tostring(args.minValue)), 2)
elseif type(args.maxValue) ~= "number" then
error(("maxValue must be %q, got %q (%s)"):format("number", type(args.maxValue), tostring(args.maxValue)), 2)
elseif args.step and type(args.step) ~= "number" then
error(("step must be %q or %q, got %q (%s)"):format("nil", "number", type(args.step), tostring(args.step)), 2)
elseif type(args.default) ~= "number" then
error(("default must be %q, got %q (%s)"):format("number", type(args.default), tostring(args.default)), 2)
elseif args.default < args.minValue or args.default > args.maxValue then
error(("default must be [%s, %s], got %s"):format(args.minValue, args.maxValue, tostring(args.default)), 2)
elseif not args.current == not args.getFunc then
error(("either current or getFunc must be supplied, but not both"), 2)
elseif args.current and type(args.current) ~= "number" then
error(("current must be %q, got %q (%s)"):format("number", type(args.current), tostring(args.current)), 2)
elseif args.getFunc and type(args.getFunc) ~= "function" then
error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2)
elseif type(args.setFunc) ~= "function" then
error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2)
elseif args.currentTextFunc and type(args.currentTextFunc) ~= "function" then
error(("currentTextFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.currentTextFunc), tostring(args.currentTextFunc)), 2)
elseif args.okayFunc and type(args.okayFunc) ~= "function" then
error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2)
elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then
error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2)
elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then
error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2)
end
 
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_Slider" .. i
until not _G[name]
local slider = CreateFrame("Slider", name, self, "InterfaceOptionsSliderTemplate")
self.controls[slider] = true
_G[slider:GetName() .. "Text"]:SetText(args.name)
slider.tooltipText = args.description
_G[slider:GetName() .. "Text"]:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
_G[slider:GetName() .. "Low"]:SetText(args.minText)
_G[slider:GetName() .. "Low"]:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
_G[slider:GetName() .. "High"]:SetText(args.maxText)
_G[slider:GetName() .. "High"]:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
 
local current
if args.getFunc then
slider.getFunc = args.getFunc
current = args.getFunc()
else
current = args.current
end
 
if args.currentTextFunc then
slider.currentTextFunc = args.currentTextFunc
local currentText = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
slider.currentText = currentText
currentText:SetPoint("TOP", slider, "CENTER", 0, -8)
currentText:SetText(args.currentTextFunc(current))
end
 
slider.default = args.default
slider:SetMinMaxValues(args.minValue, args.maxValue)
if args.step then
slider:SetValueStep(args.step)
end
slider.oldValue = current
slider.value = current
slider:SetValue(current)
slider.changeFunc = args.setFunc
slider.SetValue = slider_SetValue
slider:SetScript("OnValueChanged", slider_OnValueChanged)
slider.okayFunc = args.okayFunc
slider.cancelFunc = args.cancelFunc
slider.defaultFunc = args.defaultFunc
args = doneArgs(args)
return slider
end
end
 
local function generic_OnEnter(self)
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1)
end
local function generic_OnLeave(self)
GameTooltip:Hide()
end
 
do
local function dropDown_SetValue(self, value)
self.value = value
UIDropDownMenu_SetSelectedValue(self, value)
self.changeFunc(value)
end
local helper__num, helper__values
local function helper()
local value, text = helper__values[helper__num], helper__values[helper__num+1]
if value == nil then
helper__num, helper__values = nil, nil
return nil
end
helper__num = helper__num + 2
return value, text
end
local function get_iter(values)
if type(values) == "function" then
return values
end
helper__num = 1
helper__values = values
return helper
end
local SetValue_wrapper
if WotLK then
function SetValue_wrapper(self, ...)
return dropDown_SetValue(...)
end
else
SetValue_wrapper = dropDown_SetValue
end
local function dropDown_menu(self)
for value, text in get_iter(self.values) do
local info = UIDropDownMenu_CreateInfo()
info.text = text
info.value = value
info.checked = self.value == value
info.func = SetValue_wrapper
info.arg1 = self
info.arg2 = value
UIDropDownMenu_AddButton(info)
end
end
 
local tmp = {}
--- Return a single-choice dropdown menu
-- This is for choosing a single choice among many
-- @name panel:MakeDropDown
-- @param ... tuple of key-value pairs<br/>
-- name: What shows above the dropdown<br/>
-- description: What shows when hovering over the dropdown<br/>
-- values: A list of options, in order, where the odd keys are the key and even are its corresponding value<br/>
-- default: The default key<br/>
-- current: The current key - you can either provide this or getFunc<br/>
-- getFunc: Function to return the current key<br/>
-- setFunc: What is called when the key changes<br/>
-- [optional] okayFunc: Called when the okay button is pressed<br/>
-- [optional] cancelFunc: Called when the cancel button is pressed<br/>
-- [optional] defaultFunc: Called when the default button is pressed
-- @usage panel:MakeDropDown(
-- 'name', 'Choose',
-- 'description', 'Specify your tooltip description',
-- 'values', {
-- 'ONE', "One",
-- 'TWO', "Two",
-- 'THREE', "Three",
-- },
-- 'default', 'ONE',
-- 'current', db.choice,
-- 'setFunc', function(value) db.choice = value end,
-- )
-- @return the DropDown frame
function panelMeta:MakeDropDown(...)
local args = getArgs(...)
if type(args.name) ~= "string" then
error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2)
elseif type(args.description) ~= "string" then
error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2)
elseif type(args.values) ~= "function" then
if type(args.values) ~= "table" then
error(("values must be %q, got %q (%s)"):format("table", type(args.values), tostring(args.values)), 2)
elseif #args.values%2 ~= 0 then
error(("values must have an even number of items, got %d"):format(#args.values), 2)
end
for i = 1, #args.values, 2 do
local k, v = args.values[i], args.values[2]
if type(k) ~= "string" and type(k) ~= "number" then
error(("values' keys must be %q or %q, got %q (%s)"):format("string", "number", type(k), tostring(k)))
elseif type(v) ~= "string" then
error(("values' values must be %q, got %q (%s)"):format("string", type(v), tostring(v)))
end
tmp[k] = v
end
end
if type(args.default) ~= "number" and type(args.default) ~= "string" then
error(("default must be %q or %q, got %q (%s)"):format("number", "string", type(args.default), tostring(args.default)), 2)
elseif type(args.values) ~= "function" and not tmp[args.default] then
error(("default must be in values, %s is not"):format(tostring(args.default)), 2)
elseif not args.current == not args.getFunc then
error(("either current or getFunc must be supplied, but not both"), 2)
elseif args.current and type(args.current) ~= "string" and type(args.current) ~= "number" then
error(("current must be %q or %q, got %q (%s)"):format("string", "number", type(args.current), tostring(args.current)), 2)
elseif type(args.values) ~= "function" and args.current and not tmp[args.current] then
error(("current must be in values, %s is not"):format(tostring(args.current)), 2)
elseif args.getFunc and type(args.getFunc) ~= "function" then
error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2)
elseif type(args.setFunc) ~= "function" then
error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2)
elseif args.okayFunc and type(args.okayFunc) ~= "function" then
error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2)
elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then
error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2)
elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then
error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2)
end
for k in pairs(tmp) do
tmp[k] = nil
end
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_DropDown" .. i
until not _G[name]
 
local dropDown = CreateFrame("Frame", name, self, "UIDropDownMenuTemplate")
self.controls[dropDown] = true
if args.name ~= "" then
local label = dropDown:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
label:SetText(args.name)
label:SetPoint("BOTTOMLEFT", dropDown, "TOPLEFT", 16, 3)
end
dropDown.tooltipText = args.description
dropDown.values = args.values
UIDropDownMenu_Initialize(dropDown, function()
dropDown_menu(dropDown)
end)
if WotLK then
UIDropDownMenu_SetWidth(dropDown, 90)
else
UIDropDownMenu_SetWidth(90, dropDown)
end
local current
if args.getFunc then
dropDown.getFunc = args.getFunc
current = args.getFunc()
else
current = args.current
end
UIDropDownMenu_SetSelectedValue(dropDown, current)
dropDown.default = args.default
dropDown.value = args.current
dropDown.oldValue = args.current
dropDown.changeFunc = args.setFunc
dropDown.SetValue = dropDown_SetValue
dropDown:EnableMouse(true)
dropDown:SetScript("OnEnter", generic_OnEnter)
dropDown:SetScript("OnLeave", generic_OnLeave)
dropDown.okayFunc = args.okayFunc
dropDown.cancelFunc = args.cancelFunc
dropDown.defaultFunc = args.defaultFunc
args = doneArgs(args)
return dropDown
end
end
 
do
local function donothing() end
local function button_OnClick(self)
self.clickFunc()
end
--- Return a button
-- @name panel:MakeButton
-- @param ... tuple of key-value pairs<br/>
-- name: What shows above the dropdown<br/>
-- description: What shows when hovering over the dropdown<br/>
-- func: What is called when the button is pressed
-- @usage panel:MakeButton(
-- 'name', 'Click',
-- 'description', 'Specify your tooltip description',
-- 'func', function() DEFAULT_CHAT_FRAME:AddMessage("Clicked!") end
-- )
-- @return the Button
function panelMeta:MakeButton(...)
local args = getArgs(...)
if type(args.name) ~= "string" then
error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2)
elseif type(args.description) ~= "string" then
error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2)
elseif type(args.func) ~= "function" then
error(("description must be %q, got %q (%s)"):format("function", type(args.func), tostring(args.func)), 2)
end
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_Button" .. i
until not _G[name]
 
local button = CreateFrame("Button", name, self, "UIPanelButtonTemplate2")
self.controls[button] = true
button:SetText(args.name)
button.tooltipText = args.description
button:SetWidth(120)
button:SetHeight(22)
button.SetValue = donothing
button.clickFunc = args.func
button:SetScript("OnClick", button_OnClick)
button:SetScript("OnEnter", generic_OnEnter)
button:SetScript("OnLeave", generic_OnLeave)
args = doneArgs(args)
return button
end
end
 
do
local function toggle_SetValue(self, value)
value = not not value
self.changeFunc(value)
self.value = value
self:SetChecked(value)
end
local function toggle_OnClick(self)
self:SetValue(not not self:GetChecked())
end
--- Return a checkbox
-- @name panel:MakeToggle
-- @param ... tuple of key-value pairs<br/>
-- name: What appears to the right of the checkbox<br/>
-- description: What the tooltip shows when hovering over<br/>
-- default: The default value<br/>
-- current: The current value - you can provide this or getFunc<br/>
-- getFunc: Function to return the current value<br/>
-- setFunc: What is called when the value changes<br/>
-- [optional] okayFunc: Called when the okay button is pressed<br/>
-- [optional] cancelFunc: Called when the cancel button is pressed<br/>
-- [optional] defaultFunc: Called when the default button is pressed
-- @usage panel:MakeToggle(
-- 'name', 'Toggle',
-- 'description', 'Specify your tooltip description',
-- 'default', false,
-- 'getFunc', function() return db.myToggle end
-- 'setFunc', function(value) db.myToggle = value end
-- )
-- @return the CheckButton
function panelMeta:MakeToggle(...)
local args = getArgs(...)
if type(args.name) ~= "string" then
error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2)
elseif type(args.description) ~= "string" then
error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2)
elseif type(args.default) ~= "boolean" then
error(("default must be %q, got %q (%s)"):format("boolean", type(args.default), tostring(args.default)), 2)
elseif (args.current == nil) == not args.getFunc then
error(("either current or getFunc must be supplied, but not both"), 2)
elseif args.current and type(args.current) ~= "boolean" then
error(("current must be %q, got %q (%s)"):format("boolean", type(args.current), tostring(args.current)), 2)
elseif args.getFunc and type(args.getFunc) ~= "function" then
error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2)
elseif type(args.setFunc) ~= "function" then
error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2)
elseif args.okayFunc and type(args.okayFunc) ~= "function" then
error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2)
elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then
error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2)
elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then
error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2)
end
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_Toggle" .. i
until not _G[name]
 
local toggle = CreateFrame("CheckButton", name, self, "InterfaceOptionsCheckButtonTemplate")
self.controls[toggle] = true
_G[toggle:GetName() .. "Text"]:SetText(args.name)
toggle:SetHitRectInsets(0, -_G[toggle:GetName() .. "Text"]:GetWidth() - 1, 0, 0)
toggle.tooltipText = args.description
toggle.default = args.default
local current
if args.getFunc then
toggle.getFunc = args.getFunc
current = args.getFunc()
else
current = args.current
end
toggle.value = current
toggle.oldValue = current
toggle.changeFunc = args.setFunc
toggle.SetValue = toggle_SetValue
toggle:SetScript("OnClick", toggle_OnClick)
toggle:SetChecked(current)
toggle:SetScript("OnEnter", generic_OnEnter)
toggle:SetScript("OnLeave", generic_OnLeave)
toggle.okayFunc = args.okayFunc
toggle.cancelFunc = args.cancelFunc
toggle.defaultFunc = args.defaultFunc
args = doneArgs(args)
return toggle
end
end
 
do
local function update(self, r, g, b, a)
if not self.hasAlpha then
a = 1
end
self.info.r = r
self.info.g = g
self.info.b = b
if self.hasAlpha then
self.info.opacity = a
end
self.color:SetTexture(r, g, b, a)
if self.value == self.oldValue then
self.value = {}
end
self.value[1] = r
self.value[2] = g
self.value[3] = b
if self.hasAlpha then
self.value[4] = a
end
self.info.r = r
self.info.g = g
self.info.b = b
if self.hasAlpha then
self.info.opacity = 1 - a
end
if self.hasAlpha then
self.changeFunc(r, g, b, a)
else
self.changeFunc(r, g, b)
end
end
local function button_SetValue(self, ...)
if select('#', ...) == 1 and type((...)) == "table" then
return button_SetValue(self, unpack(value))
end
update(self, ...)
end
local function button_OnClick(self)
OpenColorPicker(self.info)
end
local function swatchFunc(self)
local r, g, b = ColorPickerFrame:GetColorRGB()
local opacity = 1 - OpacitySliderFrame:GetValue()
 
update(self, r, g, b, opacity)
end
local function cancelFunc(self)
local previousValues = ColorPickerFrame.previousValues
local r, g, b, opacity = previousValues.r, previousValues.g, previousValues.b, hasAlpha and 1 - previousValues.opacity or 1
 
update(self, r, g, b, opacity)
end
--- Return a color swatch that opens a color picker
-- @name panel:MakeColorPicker
-- @param ... tuple of key-value pairs<br/>
-- name: What shows up next to the swatch<br />
-- description: What shows up in the tooltip on hover<br />
-- hasAlpha: Whether the color picker should have an alpha setting<br />
-- defaultR: Default red value [0, 1]<br />
-- defaultG: Default green value [0, 1]<br />
-- defaultB: Default blue value [0, 1]<br />
-- defaultA: Default alpha value [0, 1], only needed if hasAlpha is true<br />
-- currentR: The current red value - you can provide this or getFunc<br />
-- currentG: The current green value - you can provide this or getFunc<br />
-- currentB: The current blue value - you can provide this or getFunc<br />
-- currentA: The current alpha value - you can provide this or getFunc<br />
-- getFunc: Function to return the current color as a tuple<br />
-- setFunc: What is called when the color changes<br />
-- [optional] okayFunc: Called when the okay button is pressed<br />
-- [optional] cancelFunc: Called when the cancel button is pressed<br />
-- [optional] defaultFunc: Called when the default button is pressed
-- @usage panel:MakeColorPicker(
-- 'name', 'Pick a color',
-- 'description', 'Specify your tooltip description',
-- 'hasAlpha', false,
-- 'defaultR', 1,
-- 'defaultG', 0.82,
-- 'defaultB', 0,
-- 'getFunc', function() return unpack(db.color) end
-- 'setFunc', function(r, g, b) db.color[1], db.color[2], db.color[3] = r, g, b end
-- )
-- @usage panel:MakeColorPicker(
-- 'name', 'Pick a color',
-- 'description', 'Specify your tooltip description',
-- 'hasAlpha', true,
-- 'defaultR', 0,
-- 'defaultG', 1,
-- 'defaultB', 0,
-- 'defaultA', 0.5,
-- 'currentR', db.color2.r,
-- 'currentG', db.color2.g,
-- 'currentB', db.color2.b,
-- 'currentA', db.color2.a,
-- 'setFunc', function(r, g, b, a) db.color2.r, db.color2.g db.color2.b, db.color2.a = r, g, b, a end
-- )
-- @return the color swatch
function panelMeta:MakeColorPicker(...)
local args = getArgs(...)
if type(args.name) ~= "string" then
error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2)
elseif type(args.description) ~= "string" then
error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2)
elseif type(args.hasAlpha) ~= "boolean" then
error(("hasAlpha must be %q, got %q (%s)"):format("boolean", type(args.hasAlpha), tostring(args.hasAlpha)), 2)
elseif type(args.defaultR) ~= "number" then
error(("defaultR must be %q, got %q (%s)"):format("number", type(args.defaultR), tostring(args.defaultR)), 2)
elseif args.defaultR < 0 or args.defaultR > 1 then
error(("defaultR must be [0, 1], got %s"):format(tostring(args.defaultR)), 2)
elseif type(args.defaultG) ~= "number" then
error(("defaultG must be %q, got %q (%s)"):format("number", type(args.defaultG), tostring(args.defaultG)), 2)
elseif args.defaultG < 0 or args.defaultG > 1 then
error(("defaultG must be [0, 1], got %s"):format(tostring(args.defaultG)), 2)
elseif type(args.defaultB) ~= "number" then
error(("defaultB must be %q, got %q (%s)"):format("number", type(args.defaultB), tostring(args.defaultB)), 2)
elseif args.defaultB < 0 or args.defaultB > 1 then
error(("defaultB must be [0, 1], got %s"):format(tostring(args.defaultB)), 2)
elseif args.hasAlpha and type(args.defaultA) ~= "number" then
error(("defaultA must be %q, got %q (%s)"):format("number", type(args.defaultA), tostring(args.defaultA)), 2)
elseif args.hasAlpha and (args.defaultA < 0 or args.defaultA > 1) then
error(("defaultA must be [0, 1], got %s"):format(tostring(args.defaultA)), 2)
elseif not args.currentR == not args.getFunc then
error(("either currentR or getFunc must be supplied, but not both"), 2)
elseif args.currentR and (not args.currentG or not args.currentB or (args.hasAlpha and not args.currentA)) then
error(("if you supply currentR, you must supply currentG and currentB (and currentA if hasAlpha)"), 2)
elseif args.currentR and type(args.currentR) ~= "number" then
error(("current must be %q, got %q (%s)"):format("number", type(args.currentR), tostring(args.currentR)), 2)
elseif args.currentG and type(args.currentG) ~= "number" then
error(("current must be %q, got %q (%s)"):format("number", type(args.currentG), tostring(args.currentG)), 2)
elseif args.currentB and type(args.currentB) ~= "number" then
error(("current must be %q, got %q (%s)"):format("number", type(args.currentB), tostring(args.currentB)), 2)
elseif args.currentA and type(args.currentA) ~= "number" then
error(("current must be %q, got %q (%s)"):format("number", type(args.currentA), tostring(args.currentA)), 2)
elseif args.getFunc and type(args.getFunc) ~= "function" then
error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2)
elseif type(args.setFunc) ~= "function" then
error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2)
elseif args.okayFunc and type(args.okayFunc) ~= "function" then
error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2)
elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then
error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2)
elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then
error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2)
end
 
local name
local i = 0
repeat
i = i + 1
name = self:GetName() .. "_ColorPicker" .. i
until not _G[name]
 
if not args.hasAlpha then
args.defaultA = 1
end
 
local button = CreateFrame("Button", name, self)
self.controls[button] = true
 
 
local currentR, currentG, currentB, currentA
if args.getFunc then
button.getFunc = args.getFunc
currentR, currentG, currentB, currentA = button.getFunc()
if not args.hasAlpha then
currentA = 1
end
else
currentR = args.currentR
currentG = args.currentG
currentB = args.currentB
if not args.hasAlpha then
currentA = 1
else
currentR = args.currentA
end
end
 
button.tooltipText = args.description
local text = button:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
text:SetText(args.name)
text:SetPoint("LEFT", button, "RIGHT", 0, 1)
button:SetHitRectInsets(0, -text:GetWidth() - 1, 0, 0)
local color = button:CreateTexture(nil, "ARTWORK")
button.color = color
color:SetTexture(currentR, currentG, currentB, currentA)
local background = button:CreateTexture(nil, "BORDER")
background:SetTexture([=[Tileset\Generic\Checkers]=])
background:SetTexCoord(0, 0.5, 0, 0.5)
local border = button:CreateTexture(nil, "BACKGROUND")
border:SetTexture([=[Interface\ChatFrame\ChatFrameColorSwatch]=])
button:SetWidth(26)
button:SetHeight(26)
background:SetPoint("CENTER")
background:SetWidth(14)
background:SetHeight(14)
color:SetPoint("CENTER")
color:SetWidth(14)
color:SetHeight(14)
border:SetAllPoints(button)
button.default = { args.defaultR, args.defaultG, args.defaultB }
button.oldValue = { currentR, currentG, currentB }
if hasAlpha then
button.default[4] = args.defaultA
button.oldValue[4] = currentA
end
button.value = button.oldValue
button.hasAlpha = args.hasAlpha
button.changeFunc = args.setFunc
button.SetValue = button_SetValue
local function swatchFunc_wrapper()
swatchFunc(button)
end
local function cancelFunc_wrapper()
cancelFunc(button)
end
button.info = {
swatchFunc = swatchFunc_wrapper,
hasOpacity = args.hasAlpha,
opacityFunc = args.hasAlpha and swatchFunc_wrapper or nil,
r = currentR,
g = currentB,
b = currentG,
opacity = args.hasAlpha and 1 - currentA or nil,
cancelFunc = cancelFunc_wrapper,
}
button:SetScript("OnClick", button_OnClick)
button:SetScript("OnEnter", generic_OnEnter)
button:SetScript("OnLeave", generic_OnLeave)
button:RegisterForClicks("LeftButtonUp")
button.okayFunc = args.okayFunc
button.cancelFunc = args.cancelFunc
button.defaultFunc = args.defaultFunc
args = doneArgs(args)
return button
end
end
 
--- Add a slash command to open a specific options panel
-- @param name name of the panel to open
-- @param ... tuple of slash commands
-- @usage LibStub("LibSimpleOptions-1.0").AddSlashCommand("My Options", "/MyOpt", "/MO")
function LibSimpleOptions.AddSlashCommand(name, ...)
local num = 0
local name_upper = name:upper()
for i = 1, select('#', ...) do
local cmd = select(i, ...)
num = num + 1
_G["SLASH_" .. name_upper .. num] = cmd
local cmd_lower = cmd:lower()
if cmd_lower ~= cmd then
num = num + 1
_G["SLASH_" .. name_upper .. num] = cmd_lower
end
end
 
_G.hash_SlashCmdList[name_upper] = nil
_G.SlashCmdList[name_upper] = function()
InterfaceOptionsFrame_OpenToFrame(name)
end
end
 
for funcName, func in pairs(panelMeta) do
LibSimpleOptions[funcName] = func
for panel in pairs(panels) do
panel[funcName] = func
end
end
\ No newline at end of file
pStats/pStats.lua
6,7 → 6,22
end
end
 
local function OnEnter(self)
local dataobj, elapsed = LibStub:GetLibrary('LibDataBroker-1.1'):NewDataObject('Stats', {text = '2.0 MiB', icon = [=[Interface\AddOns\pStats\icon]=]}), 0.5
 
CreateFrame('Frame'):SetScript('OnUpdate', function(self, al)
elapsed = elapsed + al
if(elapsed > 0.5) then
dataobj.text = formats(gcinfo())
elapsed = 0
end
end)
 
function dataobj.OnLeave()
GameTooltip:SetClampedToScreen(true)
GameTooltip:Hide()
end
 
function dataobj.OnEnter(self)
local db = pStatsDB
local r, g, b = unpack(db.colors)
local down, up, latency = GetNetStats()
45,16 → 60,24
GameTooltip:Show()
end
 
local function OnClick(self, button)
local function collect(self)
 
end
 
function dataobj.OnClick(self, button)
if(button == "RightButton") then
local collected = collectgarbage('count')
collectgarbage('collect')
OnEnter(self)
dataobj.OnEnter(self)
GameTooltip:AddLine('\n')
GameTooltip:AddDoubleLine('Garbage Collected:', formats(collected - collectgarbage('count')))
GameTooltip:Show()
else
ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, 'MiniMapTracking', 0, self:GetHeight())
if(self:GetName() == 'MiniMapTracking' or self:GetName() == 'MiniMapTrackingButton') then
ToggleDropDownMenu(1, nil, MiniMapTrackingDropDown, 'MiniMapTracking', 0, self:GetHeight())
else
InterfaceOptionsFrame_OpenToFrame('pStats')
end
GameTooltip:Hide()
end
end
70,22 → 93,16
end
 
if(select(4, GetBuildInfo()) >= 3e4) then
MiniMapTrackingButton:EnableMouseWheel(true)
MiniMapTrackingButton:EnableMouseWheel()
MiniMapTrackingButton:RegisterForClicks('AnyUp')
MiniMapTrackingButton:SetScript('OnMouseWheel', OnMouseWheel)
MiniMapTrackingButton:SetScript('OnClick', OnClick)
MiniMapTrackingButton:SetScript('OnEnter', OnEnter)
MiniMapTrackingButton:SetScript('OnLeave', function()
GameTooltip:SetClampedToScreen(true)
GameTooltip:Hide()
end)
MiniMapTrackingButton:SetScript('OnClick', dataobj.OnClick)
MiniMapTrackingButton:SetScript('OnEnter', dataobj.OnEnter)
MiniMapTrackingButton:SetScript('OnLeave', dataobj.OnLeave)
else
MiniMapTracking:EnableMouseWheel(true)
MiniMapTracking:EnableMouseWheel()
MiniMapTracking:SetScript('OnMouseWheel', OnMouseWheel)
MiniMapTracking:SetScript('OnMouseUp', OnClick)
MiniMapTracking:SetScript('OnEnter', OnEnter)
MiniMapTracking:SetScript('OnLeave', function()
GameTooltip:SetClampedToScreen(true)
GameTooltip:Hide()
end)
MiniMapTracking:SetScript('OnMouseUp', dataobj.OnClick)
MiniMapTracking:SetScript('OnEnter', dataobj.OnEnter)
MiniMapTracking:SetScript('OnLeave', dataobj.OnLeave)
end
\ No newline at end of file
pStats/icon.tga Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
pStats/pStats.toc
2,12 → 2,14
## Author: p3lim
## Version: 20400.wowi:revision
## Title: |cffff6000p|rStats
## Notes: Replaces the tooltip on MinimapTracking with a more informative one
## OptionalDeps: LibStub, LibSimpleOptions-1.0
## Notes: Replaces the tooltip on MinimapTracking with a more informative one. Also supports LDB
## OptionalDeps: LibStub, CallbackHandler-1.0, LibSimpleOptions-1.0, LibDataBroker-1.1
## SavedVariablesPerCharacter: pStatsDB
 
LibSimpleOptions-1.0\LibStub\LibStub.lua
LibSimpleOptions-1.0\LibSimpleOptions-1.0.lua
Libs\LibStub.lua
Libs\CallbackHandler-1.0.lua
Libs\LibSimpleOptions-1.0.lua
Libs\LibDataBroker-1.1.lua
 
pStats.lua
pStatsConfig.lua
\ No newline at end of file
pStats Property changes : Deleted: svn:externals - LibSimpleOptions-1.0 http://svn.wowace.com/wowace/trunk/LibSimpleOptions-1.0