4864 lines
137 KiB
Lua
Executable File
4864 lines
137 KiB
Lua
Executable File
--[[
|
|
Name: Waterfall-1.0
|
|
Revision: $Revision: 78661 $
|
|
Author(s): Nargiddley (nargiddley@gmail.com)
|
|
Inspired By: Dewdrop by ckknight
|
|
Website: http://www.wowace.com/wiki/Waterfall-1.0
|
|
Documentation: http://www.wowace.com/wiki/Waterfall-1.0
|
|
SVN: http://svn.wowace.com/wowace/trunk/Waterfall-1.0
|
|
Description: Gui Configuration Library
|
|
License: LGPL 2.1
|
|
Dependencies: AceOO-2.0
|
|
]]
|
|
|
|
local MAJOR_VERSION = "Waterfall-1.0"
|
|
local MINOR_VERSION = "$Revision: 78663 $"
|
|
|
|
local CONTROL_LIMIT = 250
|
|
local _
|
|
|
|
local tinsert = table.insert
|
|
local tremove = table.remove
|
|
local table_setn = table.setn
|
|
|
|
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
|
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
|
|
|
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
|
|
|
|
local AceOO = AceLibrary("AceOO-2.0")
|
|
|
|
local Waterfall = {}
|
|
|
|
local currentframe
|
|
|
|
local OPTIONS = "Options"
|
|
local ARROW = " -> "
|
|
local ARE_YOU_SURE = "Are you sure you want to %s?"
|
|
|
|
if GetLocale() == "zhCN" then
|
|
OPTIONS = "选项"
|
|
ARROW = " -> "
|
|
ARE_YOU_SURE = "你确定要 %s么?"
|
|
elseif GetLocale() == "zhTW" then
|
|
OPTIONS = "選項"
|
|
ARROW = " > "
|
|
ARE_YOU_SURE = "你確定要「%s」嗎?"
|
|
elseif GetLocale() == "koKR" then
|
|
OPTIONS = "설정"
|
|
ARE_YOU_SURE = "정말 당신은 `%s'|1을;를; 하시겠습니까?"
|
|
elseif GetLocale() == "ruRU" then
|
|
OPTIONS = "Опции"
|
|
ARE_YOU_SURE = "Вы уверены что вы хотите %s?"
|
|
end
|
|
|
|
local DEFAULT_CONTROL_WIDTH = 180
|
|
--[[
|
|
local print = Sea.io.print
|
|
local function printTable(table,rowname,level)
|
|
if ( level == nil ) then level = 1; end
|
|
|
|
if ( type(rowname) == "nil" ) then rowname = "ROOT";
|
|
elseif ( type(rowname) == "string" ) then
|
|
rowname = "\""..rowname.."\"";
|
|
elseif ( type(rowname) ~= "number" ) then
|
|
rowname = "*"..type(rowname).."*";
|
|
end
|
|
|
|
local msg = "";
|
|
|
|
|
|
|
|
if ( table == nil ) then
|
|
Sea.io.print(msg,"[",rowname,"] := nil "); return
|
|
end
|
|
if ( type(table) == "table" and level > 0 ) then
|
|
Sea.io.print (msg,rowname," { ");
|
|
for k,v in table do
|
|
if v == nil then Sea.io.print(msg,"[",rowname,"] := nil "); end
|
|
printTable(v,k,level-1);
|
|
end
|
|
Sea.io.print(msg,"}");
|
|
elseif (type(table) == "function" ) then
|
|
Sea.io.print(msg,"[",rowname,"] => {{FunctionPtr*}}");
|
|
elseif (type(table) == "userdata" ) then
|
|
Sea.io.print(msg,"[",rowname,"] => {{UserData}}");
|
|
elseif (type(table) == "boolean" ) then
|
|
local value = "true";
|
|
if ( not table ) then
|
|
value = "false";
|
|
end
|
|
Sea.io.print(msg,"[",rowname,"] => ",value);
|
|
else
|
|
Sea.io.print(msg,"[",rowname,"] => ",table);
|
|
end
|
|
end
|
|
]]
|
|
|
|
--[[
|
|
Passing an AceOO class will get an object of that class from the pool
|
|
You dont need to specify the class when releasing it
|
|
Passing a string will get a table from a named pool
|
|
the string must be passed when releasing tables like this
|
|
--]]
|
|
local getObj, releaseObj
|
|
do
|
|
local objPools = {}
|
|
function getObj(class,...)
|
|
if not objPools[class] then
|
|
objPools[class] = {}
|
|
end
|
|
local newObj = tremove(objPools[class])
|
|
if not newObj then
|
|
if type(class) ~= "string" and type(class.new) == "function" then
|
|
newObj = class:new(unpack(arg))
|
|
else
|
|
newObj = {}
|
|
end
|
|
end
|
|
return newObj
|
|
end
|
|
function releaseObj(obj,class)
|
|
if not class then
|
|
class = obj.class
|
|
end
|
|
if not class then error("You must supply a class to release non AceOO objects") end
|
|
if not objPools[class] then
|
|
objPools[class] = {}
|
|
end
|
|
if type(obj.CleanUp) == "function" then
|
|
obj:CleanUp()
|
|
end
|
|
tinsert(objPools[class],obj)
|
|
end
|
|
end
|
|
--[[
|
|
--borrowed from Dewdrop-2.0
|
|
local function new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
local t = {}
|
|
if k1 then t[k1] = v1
|
|
if k2 then t[k2] = v2
|
|
if k3 then t[k3] = v3
|
|
if k4 then t[k4] = v4
|
|
if k5 then t[k5] = v5
|
|
if k6 then t[k6] = v6
|
|
if k7 then t[k7] = v7
|
|
if k8 then t[k8] = v8
|
|
if k9 then t[k9] = v9
|
|
if k10 then t[k10] = v10
|
|
if k11 then t[k11] = v11
|
|
if k12 then t[k12] = v12
|
|
if k13 then t[k13] = v13
|
|
if k14 then t[k14] = v14
|
|
if k15 then t[k15] = v15
|
|
if k16 then t[k16] = v16
|
|
if k17 then t[k17] = v17
|
|
if k18 then t[k18] = v18
|
|
if k19 then t[k19] = v19
|
|
if k20 then t[k20] = v20
|
|
end end end end end end end end end end end end end end end end end end end end
|
|
return t
|
|
end
|
|
local tmp
|
|
do
|
|
local t
|
|
function tmp(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
if type(k1) == "table" then
|
|
for k,v in pairs(k1) do
|
|
t[k] = v
|
|
end
|
|
else
|
|
if k1 then t[k1] = v1
|
|
if k2 then t[k2] = v2
|
|
if k3 then t[k3] = v3
|
|
if k4 then t[k4] = v4
|
|
if k5 then t[k5] = v5
|
|
if k6 then t[k6] = v6
|
|
if k7 then t[k7] = v7
|
|
if k8 then t[k8] = v8
|
|
if k9 then t[k9] = v9
|
|
if k10 then t[k10] = v10
|
|
if k11 then t[k11] = v11
|
|
if k12 then t[k12] = v12
|
|
if k13 then t[k13] = v13
|
|
if k14 then t[k14] = v14
|
|
if k15 then t[k15] = v15
|
|
if k16 then t[k16] = v16
|
|
if k17 then t[k17] = v17
|
|
if k18 then t[k18] = v18
|
|
if k19 then t[k19] = v19
|
|
if k20 then t[k20] = v20
|
|
end end end end end end end end end end end end end end end end end end end end
|
|
end
|
|
return t
|
|
end
|
|
local x = tmp
|
|
function tmp(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
t = {}
|
|
tmp = x
|
|
x = nil
|
|
return tmp(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
end
|
|
end
|
|
local tmp2
|
|
do
|
|
local t
|
|
function tmp2(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
if k1 then t[k1] = v1
|
|
if k2 then t[k2] = v2
|
|
if k3 then t[k3] = v3
|
|
if k4 then t[k4] = v4
|
|
if k5 then t[k5] = v5
|
|
if k6 then t[k6] = v6
|
|
if k7 then t[k7] = v7
|
|
if k8 then t[k8] = v8
|
|
if k9 then t[k9] = v9
|
|
if k10 then t[k10] = v10
|
|
if k11 then t[k11] = v11
|
|
if k12 then t[k12] = v12
|
|
if k13 then t[k13] = v13
|
|
if k14 then t[k14] = v14
|
|
if k15 then t[k15] = v15
|
|
if k16 then t[k16] = v16
|
|
if k17 then t[k17] = v17
|
|
if k18 then t[k18] = v18
|
|
if k19 then t[k19] = v19
|
|
if k20 then t[k20] = v20
|
|
end end end end end end end end end end end end end end end end end end end end
|
|
return t
|
|
end
|
|
local x = tmp2
|
|
function tmp2(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
t = {}
|
|
tmp2 = x
|
|
x = nil
|
|
return tmp2(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20)
|
|
end
|
|
end
|
|
]]
|
|
|
|
local function new(...)
|
|
local t = {}
|
|
for i = 1, table.getn(arg), 2 do
|
|
local k = arg[i]
|
|
if k then
|
|
t[k] = arg[i+1]
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
local tmp
|
|
do
|
|
local t = {}
|
|
function tmp(...)
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
table_setn(t,0)
|
|
for i = 1, table.getn(arg), 2 do
|
|
local k = arg[i]
|
|
if k then
|
|
t[k] = arg[i+1]
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
end
|
|
local tmp2
|
|
do
|
|
local t = {}
|
|
function tmp2(...)
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
table_setn(t,0)
|
|
for i = 1, table.getn(arg), 2 do
|
|
local k = arg[i]
|
|
if k then
|
|
t[k] = arg[i+1]
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
end
|
|
|
|
|
|
local function getArgs(t, str, num, ...)
|
|
local x = t[str .. num]
|
|
if x == nil then
|
|
return unpack(arg)
|
|
else
|
|
return x, getArgs(t, str, num + 1, unpack(arg))
|
|
end
|
|
end
|
|
|
|
local function confirmPopup(message, func, ...)
|
|
if not StaticPopupDialogs["WATERFALL01_CONFIRM_DIALOG"] then
|
|
StaticPopupDialogs["WATERFALL01_CONFIRM_DIALOG"] = {}
|
|
end
|
|
local t = StaticPopupDialogs["WATERFALL01_CONFIRM_DIALOG"]
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
table_setn(t,0)
|
|
t.text = message
|
|
t.button1 = ACCEPT
|
|
t.button2 = CANCEL
|
|
t.OnAccept = function()
|
|
func(unpack(t))
|
|
end
|
|
for i = 1, table.getn(arg) do
|
|
t[i] = arg[i]
|
|
end
|
|
t.timeout = 0
|
|
t.whileDead = 1
|
|
t.hideOnEscape = 1
|
|
|
|
StaticPopup_Show("WATERFALL01_CONFIRM_DIALOG")
|
|
end
|
|
|
|
local function showGameTooltip(this)
|
|
if this.tooltipTitle or this.tooltipText then
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, this.frame or this)
|
|
if this.tooltipTitle then
|
|
GameTooltip:SetText(this.tooltipTitle, 1, 1, 1, 1)
|
|
if this.tooltipText then
|
|
GameTooltip:AddLine(this.tooltipText, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
|
|
end
|
|
else
|
|
GameTooltip:SetText(this.tooltipText, 1, 1, 1, 1)
|
|
end
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
--end of borrowing
|
|
|
|
local function parseList(list)
|
|
local token, rest = string.match(list,"([^%s]+)%s+(.+)")
|
|
if not rest then
|
|
return (tonumber(list) or list)
|
|
else
|
|
return (tonumber(token) or token), parseList(rest)
|
|
end
|
|
end
|
|
|
|
local function compareOptions(a,b)
|
|
if not a then
|
|
return true
|
|
end
|
|
if not b then
|
|
return false
|
|
end
|
|
local A, B = a.order or 100, b.order or 100
|
|
if A == B then
|
|
local NameA = a.guiName or a.name or ""
|
|
local NameB = b.guiName or b.name or ""
|
|
return string.upper(NameA) < string.upper(NameB)
|
|
end
|
|
if A < 0 then
|
|
if B > 0 then
|
|
return false
|
|
end
|
|
else
|
|
if B < 0 then
|
|
return true
|
|
end
|
|
end
|
|
return A < B
|
|
end
|
|
|
|
function Waterfall:Register(id,...)
|
|
local settings = new(unpack(arg))
|
|
|
|
if settings.aceOptions then
|
|
assert(type(settings.aceOptions) == "table","\"aceOptions\" must be a table")
|
|
else
|
|
assert(type(settings.tree) == "table","\"tree\" must be a table")
|
|
assert(type(settings.children) == "function","\"children\" must be a function")
|
|
end
|
|
if not settings.title then
|
|
settings.title = id
|
|
end
|
|
|
|
if settings.treeType == "SECTIONS" then
|
|
settings.hideTreeRoot = true
|
|
settings.treeLevels = 3
|
|
end
|
|
|
|
if self.registry[id] then
|
|
self:UnRegister(id)
|
|
end
|
|
self.registry[id] = settings
|
|
end
|
|
|
|
function Waterfall:UnRegister(id)
|
|
self.registry[id] = nil
|
|
end
|
|
|
|
function Waterfall:IsRegistered(id)
|
|
return not not self.registry[id]
|
|
end
|
|
|
|
local function releaseTree(tree)
|
|
for i, v in ipairs(tree) do
|
|
tree[i] = nil
|
|
releaseTree(v)
|
|
releaseObj(v,"table")
|
|
end
|
|
for k, v in pairs(tree) do
|
|
tree[k] = nil
|
|
end
|
|
table_setn(tree,0)
|
|
end
|
|
|
|
local function checkNegatable(attr,handler,param)
|
|
local ret
|
|
if type(attr) == "function" then
|
|
ret = attr(param)
|
|
elseif type(attr) == "string" and handler then
|
|
local neg = string.match(attr,"^~(.+)$")
|
|
if neg then
|
|
attr = neg
|
|
end
|
|
ret = handler[attr](handler,param)
|
|
if neg then
|
|
ret = not ret
|
|
end
|
|
else
|
|
ret = attr
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local mysort = function(a, b)
|
|
|
|
local alpha, bravo = a, b
|
|
local alpha_order = alpha and alpha.order or 100
|
|
local bravo_order = bravo and bravo.order or 100
|
|
local alpha_name = alpha and (alpha.guiName or alpha.name)
|
|
local bravo_name = bravo and (bravo.guiName or bravo.name)
|
|
if alpha_order == bravo_order then
|
|
if not alpha_name then
|
|
return bravo_name
|
|
elseif not bravo_name then
|
|
return false
|
|
else
|
|
return string.upper(string.gsub(string.gsub(alpha_name,"|c%x%x%x%x%x%x%x%x", ""), "|r", "")) < string.upper(string.gsub(string.gsub(bravo_name,"|c%x%x%x%x%x%x%x%x", ""),"|r", ""))
|
|
end
|
|
else
|
|
if alpha_order < 0 then
|
|
if bravo_order > 0 then
|
|
return false
|
|
end
|
|
else
|
|
if bravo_order < 0 then
|
|
return true
|
|
end
|
|
end
|
|
return alpha_order < bravo_order
|
|
end
|
|
end
|
|
|
|
local function buildAceOptionsTree(tree, status, options, numLevels, path, rootHandler)
|
|
local settings = Waterfall.registry[currentframe.id]
|
|
local handler = options.handler or rootHandler
|
|
local bargs = options.args
|
|
|
|
assert(type(bargs) == "table",string.format("args must be a table: Current Path:%s",(path or ".")))
|
|
local root
|
|
|
|
if path then
|
|
tree.id = path
|
|
tree.text = options.guiName or options.name or (options.handler and options.handler.name) or path
|
|
tree.name = tree.text
|
|
tree.tooltipTitle = tree.text
|
|
tree.tooltipText = options.desc
|
|
tree.order = options.order
|
|
tree.disabled = checkNegatable(options.disabled, handler, options.passValue)
|
|
tree.handler = handler
|
|
tree.icon = options.icon
|
|
tree.hidden = checkNegatable(options.wfHidden or options.guiHidden or options.hidden,handler, options.passValue)
|
|
local hasOptions
|
|
for k, item in pairs(bargs) do
|
|
if item.type ~= "group" and item.type ~= "heading" then
|
|
if not checkNegatable(item.wfHidden or item.guiHidden or item.hidden,handler, item.passValue) then
|
|
hasOptions = true
|
|
end
|
|
end
|
|
end
|
|
tree.hasOptions = hasOptions
|
|
else
|
|
releaseTree(tree)
|
|
local hasOptions
|
|
for k, item in pairs(bargs) do
|
|
if item.type ~= "group" and item.type ~= "heading" then
|
|
hasOptions = true
|
|
end
|
|
end
|
|
if hasOptions then
|
|
root = getObj("table")
|
|
root.text = options.guiName or options.name or (options.handler and options.handler.name) or path
|
|
root.name = tree.text
|
|
root.tooltipTitle = tree.text
|
|
root.tooltipText = options.desc
|
|
root.order = options.order
|
|
root.disabled = checkNegatable(options.disabled, handler, options.passValue)
|
|
root.handler = handler
|
|
root.icon = options.icon
|
|
root.hidden = checkNegatable(options.wfHidden or options.guiHidden or options.hidden,handler, options.passValue)
|
|
root.id = "."
|
|
root.hasOptions = true
|
|
if status['.'] == nil then
|
|
status['.'] = true
|
|
end
|
|
tinsert(tree,root)
|
|
if not settings.hideTreeRoot then
|
|
tree = root
|
|
end
|
|
end
|
|
settings.treeRootShown = hasOptions and not settings.hideTreeRoot
|
|
end
|
|
|
|
if not numLevels or numLevels > 1 then
|
|
for k, item in pairs(bargs) do
|
|
if item.type == "group" then
|
|
local child = getObj("table")
|
|
local nextPath
|
|
if path then
|
|
nextPath = path.."."..k
|
|
else
|
|
nextPath = k
|
|
end
|
|
if numLevels then
|
|
buildAceOptionsTree(child, status, item,numLevels - 1,nextPath, handler)
|
|
else
|
|
buildAceOptionsTree(child, status, item,nil,nextPath, handler)
|
|
end
|
|
tinsert(tree,child)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
table.sort(tree, mysort)
|
|
|
|
-- table.sort(tree,compareOptions)
|
|
end
|
|
|
|
local function checkAceOptionsPath(path, options, frame)
|
|
local t = options
|
|
local validpath
|
|
for k in string.gfind(path,"[^\.]+") do
|
|
if tonumber(k) and t.args[tonumber(k)] then
|
|
k = tonumber(k)
|
|
end
|
|
if t.args and t.args[k] then
|
|
t = t.args[k]
|
|
if validpath then
|
|
validpath = validpath..'.'..k
|
|
else
|
|
validpath = k
|
|
end
|
|
else
|
|
if frame then
|
|
frame:SetSelected(validpath, true)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
return validpath or '.'
|
|
end
|
|
|
|
local function feedFromOptionsTree(paneid, options)
|
|
if not paneid then return end
|
|
local settings = Waterfall.registry[currentframe.id]
|
|
paneid = checkAceOptionsPath(paneid, options, settings.frame)
|
|
local curlevel = 1
|
|
local levels = 1
|
|
for x in string.gfind(paneid,"[^%.]+") do
|
|
curlevel = curlevel + 1
|
|
end
|
|
if settings.treeLevels == curlevel then
|
|
levels = nil
|
|
end
|
|
if paneid == "." then
|
|
Waterfall:FeedAceOptionsTable(options, nil, levels)
|
|
return options.name or (options.handler and options.handler.name) or OPTIONS
|
|
else
|
|
local crumbs
|
|
if settings.treeRootShown then
|
|
crumbs = options.name or (options.handler and options.handler.name) or OPTIONS
|
|
end
|
|
local t = options
|
|
Waterfall:FeedAceOptionsTable(options,paneid,levels)
|
|
for k in string.gfind(paneid,"[^\.]+") do
|
|
if tonumber(k) and t.args[tonumber(k)] then
|
|
k = tonumber(k)
|
|
end
|
|
if t.args and t.args[k] then
|
|
t = t.args[k]
|
|
if crumbs then
|
|
crumbs = crumbs..ARROW..(t.guiName or t.name or "")
|
|
else
|
|
crumbs = (t.guiName or t.name or "")
|
|
end
|
|
else
|
|
Waterfall:error("Invalid path \"%s\" for Aceoptions table",paneid)
|
|
end
|
|
end
|
|
return crumbs
|
|
end
|
|
end
|
|
|
|
local old_CloseSpecialWindows
|
|
|
|
function Waterfall:Open(id, pane)
|
|
if not old_CloseSpecialWindows then
|
|
old_CloseSpecialWindows = CloseSpecialWindows
|
|
CloseSpecialWindows = function()
|
|
local found = old_CloseSpecialWindows()
|
|
return self:CloseAll() or found
|
|
end
|
|
end
|
|
local info = self.registry[id]
|
|
|
|
if not info then
|
|
error("You cannot open a waterfall without registering it first")
|
|
end
|
|
--already open
|
|
if info.frame then
|
|
if pane then
|
|
info.frame:SetSelected(pane)
|
|
end
|
|
return
|
|
end
|
|
local frame = getObj(WaterfallFrame) --WaterfallFrame:new()
|
|
frame:SetID(id)
|
|
frame.lib = self
|
|
info.frame = frame
|
|
if info.title then
|
|
frame:SetTitle(info.title)
|
|
end
|
|
local r,g,b = info.colorR or 1, info.colorG or 0.6, info.colorB or 0
|
|
frame:SetColor(r,g,b)
|
|
|
|
if info.aceOptions then
|
|
|
|
if not info.tree then
|
|
info.tree = {}
|
|
end
|
|
if not info.treestatus then
|
|
info.treestatus = {}
|
|
end
|
|
currentframe = frame
|
|
frame:SetTree(info.tree, info.treestatus, buildAceOptionsTree, info.aceOptions, info.treeLevels)
|
|
currentframe = nil
|
|
frame:SetChildren(feedFromOptionsTree, info.aceOptions)
|
|
if pane then
|
|
frame.treeview:Collapse()
|
|
end
|
|
frame:SetSelected(pane or info.defaultPane or ".")
|
|
frame.treeview:SetType(info.treeType)
|
|
else
|
|
if not info.treestatus then
|
|
info.treestatus = {}
|
|
end
|
|
frame:SetTree(info.tree, info.treestatus)
|
|
frame:SetChildren(info.children)
|
|
if pane or info.defaultPane then
|
|
frame:SetSelected(pane or info.defaultPane)
|
|
end
|
|
frame.treeview:SetType(info.treeType)
|
|
end
|
|
|
|
if info.height then
|
|
frame:SetHeight(info.height)
|
|
end
|
|
if info.width then
|
|
frame:SetWidth(info.width)
|
|
end
|
|
frame:Refresh()
|
|
frame:Show()
|
|
|
|
end
|
|
|
|
function Waterfall:IsOpen(id)
|
|
return not not self.registry[id].frame
|
|
end
|
|
|
|
function Waterfall:Refresh(id)
|
|
local info = self.registry[id]
|
|
if not info then
|
|
error("You can't refresh a waterfall without registering it first")
|
|
end
|
|
if info.frame then
|
|
info.frame:Refresh()
|
|
end
|
|
end
|
|
|
|
function Waterfall:SetSize(id, width, height)
|
|
local info = self.registry[id]
|
|
if not info then
|
|
error("You refresh open a waterfall without registering it first")
|
|
end
|
|
if info.frame then
|
|
info.frame:SetWidth(width)
|
|
info.frame:SetHeight(height)
|
|
end
|
|
end
|
|
|
|
local function setCommonAttributes(control,info)
|
|
control.width = info.width
|
|
control.height = info.height
|
|
control.noNewLine = info.noNewLine
|
|
control.causesRefresh = info.causesRefresh
|
|
control.fullRefresh = info.fullRefresh
|
|
control.treeRefresh = info.treeRefresh
|
|
control.tooltipTitle = info.tooltipTitle
|
|
control.tooltipText = info.tooltipText
|
|
control:SetText(info.text or "")
|
|
end
|
|
|
|
function Waterfall:AddControl(...)
|
|
currentframe.controlcount = currentframe.controlcount + 1
|
|
if not currentframe then
|
|
error("AddControl must be called from within a children function")
|
|
end
|
|
local control
|
|
local info = self.registry[currentframe.id]
|
|
local limit = info.controlLimit or CONTROL_LIMIT
|
|
if currentframe.controlcount > limit then
|
|
if currentframe.controlcount == limit + 1 then
|
|
control = getObj(WaterfallLabel)
|
|
control.r = 1
|
|
control.g = 0
|
|
control.b = 0
|
|
control:SetText(("More than %s Controls in current pane....."):format(limit))
|
|
control:Refresh()
|
|
currentframe:AddControl(control)
|
|
end
|
|
return
|
|
end
|
|
|
|
local info = tmp2(unpack(arg))
|
|
|
|
if info.type == "label" then
|
|
control = getObj(WaterfallLabel)
|
|
setCommonAttributes(control,info)
|
|
control.justifyH = info.justifyH
|
|
control.r = info.r
|
|
control.g = info.g
|
|
control.b = info.b
|
|
control:Refresh()
|
|
elseif info.type == "dragLink" then
|
|
control = getObj(WaterfallDragLink)
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
|
|
control:Refresh()
|
|
elseif info.type == "linklabel" then
|
|
control = getObj(WaterfallLinklabel)
|
|
setCommonAttributes(control,info)
|
|
control.justifyH = info.justifyH
|
|
control.r = info.r
|
|
control.g = info.g
|
|
control.b = info.b
|
|
|
|
control:SetFunc("link",info.linkFunc,getArgs(info,"linkArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.confirm = info.confirm
|
|
control:Refresh()
|
|
|
|
elseif info.type == "button" then
|
|
control = getObj(WaterfallButton)
|
|
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("exec",info.execFunc,getArgs(info,"execArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.confirm = info.confirm
|
|
control.link = info.link
|
|
|
|
control:Refresh()
|
|
|
|
elseif info.type == "heading" then
|
|
control = getObj(WaterfallHeading)
|
|
control.justifyH = info.justifyH
|
|
setCommonAttributes(control,info)
|
|
control:Refresh()
|
|
elseif info.type == "textbox" then
|
|
control = getObj(WaterfallTextBox)
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
control:SetFunc("changed",info.changedFunc,getArgs(info,"changedArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.toNumber = info.toNumber
|
|
control.parseList = info.parseList
|
|
control.setOnTextChanged = info.setOnTextChanged
|
|
control:SetFunc("validate",info.validateFunc,getArgs(info,"validateArg",1))
|
|
control.validateModifies = info.validateModifies
|
|
control:Refresh()
|
|
|
|
elseif info.type == "dropdown" then
|
|
control = getObj(WaterfallDropdown)
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.parseList = info.parseList
|
|
control.list = info.list
|
|
control.columns = info.columns
|
|
control.strict = info.strict
|
|
|
|
control:Refresh()
|
|
|
|
elseif info.type == "checkbox" then
|
|
control = getObj(WaterfallCheckBox)
|
|
setCommonAttributes(control,info)
|
|
control:SetChecked(info.checked)
|
|
control.isRadio = info.isRadio
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
|
|
control:Refresh()
|
|
elseif info.type == "slider" then
|
|
control = getObj(WaterfallSlider)
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
control.min = info.min
|
|
control.max = info.max
|
|
control.step = info.step
|
|
control.bigStep = info.bigStep or info.step
|
|
control.finalSetOnly = info.finalSetOnly
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control:Refresh()
|
|
elseif info.type == "color" then
|
|
control = getObj(WaterfallColorSwatch)
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.hasOpacity = info.hasOpacity
|
|
control.r = info.r
|
|
control.g = info.g
|
|
control.b = info.b
|
|
control.opacity = info.opacity
|
|
control.hasOpacity = info.hasOpacity
|
|
control:Refresh()
|
|
elseif info.type == "keybind" then
|
|
control = getObj(WaterfallKeybinding)
|
|
control:SetText("Binding")
|
|
setCommonAttributes(control,info)
|
|
control:SetFunc("set",info.setFunc,getArgs(info,"setArg",1))
|
|
control:SetFunc("get",info.getFunc,getArgs(info,"getArg",1))
|
|
if type(info.disabled) == "function" then
|
|
control:SetFunc("disabled",info.disabled,getArgs(info,"disabledArg",1))
|
|
control.inverseDisabled = info.inverseDisabled
|
|
else
|
|
control.disabled = info.disabled
|
|
end
|
|
control.keybindingOnly = info.keybindingOnly
|
|
control.keybindingExcept = info.keybindingExcept
|
|
control:Refresh()
|
|
else
|
|
|
|
error("Invalid or missing type")
|
|
end
|
|
currentframe:AddControl(control)
|
|
end
|
|
|
|
|
|
local function addDisabled(t,disabled,handler,param)
|
|
if disabled then
|
|
if type(disabled) == "function" or type(disabled) == "boolean" then
|
|
tinsert(t,"disabled")
|
|
tinsert(t,disabled)
|
|
if param then
|
|
tinsert(t,"disabledArg1")
|
|
tinsert(t,param)
|
|
end
|
|
elseif type(disabled) == "string" then
|
|
local neg = string.match(disabled,"^~(.+)$")
|
|
if neg then
|
|
disabled = neg
|
|
end
|
|
if handler and handler[disabled] then
|
|
tinsert(t,"disabled")
|
|
tinsert(t,handler[disabled])
|
|
tinsert(t,"disabledArg1")
|
|
tinsert(t,handler)
|
|
if param then
|
|
tinsert(t,"disabledArg2")
|
|
tinsert(t,param)
|
|
end
|
|
end
|
|
if neg then
|
|
tinsert(t,"inverseDisabled")
|
|
tinsert(t,true)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function appendArgs(t,name,start,...)
|
|
for k = 1 , table.getn(arg) do
|
|
tinsert(t,name.."Arg"..(start + k - 1))
|
|
tinsert(t,arg[k])
|
|
end
|
|
end
|
|
|
|
local function addFunction(t,name,func,handler,...)
|
|
if type(func) == "function" then
|
|
tinsert(t,name.."Func")
|
|
tinsert(t,func)
|
|
appendArgs(t,name,1,unpack(arg))
|
|
elseif type(func) == "string" and handler and handler[func] then
|
|
tinsert(t,name.."Func")
|
|
tinsert(t,handler[func])
|
|
tinsert(t,name.."Arg1")
|
|
tinsert(t,handler)
|
|
appendArgs(t,name,2,unpack(arg))
|
|
end
|
|
end
|
|
|
|
local function validateRange(min,max,step,value)
|
|
value = tonumber(value)
|
|
if step > 0 then
|
|
value = math.floor((value - min) / step + 0.5) * step + min
|
|
end
|
|
if value >= min and value <= max then
|
|
return value
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
--[[
|
|
Feeds an ace options table into the right pane, must be called within a "children" function
|
|
root is the root of your options table, this is important if you use any methods for resolving the handler
|
|
path is the path into the table seperated by "." e.g. "Items.Compress" to feed the table given by root.args.Items.args.Compress
|
|
maxLevels is how many sub groups to feed as well, 1 is only the current level 2 will feed sub groups etc. nil assumes no limit
|
|
]]
|
|
function Waterfall:FeedAceOptionsTable(root,path,maxLevels)
|
|
local feedtmp = getObj("table")
|
|
local feedkeys = getObj("table")
|
|
local tmpargs = getObj("table")
|
|
local t
|
|
local handler = root.handler
|
|
local groupDisabled = checkNegatable(root.disabled,root.handler,root.passValue)
|
|
local passSet
|
|
local passGet
|
|
if root.pass then
|
|
passSet = root.set
|
|
passGet = root.get
|
|
else
|
|
passSet = nil
|
|
passGet = nil
|
|
end
|
|
if path then
|
|
t = root
|
|
for k in string.gfind(path,"[^\.]+") do
|
|
if tonumber(k) and t.args[tonumber(k)] then
|
|
k = tonumber(k)
|
|
end
|
|
if t.args and t.args[k] then
|
|
t = t.args[k]
|
|
handler = t.handler or handler
|
|
groupDisabled = checkNegatable(t.disabled,handler,t.passValue) or groupDisabled
|
|
if t.pass then
|
|
passSet = t.set
|
|
passGet = t.get
|
|
else
|
|
passSet = nil
|
|
passGet = nil
|
|
end
|
|
else
|
|
self:error("Invalid path \"%s\" for Aceoptions table",path)
|
|
end
|
|
end
|
|
else
|
|
t = root
|
|
end
|
|
if t.type ~= "group" then
|
|
self:error("You must feed an ace options group")
|
|
end
|
|
for k, v in pairs(t.args) do
|
|
tinsert(feedtmp, v)
|
|
feedkeys[v] = k
|
|
end
|
|
|
|
table.sort(feedtmp, mysort)
|
|
local lastheader
|
|
for i, v in ipairs(feedtmp) do
|
|
--only add headers if they arent immediately followed by a group
|
|
if lastheader then
|
|
if v.type ~= "group" then
|
|
--self:AddControl("type","label","text","","width",80)
|
|
--self:AddControl("type","heading","text",lastheader,"width",DEFAULT_CONTROL_WIDTH,"justifyH","CENTER","noNewLine",true)
|
|
self:AddControl("type","heading","text",lastheader,"width",DEFAULT_CONTROL_WIDTH,"justifyH","CENTER")
|
|
end
|
|
lastheader = nil
|
|
end
|
|
local hidden
|
|
if v.guiHidden ~= nil then
|
|
hidden = v.guiHidden
|
|
elseif v.wfHidden ~= nil then
|
|
hidden = v.wfHidden
|
|
else
|
|
hidden = v.hidden
|
|
end
|
|
hidden = checkNegatable(hidden,v.handler or handler,v.passValue)
|
|
|
|
local name = v.guiName or v.name
|
|
if name and ( checkNegatable(v.disabled,v.handler or handler,v.passValue) or groupDisabled ) then
|
|
name = "|cFF808080"..name
|
|
end
|
|
if not hidden then
|
|
if v.type == "toggle" then
|
|
--self:AddControl("type","label","text","","width",80)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"checkbox")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
tinsert(tmpargs,"isRadio")
|
|
tinsert(tmpargs,not not v.isRadio)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
|
|
self:AddControl(unpack(tmpargs))
|
|
elseif v.type == "dragLink" then
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"dragLink")
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
local tooltipTitle = "" .. tostring(v.itemId)
|
|
tinsert(tmpargs,tooltipTitle)
|
|
tinsert(tmpargs,"linkInfo")
|
|
tinsert(tmpargs,v.linkInfo or {})
|
|
tinsert(tmpargs,"icon")
|
|
tinsert(tmpargs,v.icon or "")
|
|
tinsert(tmpargs,"iconWidth")
|
|
tinsert(tmpargs,v.iconWidth or WaterfallDragLink.defaultIconSize)
|
|
tinsert(tmpargs,"iconHeight")
|
|
tinsert(tmpargs,v.iconHeight or WaterfallDragLink.defaultIconSize)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler,v.passValue)
|
|
end
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
|
|
self:AddControl(unpack(tmpargs))
|
|
elseif v.type == "group" then
|
|
if not maxLevels or maxLevels > 1 then
|
|
--self:AddControl("type","label","text","","width",80)
|
|
if checkNegatable(v.disabled,v.handler or handler,v.passValue) or groupDisabled then
|
|
name = "|cFF808080"..name
|
|
end
|
|
--self:AddControl("type","heading","text",name,"width",DEFAULT_CONTROL_WIDTH,"justifyH","CENTER","noNewLine",true)
|
|
self:AddControl("type","heading","text",name,"width",DEFAULT_CONTROL_WIDTH,"justifyH","CENTER")
|
|
local nextPath
|
|
local nextMaxLevels
|
|
if path then
|
|
nextPath = path.."."..feedkeys[v]
|
|
else
|
|
nextPath = feedkeys[v]
|
|
end
|
|
if maxLevels then
|
|
nextMaxLevels = maxLevels - 1
|
|
end
|
|
self:FeedAceOptionsTable(root,nextPath,nextMaxLevels)
|
|
self:AddControl("type","heading")
|
|
end
|
|
elseif v.type == "text" then
|
|
if type(v.validate) == "table" then
|
|
if v.multiToggle then
|
|
self:AddControl("type","heading","text",name)
|
|
for key, value in pairs(v.validate) do
|
|
if type(key) == "number" then
|
|
key = value
|
|
end
|
|
self:AddControl("type","label","text","","width",12)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"checkbox")
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,value)
|
|
tinsert(tmpargs,"noNewLine")
|
|
tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,value)
|
|
if v.passValue then
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v],key)
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue,key)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v],key)
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue,key)
|
|
end
|
|
else
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,feedkeys[v],key)
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,key)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,feedkeys[v],key)
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,key)
|
|
end
|
|
end
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue,key)
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
self:AddControl(unpack(tmpargs))
|
|
for i = 0,table.getn(tmpargs) do
|
|
tmpargs[i] = nil
|
|
end
|
|
end
|
|
else
|
|
--self:AddControl("type","label","text",name,"width",80,"justifyH","RIGHT")
|
|
self:AddControl("type","label","text",name)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"dropdown")
|
|
tinsert(tmpargs,"strict")
|
|
tinsert(tmpargs,true)
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
|
|
tinsert(tmpargs,"list")
|
|
tinsert(tmpargs,v.validate)
|
|
tinsert(tmpargs,"columns")
|
|
tinsert(tmpargs,v.columns)
|
|
tinsert(tmpargs,"parseList")
|
|
tinsert(tmpargs, not not v.input)
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
self:AddControl(unpack(tmpargs))
|
|
end
|
|
elseif v.validate == "keybinding" then
|
|
--self:AddControl("type","label","text",name,"width",80,"justifyH","RIGHT")
|
|
self:AddControl("type","label","text",name)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"keybind")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
tinsert(tmpargs,"keybindingOnly")
|
|
tinsert(tmpargs,v.keybindingOnly or false)
|
|
tinsert(tmpargs,"keybindingExcept")
|
|
tinsert(tmpargs,v.keybindingExcept or false)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
|
|
self:AddControl(unpack(tmpargs))
|
|
else
|
|
--self:AddControl("type","label","text",name,"width",80,"justifyH","RIGHT")
|
|
self:AddControl("type","label","text",name)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"textbox")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
tinsert(tmpargs,"parseList")
|
|
tinsert(tmpargs, not not v.input)
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
|
|
addFunction(tmpargs,"validate",v.validate,v.handler or handler)
|
|
|
|
self:AddControl(unpack(tmpargs))
|
|
end
|
|
elseif v.type == "execute" then
|
|
--self:AddControl("type","label","text","","width",80)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"button")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"confirm")
|
|
tinsert(tmpargs, v.confirm or false)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
tinsert(tmpargs, "link")
|
|
tinsert(tmpargs,v.link or false)
|
|
addFunction(tmpargs,"exec",v.func,v.handler or handler,v.passValue)
|
|
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
self:AddControl(unpack(tmpargs))
|
|
elseif v.type == "header" then
|
|
if name and ( checkNegatable(v.disabled,v.handler or handler,v.passValue) or groupDisabled ) then
|
|
lastheader = "|cFF808080"..name
|
|
else
|
|
lastheader = name
|
|
end
|
|
elseif v.type == "range" then
|
|
--self:AddControl("type","label","text",name,"width",80,"justifyH","RIGHT")
|
|
self:AddControl("type","label","text",name)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"slider")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
local min,max,step
|
|
min = v.min or 0
|
|
max = v.max or 1
|
|
step = v.step or 0
|
|
tinsert(tmpargs,"min")
|
|
tinsert(tmpargs,v.min or 0)
|
|
tinsert(tmpargs,"max")
|
|
tinsert(tmpargs,v.max or 1)
|
|
tinsert(tmpargs,"step")
|
|
tinsert(tmpargs,v.step or 0)
|
|
tinsert(tmpargs,"bigStep")
|
|
tinsert(tmpargs,v.bigStep or v.step or 0)
|
|
tinsert(tmpargs,"finalSetOnly")
|
|
tinsert(tmpargs,v.finalSetOnly or false)
|
|
--if no step is given or there are more than 20 steps possible
|
|
--local complex = step == 0 or ((max - min) / step) > 20
|
|
local complex = true
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,"")
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
self:AddControl(unpack(tmpargs))
|
|
if complex then
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"textbox")
|
|
tinsert(tmpargs,"noNewLine")
|
|
tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"toNumber")
|
|
tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"validateModifies")
|
|
tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"width")
|
|
tinsert(tmpargs,60)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
|
|
addFunction(tmpargs,"validate",validateRange,v.handler or handler,min,max,step)
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
|
|
tinsert(tmpargs,"fullRefresh")
|
|
tinsert(tmpargs,true)
|
|
self:AddControl(unpack(tmpargs))
|
|
end
|
|
elseif v.type == "color" then
|
|
--self:AddControl("type","label","text","","width",80)
|
|
tinsert(tmpargs,"type")
|
|
tinsert(tmpargs,"color")
|
|
--tinsert(tmpargs,"noNewLine")
|
|
--tinsert(tmpargs,true)
|
|
tinsert(tmpargs,"text")
|
|
tinsert(tmpargs,name)
|
|
if passGet and v.get == nil then
|
|
addFunction(tmpargs,"get",passGet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"get",v.get,v.handler or handler,v.passValue)
|
|
end
|
|
if passSet and v.set == nil then
|
|
addFunction(tmpargs,"set",passSet,v.handler or handler,v.passValue or feedkeys[v])
|
|
else
|
|
addFunction(tmpargs,"set",v.set,v.handler or handler,v.passValue)
|
|
end
|
|
addDisabled(tmpargs,groupDisabled or v.disabled,v.handler or handler,v.passValue)
|
|
tinsert(tmpargs,"tooltipTitle")
|
|
tinsert(tmpargs,name)
|
|
tinsert(tmpargs,"tooltipText")
|
|
tinsert(tmpargs,v.desc or false)
|
|
tinsert(tmpargs,"hasOpacity")
|
|
tinsert(tmpargs, not not v.hasAlpha)
|
|
self:AddControl(unpack(tmpargs))
|
|
end
|
|
|
|
for i = 0,table.getn(tmpargs) do
|
|
tmpargs[i] = nil
|
|
end
|
|
table_setn(tmpargs, 0)
|
|
end
|
|
end
|
|
for i = 0,table.getn(feedtmp) do
|
|
feedtmp[i] = nil
|
|
end
|
|
table_setn(feedtmp, 0)
|
|
for k in pairs(feedkeys) do
|
|
feedkeys[k] = nil
|
|
end
|
|
table_setn(feedkeys, 0)
|
|
|
|
releaseObj(feedtmp,"table")
|
|
releaseObj(feedkeys,"table")
|
|
releaseObj(tmpargs,"table")
|
|
|
|
end
|
|
|
|
function Waterfall:Close(id)
|
|
local info = self.registry[id]
|
|
if not info then
|
|
error("You cannot close a waterfall without registering it first")
|
|
end
|
|
local frame = info.frame
|
|
if frame then
|
|
local OnClose = info.OnClose
|
|
if type(OnClose) == "function" then
|
|
OnClose(id)
|
|
end
|
|
releaseObj(frame)
|
|
end
|
|
info.frame = nil
|
|
end
|
|
|
|
function Waterfall:CloseAll()
|
|
local closed
|
|
for id, v in pairs(self.registry) do
|
|
if v.frame then
|
|
self:Close(id)
|
|
closed = true
|
|
end
|
|
end
|
|
return closed
|
|
end
|
|
|
|
-----------------
|
|
-- Gui Classes --
|
|
-----------------
|
|
local FrameBackdrop = {
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 16,
|
|
insets = { left = 3, right = 3, top = 30, bottom = 3 }
|
|
}
|
|
|
|
local PaneBackdrop = {
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 16,
|
|
insets = { left = 3, right = 3, top = 23, bottom = 3 }
|
|
}
|
|
|
|
local ControlBackdrop = {
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 16,
|
|
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
|
}
|
|
|
|
|
|
|
|
-- virtual class to contain frame functions
|
|
local FramePassthrough = AceOO.Class()
|
|
FramePassthrough.virtual = true
|
|
|
|
function FramePassthrough.prototype:SetPoint(point,relativeTo,relativePoint,xOffset,yOffset)
|
|
self.frame:SetPoint(point,(relativeTo and relativeTo.frame) or relativeTo,relativePoint,xOffset,yOffset)
|
|
end
|
|
function FramePassthrough.prototype:SetAllPoints(frame)
|
|
self.frame:SetAllPoints(frame.frame or frame)
|
|
end
|
|
function FramePassthrough.prototype:SetWidth(...)
|
|
self.frame:SetWidth(unpack(arg))
|
|
end
|
|
function FramePassthrough.prototype:SetHeight(...)
|
|
self.frame:SetHeight(unpack(arg))
|
|
end
|
|
function FramePassthrough.prototype:SetMinResize(...)
|
|
self.frame:SetMinResize(unpack(arg))
|
|
end
|
|
function FramePassthrough.prototype:SetMaxResize(...)
|
|
self.frame:SetMaxResize(unpack(arg))
|
|
end
|
|
function FramePassthrough.prototype:ClearAllPoints()
|
|
self.frame:ClearAllPoints()
|
|
end
|
|
function FramePassthrough.prototype:Show()
|
|
self.frame:Show()
|
|
end
|
|
function FramePassthrough.prototype:Hide()
|
|
self.frame:Hide()
|
|
end
|
|
function FramePassthrough.prototype:GetHeight()
|
|
return self.frame:GetHeight()
|
|
end
|
|
function FramePassthrough.prototype:GetWidth()
|
|
return self.frame:GetWidth()
|
|
end
|
|
|
|
-- Base Class for Gui Controls
|
|
local WaterfallControl = AceOO.Class(FramePassthrough)
|
|
WaterfallControl.virtual = true
|
|
|
|
function WaterfallControl.prototype:init(frametype,inherits)
|
|
WaterfallControl.super.prototype.init(self)
|
|
local frame = CreateFrame(frametype or "Frame",nil,nil,inherits)
|
|
self.frame = frame
|
|
frame.obj = self
|
|
frame:SetFrameLevel(10)
|
|
frame:SetFrameStrata("DIALOG")
|
|
end
|
|
|
|
function WaterfallControl.prototype:SetParent(parent)
|
|
self.parent = parent
|
|
self.frame:SetParent(parent.scrollchild)
|
|
end
|
|
|
|
function WaterfallControl.prototype:Refresh()
|
|
|
|
end
|
|
|
|
--basic cleanup function, usually overridden
|
|
function WaterfallControl.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self.disabled = nil
|
|
self:SetFunc("disabled",nil)
|
|
end
|
|
|
|
function WaterfallControl.prototype:SetFunc(funcType,func,...)
|
|
self[funcType.."Func"] = func
|
|
local i = 1
|
|
while self[funcType.."Arg"..i] do
|
|
self[funcType.."Arg"..i] = nil
|
|
i = i + 1
|
|
end
|
|
for i = 1 , table.getn(arg) do
|
|
self[funcType.."Arg"..i] = arg[i]
|
|
end
|
|
end
|
|
|
|
local function Control_OnEnter()
|
|
showGameTooltip(this.obj)
|
|
end
|
|
|
|
local function Control_OnLeave()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
--the main waterfall frame
|
|
WaterfallFrame = AceOO.Class(FramePassthrough)
|
|
--the right side pane with gui components in it
|
|
WaterfallPane = AceOO.Class(FramePassthrough)
|
|
|
|
--gui components to be placed on the pane
|
|
WaterfallLabel = AceOO.Class(WaterfallControl)
|
|
WaterfallLinklabel = AceOO.Class(WaterfallControl)
|
|
WaterfallCheckBox = AceOO.Class(WaterfallControl)
|
|
WaterfallDragLink = AceOO.Class(WaterfallControl)
|
|
WaterfallButton = AceOO.Class(WaterfallControl)
|
|
WaterfallHeading = AceOO.Class(WaterfallControl)
|
|
WaterfallTextBox = AceOO.Class(WaterfallControl)
|
|
WaterfallSlider = AceOO.Class(WaterfallControl)
|
|
WaterfallColorSwatch = AceOO.Class(WaterfallControl)
|
|
WaterfallDropdown = AceOO.Class(WaterfallControl)
|
|
WaterfallKeybinding = AceOO.Class(WaterfallControl)
|
|
|
|
--the left side treeview pane
|
|
WaterfallTreeView = AceOO.Class(FramePassthrough)
|
|
WaterfallTreeLine = AceOO.Class(FramePassthrough)
|
|
WaterfallTreeSection = AceOO.Class(FramePassthrough)
|
|
|
|
---------------------------
|
|
-- Waterfall Frame Class --
|
|
---------------------------
|
|
|
|
local function frameOnClose()
|
|
this.obj.lib:Close(this.obj.id)
|
|
end
|
|
|
|
local function closeOnClick()
|
|
this.obj:Hide()
|
|
end
|
|
|
|
local function frameOnMouseDown()
|
|
this:GetParent():StartMoving()
|
|
end
|
|
|
|
local function frameOnMouseUp()
|
|
this:GetParent():StopMovingOrSizing()
|
|
end
|
|
|
|
local function sizerseOnMouseDown()
|
|
this:GetParent():StartSizing("BOTTOMRIGHT")
|
|
end
|
|
|
|
local function sizersOnMouseDown()
|
|
this:GetParent():StartSizing("BOTTOM")
|
|
end
|
|
|
|
local function sizereOnMouseDown()
|
|
this:GetParent():StartSizing("RIGHT")
|
|
end
|
|
|
|
local function sizerOnMouseUp()
|
|
this:GetParent():StopMovingOrSizing()
|
|
end
|
|
|
|
|
|
function WaterfallFrame.prototype:init()
|
|
WaterfallFrame.super.prototype.init(self)
|
|
local frame = CreateFrame("Frame",nil,UIParent)
|
|
self.frame = frame
|
|
frame.obj = self
|
|
frame:SetWidth(550)
|
|
frame:SetHeight(500)
|
|
frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
|
|
frame:EnableMouse()
|
|
frame:SetMovable(true)
|
|
frame:SetResizable(true)
|
|
frame:SetMinResize(500,300)
|
|
frame:SetFrameLevel(1)
|
|
frame:SetFrameStrata("DIALOG")
|
|
|
|
frame:SetBackdrop(FrameBackdrop)
|
|
frame:SetBackdropColor(0,0,0)
|
|
frame:SetScript("OnHide",frameOnClose)
|
|
|
|
local titlebar = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar = titlebar
|
|
local titlebar2 = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar2 = titlebar2
|
|
local r,g,b = 1, 0.6, 0
|
|
self.colorR = r
|
|
self.colorG = g
|
|
self.colorB = b
|
|
|
|
titlebar:SetPoint("TOPLEFT",frame,"TOPLEFT",3,-4)
|
|
titlebar:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-3,-4)
|
|
titlebar:SetHeight(13)
|
|
|
|
titlebar2:SetPoint("TOPLEFT",titlebar,"BOTTOMLEFT",0,0)
|
|
titlebar2:SetPoint("TOPRIGHT",titlebar,"BOTTOMRIGHT",0,0)
|
|
titlebar2:SetHeight(13)
|
|
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
|
|
local closebutton = CreateFrame("Button",nil,frame,"UIPanelCloseButton")
|
|
closebutton:SetScript("OnClick", closeOnClick)
|
|
closebutton:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-2,-2)
|
|
|
|
self.closebutton = closebutton
|
|
closebutton.obj = self
|
|
|
|
local title = CreateFrame("Frame",nil,frame)
|
|
self.title = title
|
|
title:EnableMouse()
|
|
title:SetScript("OnMouseDown",frameOnMouseDown)
|
|
title:SetScript("OnMouseUp", frameOnMouseUp)
|
|
|
|
|
|
title:SetPoint("TOPLEFT",titlebar,"TOPLEFT",0,0)
|
|
title:SetPoint("BOTTOMRIGHT",titlebar2,"BOTTOMRIGHT",0,0)
|
|
|
|
local titletext = title:CreateFontString(nil,"OVERLAY","QuestTitleFont")
|
|
titletext:SetPoint("TOPLEFT",title,"TOPLEFT",0,0)
|
|
titletext:SetPoint("TOPRIGHT",title,"TOPRIGHT",0,0)
|
|
titletext:SetHeight(26)
|
|
titletext:SetShadowColor(0,0,0)
|
|
titletext:SetShadowOffset(1,-1)
|
|
titletext:SetTextColor(1,1,1)
|
|
|
|
self.titletext = titletext
|
|
|
|
local sizer_se = CreateFrame("Frame",nil,frame)
|
|
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
|
sizer_se:SetWidth(25)
|
|
sizer_se:SetHeight(25)
|
|
sizer_se:EnableMouse()
|
|
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
|
|
sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
|
|
self.sizer_se = sizer_se
|
|
|
|
local sizer_s = CreateFrame("Frame",nil,frame)
|
|
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
|
|
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
|
sizer_s:SetHeight(25)
|
|
sizer_s:EnableMouse()
|
|
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
|
|
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
|
|
self.sizer_s = sizer_s
|
|
|
|
local sizer_e = CreateFrame("Frame",nil,frame)
|
|
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
|
|
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
|
|
sizer_e:SetWidth(25)
|
|
sizer_e:EnableMouse()
|
|
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
|
|
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
|
|
self.sizer_e = sizer_e
|
|
|
|
local treeview = WaterfallTreeView:new(self)
|
|
self.treeview = treeview
|
|
treeview:SetPoint("TOPLEFT",frame,"TOPLEFT",11,-32)
|
|
treeview:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",11,10)
|
|
treeview:SetWidth(200)
|
|
treeview:SetMinResize(200,0)
|
|
treeview:SetMaxResize(400,10000)
|
|
|
|
local mainpane = WaterfallPane:new(self)
|
|
|
|
mainpane:SetPoint("TOPLEFT",treeview.frame,"TOPRIGHT",-3,0)
|
|
mainpane:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-10,10)
|
|
self.mainpane = mainpane
|
|
|
|
end
|
|
|
|
function WaterfallFrame.prototype:SetColor(r,g,b)
|
|
self.colorR, self.colorG, self.colorB = r,g,b
|
|
local titlebar = self.titlebar
|
|
local titlebar2 = self.titlebar2
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
self.mainpane:SetColor(r,g,b)
|
|
end
|
|
|
|
function WaterfallFrame.prototype:GetColor()
|
|
return self.colorR, self.colorG, self.colorB
|
|
end
|
|
|
|
function WaterfallFrame.prototype:Hide()
|
|
self.frame:Hide()
|
|
end
|
|
|
|
function WaterfallFrame.prototype:Show()
|
|
self.frame:Show()
|
|
end
|
|
|
|
function WaterfallFrame.prototype:SetID(id)
|
|
self.id = id
|
|
end
|
|
|
|
function WaterfallFrame.prototype:ChangePane(newpane)
|
|
|
|
self.mainpane:Clear(newpane)
|
|
self.controlcount = 0
|
|
currentframe = self
|
|
if self.children then
|
|
local title = self.children(newpane, self.childrenArg)
|
|
self.mainpane.titletext:SetText(title)
|
|
end
|
|
currentframe = nil
|
|
self.mainpane:DoLayout()
|
|
self.mainpane.paneid = newpane
|
|
end
|
|
|
|
function WaterfallFrame.prototype:SetSelected(id, noupdate)
|
|
|
|
self.treeview:SetSelected(id, noupdate)
|
|
end
|
|
|
|
function WaterfallFrame.prototype:SetTitle(title)
|
|
self.titletext:SetText(title)
|
|
end
|
|
|
|
function WaterfallFrame.prototype:SetChildren(children, arg)
|
|
self.children = children
|
|
self.childrenArg = arg
|
|
end
|
|
function WaterfallFrame.prototype:SetTree(tree, treestatus, func, ...)
|
|
self.treeview:SetContent(tree, treestatus, func, unpack(arg))
|
|
end
|
|
|
|
function WaterfallFrame.prototype:AddControl(control)
|
|
self.mainpane:AddControl(control)
|
|
end
|
|
|
|
function WaterfallFrame.prototype:Refresh()
|
|
self.treeview:Refresh()
|
|
self:ChangePane(self.treeview:GetSelected())
|
|
end
|
|
|
|
function WaterfallFrame.prototype:CleanUp()
|
|
self.children = nil
|
|
self.tree = nil
|
|
self.treeview:CleanUp()
|
|
self:ChangePane()
|
|
self:Hide()
|
|
end
|
|
|
|
function WaterfallFrame.prototype:ReAnchorTree()
|
|
self.treeview:SetPoint("TOPLEFT",self.frame,"TOPLEFT",11,-32)
|
|
self.treeview:SetPoint("BOTTOMLEFT",self.frame,"BOTTOMLEFT",11,10)
|
|
end
|
|
-------------------------
|
|
-- WaterfallPane Class --
|
|
-------------------------
|
|
|
|
local function paneOnSizeChanged()
|
|
this.obj:SizeChanged()
|
|
end
|
|
local function paneOnMouseWheel()
|
|
this.obj:MoveScroll(arg1)
|
|
end
|
|
local function paneOnSizeChanged()
|
|
this.obj:DoLayout()
|
|
end
|
|
local function paneOnScrollValueChanged(self,value)
|
|
this.obj:SetScroll(arg1)
|
|
end
|
|
local numpanes = 0
|
|
function WaterfallPane.prototype:init(parent)
|
|
WaterfallPane.super.prototype.init(self)
|
|
numpanes = numpanes + 1
|
|
self.parent = parent
|
|
local name = "WaterfallPane"..numpanes
|
|
local frame = CreateFrame("Frame",name,parent.frame)
|
|
frame:SetBackdrop(PaneBackdrop)
|
|
frame:SetBackdropBorderColor(0.6, 0.6, 0.6)
|
|
frame:SetBackdropColor(0.1, 0.1, 0.1)
|
|
frame:SetFrameLevel(2)
|
|
frame:SetFrameStrata("DIALOG")
|
|
self.frame = frame
|
|
frame.obj = self
|
|
frame:SetScript("OnSizeChanged",paneOnSizeChanged)
|
|
|
|
--local title = CreateFrame("Frame",nil,frame)
|
|
--title:SetPoint("TOPLEFT",frame,"TOPLEFT",4,-4)
|
|
--title:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-4,-4)
|
|
--title:SetHeight(24)
|
|
--title:SetBackdrop(PaneBackdrop)
|
|
--title:SetBackdropColor(0,0,0,0.2)
|
|
--self.title = title
|
|
|
|
local scrollframe = CreateFrame("ScrollFrame",name.."ScrollFrame",frame)
|
|
local scrollchild = CreateFrame("Frame",name.."ChildFrame",scrollframe)
|
|
local scrollbar = CreateFrame("Slider",name.."ScrollBar",scrollframe,"UIPanelScrollBarTemplate")
|
|
self.scrollframe = scrollframe
|
|
self.scrollchild = scrollchild
|
|
self.scrollbar = scrollbar
|
|
|
|
scrollframe:SetScrollChild(scrollchild)
|
|
scrollframe:SetPoint("TOPLEFT",frame,"TOPLEFT",9,-29)
|
|
scrollframe:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-28,12)
|
|
scrollframe:EnableMouseWheel(true)
|
|
scrollframe:SetScript("OnMouseWheel", paneOnMouseWheel)
|
|
scrollframe:SetScript("OnSizeChanged", paneOnSizeChanged)
|
|
scrollframe.obj = self
|
|
|
|
--scrollchild:SetPoint("TOPLEFT",scrollframe,"TOPLEFT",0,0)
|
|
--scrollchild:SetPoint("BOTTOMRIGHT",scrollframe,"BOTTOMRIGHT",0,0)
|
|
scrollchild:ClearAllPoints()
|
|
scrollchild:SetPoint("TOPLEFT",scrollframe,"TOPLEFT",0,0)
|
|
scrollchild:SetWidth(400)
|
|
|
|
scrollbar:SetPoint("TOPLEFT",scrollframe,"TOPRIGHT",0,-16)
|
|
scrollbar:SetPoint("BOTTOMLEFT",scrollframe,"BOTTOMRIGHT",0,16)
|
|
scrollbar:SetMinMaxValues(0,1000)
|
|
scrollbar:SetValueStep(1)
|
|
scrollbar:SetValue(0)
|
|
scrollbar:SetWidth(16)
|
|
scrollbar:SetScript("OnValueChanged", paneOnScrollValueChanged)
|
|
scrollbar.obj = self
|
|
self.scrollvalue = 0
|
|
|
|
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",8,-5)
|
|
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-8,-5)
|
|
titletext:SetHeight(16)
|
|
titletext:SetText("")
|
|
titletext:SetTextColor(1,1,1)
|
|
|
|
local r,g,b = 1, 0.6, 0
|
|
self.colorR = r
|
|
self.colorG = g
|
|
self.colorB = b
|
|
local titlebar = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar = titlebar
|
|
local titlebar2 = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar2 = titlebar2
|
|
titlebar:SetPoint("TOPLEFT",frame,"TOPLEFT",4,-4)
|
|
titlebar:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-4,-4)
|
|
titlebar:SetHeight(10)
|
|
titlebar2:SetPoint("TOPLEFT",titlebar,"BOTTOMLEFT",0,0)
|
|
titlebar2:SetPoint("TOPRIGHT",titlebar,"BOTTOMRIGHT",0,0)
|
|
titlebar2:SetHeight(10)
|
|
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
|
|
--titletext:SetTextColor(1,1,1)
|
|
self.titletext = titletext
|
|
|
|
self.controls = {}
|
|
end
|
|
|
|
function WaterfallPane.prototype:GetID()
|
|
return self.parent.id
|
|
end
|
|
|
|
function WaterfallPane.prototype:SetScroll(value)
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local viewheight = frame:GetHeight()
|
|
local height = child:GetHeight()
|
|
local width, viewwidth = frame:GetWidth(), child:GetWidth()
|
|
local offset
|
|
local xOffset = max(0, (width-viewwidth)/2 )
|
|
if viewheight > height then
|
|
offset = 0
|
|
else
|
|
offset = floor((height - viewheight) / 1000.0 * (value or 0))
|
|
end
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",xOffset,offset)
|
|
child.offset = offset
|
|
|
|
self.scrollvalue = value
|
|
end
|
|
|
|
--[[
|
|
horiz scrolling version
|
|
function WaterfallPane.prototype:SetScroll(value)
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local viewheight = frame:GetWidth()
|
|
local height = child:GetWidth()
|
|
local offset
|
|
if viewheight > height then
|
|
offset = 0
|
|
else
|
|
offset = floor((height - viewheight) / 1000.0 * value)
|
|
end
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",-offset,0)
|
|
child:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",-offset,0)
|
|
child.offset = offset
|
|
|
|
self.scrollvalue = value
|
|
end
|
|
]]
|
|
function WaterfallPane.prototype:MoveScroll(value)
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
|
if height > viewheight then
|
|
self.scrollbar:Hide()
|
|
else
|
|
self.scrollbar:Show()
|
|
local diff = height - viewheight
|
|
local delta = 1
|
|
if value < 0 then
|
|
delta = -1
|
|
end
|
|
self.scrollbar:SetValue(min(max(self.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
|
end
|
|
end
|
|
|
|
function WaterfallPane.prototype:SetColor(r,g,b)
|
|
self.colorR, self.colorG, self.colorB = r,g,b
|
|
local titlebar = self.titlebar
|
|
local titlebar2 = self.titlebar2
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
end
|
|
|
|
function WaterfallPane.prototype:Clear(newpane)
|
|
for i = 1, table.getn(self.controls) do
|
|
releaseObj(self.controls[i])
|
|
self.controls[i] = nil
|
|
end
|
|
table_setn(self.controls,0)
|
|
if self.paneid ~= newpane then
|
|
self:SetScroll(0)
|
|
end
|
|
end
|
|
|
|
function WaterfallPane.prototype:ClearFocus()
|
|
for i, v in ipairs(self.controls) do
|
|
if v.class == WaterfallTextBox then
|
|
v.frame:ClearFocus()
|
|
end
|
|
end
|
|
end
|
|
|
|
function WaterfallPane.prototype:AddControl(control)
|
|
tinsert(self.controls, control)
|
|
control:SetParent(self)
|
|
end
|
|
|
|
--simple one under the other layout for now
|
|
function WaterfallPane.prototype:DoLayout()
|
|
|
|
local usedheight = 0
|
|
local maxwidth = 0
|
|
local rowwidth = 1
|
|
local rowheight = 1
|
|
for i, control in ipairs(self.controls) do
|
|
control:ClearAllPoints()
|
|
if i == 1 then
|
|
control:SetPoint("TOPLEFT",self.scrollchild,"TOPLEFT",10,0)
|
|
rowheight = control:GetHeight()
|
|
rowwidth = control:GetWidth() + 10
|
|
else
|
|
if control.noNewLine then
|
|
control:SetPoint("TOPLEFT",self.controls[i-1],"TOPRIGHT",0,0)
|
|
rowheight = max(rowheight,control:GetHeight())
|
|
rowwidth = rowwidth + control:GetWidth()
|
|
else
|
|
usedheight = usedheight + rowheight
|
|
maxwidth = max(rowwidth,maxwidth)
|
|
control:SetPoint("TOPLEFT",self.scrollchild,"TOPLEFT",10,-usedheight)
|
|
rowheight = control:GetHeight()
|
|
rowwidth = control:GetWidth()
|
|
end
|
|
end
|
|
control:Show()
|
|
end
|
|
maxwidth = max(rowwidth,maxwidth)
|
|
|
|
self.scrollchild:SetHeight(usedheight+rowheight)
|
|
self.scrollchild:SetWidth(maxwidth+5)
|
|
|
|
self:FixScroll()
|
|
end
|
|
|
|
--[[
|
|
function WaterfallPane.prototype:DoLayout()
|
|
local colheight = 0
|
|
local sectionheight = 0
|
|
local sectionwidth = 0
|
|
local colwidth = 0
|
|
local usedwidth = 0
|
|
local frameheight = self.scrollchild:GetHeight()
|
|
for i, control in ipairs(self.controls) do
|
|
colheight = colheight + control:GetHeight()
|
|
colwidth = max(colwidth, control:GetWidth())
|
|
control:ClearAllPoints()
|
|
if colheight <= (frameheight - 10) then
|
|
if i == 1 then
|
|
control:SetPoint("TOPLEFT",self.scrollchild,"TOPLEFT",4,0)
|
|
else
|
|
control:SetPoint("TOPLEFT",self.controls[i-1],"BOTTOMLEFT",0,0)
|
|
end
|
|
else
|
|
usedwidth = usedwidth + colwidth + 6
|
|
colwidth = 0
|
|
colheight = 0
|
|
control:SetPoint("TOPLEFT",self.scrollchild,"TOPLEFT",4+usedwidth,0)
|
|
end
|
|
control:Show()
|
|
end
|
|
usedwidth = usedwidth + colwidth
|
|
|
|
self.scrollchild:SetWidth(usedwidth)
|
|
self:FixScroll()
|
|
end
|
|
]]
|
|
function WaterfallPane.prototype:SizeChanged()
|
|
self:FixScroll()
|
|
end
|
|
|
|
function WaterfallPane.prototype:FixScroll()
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
|
local width, viewwidth = frame:GetWidth(), child:GetWidth()
|
|
local offset = self.scrollchild.offset
|
|
if not offset then
|
|
offset = 0
|
|
end
|
|
local curvalue = self.scrollbar:GetValue()
|
|
local xOffset = max(0, (width-viewwidth)/2 )
|
|
if viewheight < height then
|
|
self.scrollbar:Hide()
|
|
--self.scrollbar:SetValue(0)
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",xOffset,0)
|
|
child.offset = 0
|
|
else
|
|
self.scrollbar:Show()
|
|
local value = (offset / (viewheight - height) * 1000)
|
|
if value > 1000 then value = 1000 end
|
|
self.scrollbar:SetValue(value)
|
|
self:SetScroll(value)
|
|
if value < 1000 then
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",xOffset,offset)
|
|
child.offset = offset
|
|
end
|
|
end
|
|
end
|
|
--[[
|
|
horiz scrolling version
|
|
function WaterfallPane.prototype:FixScroll()
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local height, viewheight = frame:GetWidth(), child:GetWidth()
|
|
local offset = self.scrollchild.offset
|
|
if not offset then
|
|
offset = 0
|
|
end
|
|
local curvalue = self.scrollbar:GetValue()
|
|
|
|
if viewheight < height then
|
|
self.scrollbar:EnableMouse(false)
|
|
self.scrollbar:SetValue(0)
|
|
else
|
|
self.scrollbar:EnableMouse(true)
|
|
local value = (offset / (viewheight - height) * 1000)
|
|
if value > 1000 then value = 1000 end
|
|
self.scrollbar:SetValue(value)
|
|
self:SetScroll(value)
|
|
if value < 1000 then
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",-offset,0)
|
|
child:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",-offset,0)
|
|
child.offset = offset
|
|
end
|
|
end
|
|
end
|
|
]]
|
|
function WaterfallPane.prototype:Refresh(fullRefresh)
|
|
if fullRefresh then
|
|
self.parent:Refresh()
|
|
else
|
|
for i, control in ipairs(self.controls) do
|
|
control:Refresh()
|
|
end
|
|
end
|
|
self:FixScroll()
|
|
end
|
|
|
|
-----------------
|
|
-- Label Class --
|
|
-----------------
|
|
|
|
function WaterfallLabel.prototype:init()
|
|
WaterfallLabel.super.prototype.init(self)
|
|
local frame = self.frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
self.text = text
|
|
frame.text = text
|
|
|
|
text:SetText("Waterfalllabel")
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
text:SetHeight(16)
|
|
text:SetPoint("LEFT",frame,"LEFT")
|
|
end
|
|
|
|
--fontstrings dont return the correct width untill they have been drawn, wait a frame to set the width
|
|
local function labelFixWidth()
|
|
if not this.obj.width then
|
|
this:SetWidth(this.text:GetWidth()+3)
|
|
end
|
|
this:SetScript("OnUpdate",nil)
|
|
end
|
|
|
|
function WaterfallLabel.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
self:Refresh()
|
|
end
|
|
|
|
function WaterfallLabel.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
end
|
|
|
|
function WaterfallLabel.prototype:Refresh()
|
|
self.frame:SetHeight(self.height or 16)
|
|
if self.width then
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT",self.frame,"LEFT")
|
|
self.text:SetPoint("RIGHT",self.frame,"RIGHT")
|
|
self:SetWidth(self.width)
|
|
else
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT",self.frame,"LEFT")
|
|
self.frame:SetScript("OnUpdate", labelFixWidth)
|
|
end
|
|
self.text:SetJustifyH(self.justifyH or "LEFT")
|
|
self.text:SetTextColor(self.r or 1, self.g or 1, self.b or 1)
|
|
end
|
|
|
|
-----------------
|
|
-- Linklabel Class --
|
|
-----------------
|
|
local function Linklabel_OnEnter()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self.highlight:Show()
|
|
showGameTooltip(self)
|
|
end
|
|
end
|
|
|
|
local function Linklabel_OnLeave()
|
|
this.obj.highlight:Hide()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function linkConfirmFunc(self, refresh, full, func, ...)
|
|
func(unpack(arg))
|
|
|
|
if refresh or full then
|
|
self.parent:Refresh(full)
|
|
end
|
|
end
|
|
|
|
local function Linklabel_OnClick()
|
|
local self = this.obj
|
|
local func = self.linkFunc
|
|
local confirm = this.obj.confirm
|
|
|
|
if func then
|
|
if confirm then
|
|
if type(confirm) == "string" then
|
|
confirmPopup(confirm,linkConfirmFunc,self,self.causesRefresh,self.fullRefresh,func,getArgs(this.obj,"linkArg",1))
|
|
else
|
|
confirmPopup((ARE_YOU_SURE):format(this.obj.text:GetText()),linkConfirmFunc,
|
|
self,self.causesRefresh,self.fullRefresh,func,getArgs(this.obj,"linkArg",1))
|
|
end
|
|
else
|
|
func(getArgs(this.obj,"linkArg",1))
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
end
|
|
|
|
function WaterfallLinklabel.prototype:init()
|
|
WaterfallLinklabel.super.prototype.init(self, "Button")
|
|
local frame = self.frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
self.text = text
|
|
frame.text = text
|
|
frame:SetScript("OnClick", Linklabel_OnClick)
|
|
frame:SetScript("OnEnter", Linklabel_OnEnter)
|
|
frame:SetScript("OnLeave", Linklabel_OnLeave)
|
|
|
|
text:SetText("WaterfallLinklabel")
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
text:SetHeight(16)
|
|
text:SetPoint("LEFT",frame,"LEFT")
|
|
|
|
local highlight = frame:CreateTexture(nil, "BACKGROUND")
|
|
self.highlight = highlight
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(frame)
|
|
highlight:Hide()
|
|
|
|
frame:EnableMouse()
|
|
end
|
|
|
|
function WaterfallLinklabel.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
self:Refresh()
|
|
end
|
|
|
|
function WaterfallLinklabel.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
end
|
|
|
|
function WaterfallLinklabel.prototype:Refresh()
|
|
self.frame:SetHeight(self.height or 16)
|
|
|
|
if self.width then
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT",self.frame,"LEFT")
|
|
self.text:SetPoint("RIGHT",self.frame,"RIGHT")
|
|
self:SetWidth(self.width)
|
|
else
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT")
|
|
self.frame:SetScript("OnUpdate", labelFixWidth)
|
|
end
|
|
self.text:SetJustifyH(self.justifyH or "LEFT")
|
|
self.text:SetTextColor(self.r or 1, self.g or 1, self.b or 1)
|
|
end
|
|
|
|
function WaterfallLinklabel.prototype:SetColor(r,g,b)
|
|
self.r = r
|
|
self.g = g
|
|
self.b = b
|
|
self:Refresh()
|
|
end
|
|
|
|
-----------------
|
|
-- ColorSwatch Class --
|
|
-----------------
|
|
local tmpt = setmetatable({}, {mode='v'})
|
|
local function ColorSwatch_OnClick()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
local func = self.setFunc
|
|
local hasOpacity = self.hasOpacity
|
|
|
|
for k in pairs(tmpt) do
|
|
tmpt[k] = nil
|
|
end
|
|
for i = 1, 1000 do
|
|
local x = self['setArg'..i]
|
|
if x == nil then
|
|
break
|
|
else
|
|
tmpt[i] = x
|
|
end
|
|
end
|
|
ColorPickerFrame.func = function()
|
|
if func then
|
|
local r,g,b = ColorPickerFrame:GetColorRGB()
|
|
local a = hasOpacity and 1 - OpacitySliderFrame:GetValue() or nil
|
|
local n = table.getn(tmpt)
|
|
tmpt[n+1] = r
|
|
tmpt[n+2] = g
|
|
tmpt[n+3] = b
|
|
tmpt[n+4] = a
|
|
func(unpack(tmpt))
|
|
self:SetColor(r,g,b,a)
|
|
tmpt[n+1] = nil
|
|
tmpt[n+2] = nil
|
|
tmpt[n+3] = nil
|
|
tmpt[n+4] = nil
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
end
|
|
ColorPickerFrame.hasOpacity = self.hasOpacity
|
|
ColorPickerFrame.opacityFunc = ColorPickerFrame.func
|
|
ColorPickerFrame.opacity = 1 - (self.opacity or 0)
|
|
ColorPickerFrame:SetColorRGB(self.r, self.g, self.b)
|
|
local r, g, b, a = self.r, self.g, self.b, self.opacity
|
|
ColorPickerFrame.cancelFunc = function()
|
|
if func then
|
|
local n = table.getn(tmpt)
|
|
tmpt[n+1] = r
|
|
tmpt[n+2] = g
|
|
tmpt[n+3] = b
|
|
tmpt[n+4] = a
|
|
func(unpack(tmpt))
|
|
self:SetColor(r,g,b,a)
|
|
for i = 1, n+4 do
|
|
tmpt[i] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
ColorPickerFrame:SetFrameStrata(self.frame:GetFrameStrata())
|
|
ColorPickerFrame:SetFrameLevel(self.frame:GetParent():GetFrameLevel()+1)
|
|
for i, child in ipairs({ColorPickerFrame:GetChildren()}) do
|
|
-- child:SetFrameStrata(self.frame:GetFrameStrata())
|
|
child:SetFrameLevel(self.frame:GetParent():GetFrameLevel()+2)
|
|
end
|
|
ShowUIPanel(ColorPickerFrame)
|
|
end
|
|
end
|
|
|
|
local function ColorSwatch_OnEnter()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self.highlight:Show()
|
|
showGameTooltip(self)
|
|
end
|
|
end
|
|
|
|
local function ColorSwatch_OnLeave()
|
|
|
|
this.obj.highlight:Hide()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
function WaterfallColorSwatch.prototype:init()
|
|
WaterfallColorSwatch.super.prototype.init(self,"Button")
|
|
local frame = self.frame
|
|
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
self.text = text
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
text:SetHeight(24)
|
|
frame:SetScript("OnClick", ColorSwatch_OnClick)
|
|
frame:SetScript("OnEnter",ColorSwatch_OnEnter)
|
|
frame:SetScript("OnLeave",ColorSwatch_OnLeave)
|
|
|
|
local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
|
|
self.colorSwatch = colorSwatch
|
|
colorSwatch:SetWidth(24)
|
|
colorSwatch:SetHeight(24)
|
|
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
|
|
local texture = frame:CreateTexture(nil, "OVERLAY")
|
|
colorSwatch.texture = texture
|
|
texture:SetTexture(1, 1, 1)
|
|
texture:SetWidth(13.8)
|
|
texture:SetHeight(13.8)
|
|
texture:Show()
|
|
|
|
local highlight = frame:CreateTexture(nil, "BACKGROUND")
|
|
self.highlight = highlight
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(frame)
|
|
highlight:Hide()
|
|
|
|
texture:SetPoint("CENTER", colorSwatch, "CENTER")
|
|
colorSwatch:SetPoint("LEFT", frame, "LEFT", 0, 0)
|
|
text:SetPoint("LEFT",colorSwatch,"RIGHT",2,0)
|
|
text:SetPoint("RIGHT",frame,"RIGHT")
|
|
end
|
|
|
|
function WaterfallColorSwatch.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
end
|
|
|
|
function WaterfallColorSwatch.prototype:SetColor(r,g,b,a)
|
|
self.r = r
|
|
self.g = g
|
|
self.b = b
|
|
self.opacity = a
|
|
self:Refresh()
|
|
end
|
|
|
|
function WaterfallColorSwatch.prototype:Refresh()
|
|
if self.getFunc then
|
|
self.r, self.g, self.b, self.opacity = self.getFunc(getArgs(self,"getArg",1))
|
|
end
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
self.colorSwatch.texture:SetTexture(self.r,self.g,self.b)
|
|
if self.disabled then
|
|
self.text:SetTextColor(0.5,0.5,0.5)
|
|
else
|
|
self.text:SetTextColor(1,1,1)
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
function WaterfallColorSwatch.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("color",nil)
|
|
self.r = nil
|
|
self.g = nil
|
|
self.b = nil
|
|
self.hasOpacity = nil
|
|
self.opacity = nil
|
|
self.disabled = nil
|
|
self:SetFunc("disabled",nil)
|
|
end
|
|
|
|
|
|
|
|
-----------------
|
|
-- Heading Class --
|
|
-----------------
|
|
|
|
function WaterfallHeading.prototype:init()
|
|
WaterfallHeading.super.prototype.init(self)
|
|
local frame = self.frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
self.text = text
|
|
frame.text = text
|
|
|
|
text:SetJustifyH("LEFT")
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
text:SetHeight(24)
|
|
text:SetPoint("LEFT",frame,"LEFT")
|
|
end
|
|
|
|
function WaterfallHeading.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
self.frame:SetScript("OnUpdate", labelFixWidth)
|
|
end
|
|
|
|
function WaterfallHeading.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
end
|
|
|
|
function WaterfallHeading.prototype:Refresh()
|
|
self.frame:SetHeight(self.height or 16)
|
|
if self.width then
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT",self.frame,"LEFT")
|
|
self.text:SetPoint("RIGHT",self.frame,"RIGHT")
|
|
self:SetWidth(self.width)
|
|
else
|
|
self.text:ClearAllPoints()
|
|
self.text:SetPoint("LEFT",self.frame,"LEFT")
|
|
self.frame:SetScript("OnUpdate", labelFixWidth)
|
|
end
|
|
self.text:SetJustifyH(self.justifyH or "LEFT")
|
|
end
|
|
-----------------
|
|
-- CheckBox Class --
|
|
-----------------
|
|
|
|
local function CheckBox_OnEnter()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self.highlight:Show()
|
|
showGameTooltip(self)
|
|
end
|
|
end
|
|
|
|
local function CheckBox_OnLeave()
|
|
local self = this.obj
|
|
if not self.down then
|
|
self.highlight:Hide()
|
|
end
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function CheckBox_OnMouseUp()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self:ToggleChecked()
|
|
self.text:SetPoint("LEFT",self.check,"RIGHT",0,0)
|
|
end
|
|
self.down = nil
|
|
end
|
|
|
|
local function CheckBox_OnMouseDown()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self.text:SetPoint("LEFT",self.check,"RIGHT",1,-1)
|
|
self.down = true
|
|
end
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:init()
|
|
WaterfallCheckBox.super.prototype.init(self,"Button")
|
|
|
|
local frame = self.frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
self.text = text
|
|
|
|
frame:SetScript("OnEnter",CheckBox_OnEnter)
|
|
frame:SetScript("OnLeave",CheckBox_OnLeave)
|
|
frame:SetScript("OnMouseUp",CheckBox_OnMouseUp)
|
|
frame:SetScript("OnMouseDown",CheckBox_OnMouseDown)
|
|
frame:EnableMouse()
|
|
local checkbg = frame:CreateTexture(nil,"ARTWORK")
|
|
self.checkbg = checkbg
|
|
checkbg:SetWidth(20)
|
|
checkbg:SetHeight(20)
|
|
checkbg:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
|
|
local check = frame:CreateTexture(nil,"OVERLAY")
|
|
self.check = check
|
|
check:SetWidth(20)
|
|
check:SetHeight(20)
|
|
check:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
|
|
self.checked = false
|
|
self:UpdateCheck()
|
|
|
|
local highlight = frame:CreateTexture(nil, "BACKGROUND")
|
|
self.highlight = highlight
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(frame)
|
|
highlight:Hide()
|
|
|
|
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
text:SetHeight(24)
|
|
text:SetPoint("LEFT",check,"RIGHT",0,0)
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:UpdateTexture()
|
|
local checkbg = self.checkbg
|
|
local check = self.check
|
|
local highlight = self.highlight
|
|
|
|
if self.isRadio then
|
|
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton")
|
|
checkbg:SetTexCoord(0,0.25,0,1)
|
|
check:SetTexture("Interface\\Buttons\\UI-RadioButton")
|
|
check:SetTexCoord(0.5,0.75,0,1)
|
|
check:SetBlendMode("ADD")
|
|
else
|
|
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
|
|
checkbg:SetTexCoord(0,1,0,1)
|
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
check:SetTexCoord(0,1,0,1)
|
|
check:SetBlendMode("BLEND")
|
|
end
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:UpdateCheck()
|
|
|
|
if self.checked then
|
|
self.check:Show()
|
|
else
|
|
self.check:Hide()
|
|
end
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:ToggleChecked()
|
|
self.checked = not self.checked
|
|
|
|
self:UpdateCheck()
|
|
|
|
if self.setFunc then
|
|
self.setFunc(getArgs(self,"setArg",1,self.checked))
|
|
end
|
|
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
else
|
|
self:Refresh()
|
|
end
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:SetChecked(value)
|
|
self.checked = value
|
|
self:UpdateCheck()
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:GetChecked()
|
|
return self.checked
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.highlight:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetChecked(false)
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("get",nil)
|
|
self:SetFunc("set",nil)
|
|
self.isRadio = nil
|
|
end
|
|
|
|
function WaterfallCheckBox.prototype:Refresh()
|
|
if self.getFunc then
|
|
local checked = self.getFunc(getArgs(self,"getArg",1))
|
|
self:SetChecked(checked)
|
|
end
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.text:SetTextColor(0.5,0.5,0.5)
|
|
SetDesaturation(self.check, true)
|
|
else
|
|
self.text:SetTextColor(1,1,1)
|
|
SetDesaturation(self.check, false)
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
self:UpdateTexture()
|
|
end
|
|
|
|
-----------------
|
|
-- DragLink Class --
|
|
-----------------
|
|
|
|
-- Provides an icon and description of a link based on on its linkInfo.itemType, itemId, itemInfo
|
|
-- Dragging onto the linkIcon sets linkInfo.itemType, linkInfo.itemId, linkInfo.itemInfo
|
|
-- If linkInfo.itemType == "spell" then linkInfo.spellName, linkInfo.spellRank, linkInfo.spellClass (current player class) are also set
|
|
-- Dragging between two DragLink objects will swap their contents
|
|
|
|
function Waterfall:GetDraggingObject()
|
|
return Waterfall.fromObject
|
|
end
|
|
|
|
|
|
function Waterfall:SetDraggingObject(fromObject)
|
|
Waterfall.fromObject = fromObject
|
|
end
|
|
|
|
local function DragLinkOnDragStart()
|
|
local fromObject = this.obj
|
|
Waterfall:SetDraggingObject(fromObject)
|
|
end
|
|
|
|
local function DragLinkOnReceiveDrag()
|
|
local self = this.obj
|
|
local toObject = this.obj
|
|
local fromObject = Waterfall:GetDraggingObject()
|
|
local refreshNeeded = false
|
|
if (fromObject and fromObject ~= toObject) then
|
|
--DEFAULT_CHAT_FRAME:AddMessage("DragLinkOnReceiveDrag toObject " .. tostring(toObject))
|
|
fromObject.itemType, toObject.itemType = toObject.itemType, fromObject.itemType
|
|
fromObject.itemId, toObject.itemId = toObject.itemId, fromObject.itemId
|
|
fromObject.itemInfo, toObject.itemInfo = toObject.itemInfo, fromObject.itemInfo
|
|
fromObject.spellName, toObject.spellName = toObject.spellName, fromObject.spellName
|
|
fromObject.spellRank, toObject.spellRank = toObject.spellRank, fromObject.spellRank
|
|
fromObject.spellClass, toObject.spellClass = toObject.spellClass, fromObject.spellClass
|
|
if fromObject.causesRefresh or fromObject.fullRefresh then
|
|
fromObject.parent:Refresh(fromObject.fullRefresh)
|
|
end
|
|
refreshNeeded = true
|
|
else
|
|
local itemType, itemId, itemInfo = GetCursorInfo()
|
|
--DEFAULT_CHAT_FRAME:AddMessage("DragLinkOnReceiveDrag itemType " .. tostring(itemType) .. " itemId " .. tostring(itemId) .. " itemInfo " .. tostring(itemInfo))
|
|
if (itemType == "item" or itemType == "spell" or itemType == "macro") then
|
|
local linkInfo = self.linkInfo
|
|
linkInfo.itemType = itemType
|
|
linkInfo.itemId = itemId
|
|
linkInfo.itemInfo = itemInfo
|
|
if (itemType == "spell") then
|
|
local spellName, spellRank = GetSpellName(itemId, itemInfo)
|
|
linkInfo.spellName = spellName
|
|
linkInfo.spellRank = spellRank
|
|
linkInfo.spellClass = WaterfallDragLink.CLASS
|
|
else
|
|
linkInfo.spellName = nil
|
|
linkInfo.spellRank = nil
|
|
linkInfo.spellClass = nil
|
|
end
|
|
--DEFAULT_CHAT_FRAME:AddMessage("DragLinkOnReceiveDrag itemType " .. tostring(itemType) .. " itemId " .. tostring(itemId) .. " itemInfo " .. tostring(itemInfo))
|
|
--DEFAULT_CHAT_FRAME:AddMessage("DragLinkOnReceiveDrag self.setFunc " .. tostring(self.setFunc) .. " self.disabled " .. tostring(self.disabled))
|
|
if (self.setFunc and not self.disabled) then
|
|
self.setFunc(getArgs(self,"setArg",1,linkInfo))
|
|
end
|
|
refreshNeeded = true
|
|
ClearCursor()
|
|
end
|
|
end
|
|
|
|
if (refreshNeeded) then
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
else
|
|
self:Refresh()
|
|
end
|
|
end
|
|
Waterfall:SetDraggingObject(nil)
|
|
end
|
|
|
|
local function DragLinkOnClick()
|
|
DragLinkOnReceiveDrag() --??
|
|
end
|
|
|
|
local function DragLinkOnEnter()
|
|
local self = this.obj
|
|
local linkInfo = self.linkInfo
|
|
if (linkInfo) then
|
|
if (linkInfo.itemType == "item") then
|
|
GameTooltip:SetOwner(this, "ANCHOR_PRESERVE")
|
|
if (linkInfo.itemId) then
|
|
GameTooltip:SetHyperlink("item:" .. linkInfo.itemId .. ":0:0:0:0:0:0:0")
|
|
else
|
|
GameTooltip:SetHyperlink(tostring(linkInfo.itemInfo))
|
|
end
|
|
elseif (linkInfo.itemType == "spell") then
|
|
if (linkInfo.spellName) then
|
|
-- Cannot set this without preserving spell book & spell id. Even then may be from different class. So lame. Awaiting a Blizzard API that doesnt suck.
|
|
-- GameTooltip:SetSpell(linkInfo.spellId, linkInfo.spellTab)
|
|
GameTooltip:SetOwner(this, "ANCHOR_PRESERVE")
|
|
GameTooltip:AddLine(linkInfo.spellName, 1, 1, 1)
|
|
local name, rank, icon, cost, isFunnel, powerType, castTime, minRange, maxRange = GetSpellInfo(linkInfo.spellName)
|
|
if (name) then
|
|
if (powerType == 0) then
|
|
cost = tostring(cost) .. " " .. MANA
|
|
elseif (powerType == 1) then
|
|
cost = tostring(cost) .. " " .. RAGE
|
|
elseif (powerType == 2) then
|
|
cost = tostring(cost) .. " " .. FOCUS
|
|
elseif (powerType == 3) then
|
|
cost = tostring(cost) .. " " .. ENERGY
|
|
elseif (powerType == 4) then
|
|
cost = tostring(cost) .. " " .. HAPPINESS
|
|
end
|
|
local range = ""
|
|
if (maxRange) then
|
|
range = SPELL_RANGE:format(maxRange)
|
|
end
|
|
GameTooltip:AddDoubleLine(cost, range, 1, 1, 1, 1, 1, 1)
|
|
if (castTime and castTime > 0) then
|
|
GameTooltip:AddLine(SPELL_CAST_TIME_SEC:format(castTime), 1, 1, 1)
|
|
else
|
|
GameTooltip:AddLine(SPELL_CAST_TIME_INSTANT, 1, 1, 1)
|
|
end
|
|
if (rank) then
|
|
GameTooltip:AddLine(tostring(rank))
|
|
end
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
elseif (linkInfo.itemType == "macro") then
|
|
if (linkInfo.itemId) then
|
|
local name, icon, body = GetMacroInfo(linkInfo.itemId)
|
|
if (name) then
|
|
GameTooltip:SetOwner(this, "ANCHOR_PRESERVE")
|
|
GameTooltip:AddLine(tostring(name), 0.2, 0.8, 0.8, 1)
|
|
GameTooltip:AddTexture(icon)
|
|
GameTooltip:AddLine(tostring(body), 1, 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function DragLinkOnLeave()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function DragLinkGetTexture(self)
|
|
local linkInfo = self.linkInfo
|
|
local texture
|
|
if (linkInfo) then
|
|
if (linkInfo.itemType == "item") then
|
|
if (linkInfo.itemId and tonumber(linkInfo.itemId)) then
|
|
_,_,_,_,_,_,_,_,_,texture = GetItemInfo(tonumber(linkInfo.itemId))
|
|
if (texture) then
|
|
return texture
|
|
end
|
|
end
|
|
elseif (linkInfo.itemType == "spell") then
|
|
if (linkInfo.spellName) then
|
|
_, _, texture = GetSpellInfo(linkInfo.spellName)
|
|
if (texture) then
|
|
return texture
|
|
end
|
|
end
|
|
elseif (linkInfo.itemType == "macro") then
|
|
if (linkInfo.itemId) then
|
|
_, texture = GetMacroInfo(linkInfo.itemId)
|
|
if (texture) then
|
|
return texture
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return "Interface\\Icons\\INV_Misc_Gift_01"
|
|
end
|
|
|
|
WaterfallDragLink.defaultIconSize = 36
|
|
_, WaterfallDragLink.CLASS = UnitClass("player") -- Use the capitalized english class name
|
|
|
|
function WaterfallDragLink.prototype:init()
|
|
WaterfallDragLink.super.prototype.init(self, "Button")
|
|
|
|
local frame = self.frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
self.text = text
|
|
|
|
frame:SetScript("OnDragStart", DragLinkOnDragStart)
|
|
frame:SetScript("OnReceiveDrag", DragLinkOnReceiveDrag)
|
|
frame:SetScript("OnClick", DragLinkOnClick)
|
|
frame:SetScript("OnEnter", DragLinkOnEnter)
|
|
frame:SetScript("OnLeave", DragLinkOnLeave)
|
|
|
|
frame:EnableMouse()
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
|
|
local linkIcon = frame:CreateTexture(nil, "OVERLAY")
|
|
linkIcon:SetWidth(self.iconWidth or WaterfallDragLink.defaultIconSize)
|
|
linkIcon:SetHeight(self.iconHeight or WaterfallDragLink.defaultIconSize)
|
|
linkIcon:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
linkIcon:SetTexture(DragLinkGetTexture(self))
|
|
linkIcon:SetTexCoord(0,1,0,1)
|
|
linkIcon:Show()
|
|
self.linkIcon = linkIcon
|
|
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
|
|
frame:SetHeight(self.iconHeight or WaterfallDragLink.defaultIconSize + 4)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
|
|
text:SetHeight(self.iconHeight or WaterfallDragLink.defaultIconSize + 4)
|
|
text:SetPoint("LEFT",check,"RIGHT",0,0)
|
|
end
|
|
|
|
function WaterfallDragLink.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
end
|
|
|
|
function WaterfallDragLink.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled", nil)
|
|
self.linkIcon:Hide()
|
|
end
|
|
|
|
function WaterfallDragLink.prototype:Refresh()
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.frame:Disable()
|
|
else
|
|
self.frame:Enable()
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
if (not self.linkIcon) then
|
|
local linkIcon = self.frame:CreateTexture(nil, "OVERLAY")
|
|
linkIcon:SetWidth(self.iconWidth or WaterfallDragLink.defaultIconSize)
|
|
linkIcon:SetHeight(self.iconHeight or WaterfallDragLink.defaultIconSize)
|
|
linkIcon:SetPoint("TOP", self.frame, "TOP", 0, 0)
|
|
linkIcon:SetTexCoord(0,1,0,1)
|
|
linkIcon:Show()
|
|
self.linkIcon = linkIcon
|
|
end
|
|
if self.getFunc then
|
|
self.linkInfo = self.getFunc(getArgs(self,"getArg",1))
|
|
else
|
|
self:assert(self.linkInfo, "wth?")
|
|
end
|
|
self.linkIcon:SetTexture(DragLinkGetTexture(self))
|
|
self.linkIcon:Show()
|
|
if (self.linkInfo.itemId) then
|
|
self:SetText((self.linkInfo.itemInfo or "") .. " (" .. tostring(self.linkInfo.itemId) .. ")")
|
|
else
|
|
self:SetText("")
|
|
end
|
|
--DEFAULT_CHAT_FRAME:AddMessage("WaterfallDragLink.prototype:Refresh texture " .. tostring(DragLinkGetTexture(self)) .. " self.linkInfo.itemId " .. tostring(self.linkInfo.itemId) .. " self.linkInfo.itemInfo " .. tostring(self.linkInfo.itemInfo))
|
|
end
|
|
|
|
-----------------
|
|
-- Button Class --
|
|
-----------------
|
|
local function buttonConfirmFunc(self, refresh, full, func, ...)
|
|
func(unpack(arg))
|
|
|
|
if refresh or full then
|
|
self.parent:Refresh(full)
|
|
end
|
|
end
|
|
|
|
local function Button_OnClick()
|
|
local self = this.obj
|
|
local func = self.execFunc
|
|
local confirm = this.obj.confirm
|
|
if func then
|
|
if confirm then
|
|
if type(confirm) == "string" then
|
|
confirmPopup(confirm,buttonConfirmFunc,self,self.causesRefresh,self.fullRefresh,func,getArgs(this.obj,"execArg",1))
|
|
else
|
|
confirmPopup((ARE_YOU_SURE):format(this.obj.frame:GetText()),buttonConfirmFunc,
|
|
self,self.causesRefresh,self.fullRefresh,func,getArgs(this.obj,"execArg",1))
|
|
end
|
|
else
|
|
func(getArgs(this.obj,"execArg",1))
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function Control_OnEnter()
|
|
if this.obj.link then
|
|
GameTooltip:SetOwner(this, "ANCHOR_PRESERVE")
|
|
GameTooltip:SetHyperlink(this.obj.link)
|
|
else
|
|
showGameTooltip(this.obj)
|
|
end
|
|
end
|
|
|
|
local function Control_OnLeave()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
function WaterfallButton.prototype:init()
|
|
WaterfallButton.super.prototype.init(self,"Button","UIPanelButtonTemplate")
|
|
local frame = self.frame
|
|
--local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
local text = frame:GetFontString()
|
|
text:SetPoint("LEFT",frame,"LEFT",7,0)
|
|
text:SetPoint("RIGHT",frame,"RIGHT",-7,0)
|
|
|
|
frame:SetScript("OnClick",Button_OnClick)
|
|
frame:SetScript("OnEnter",Control_OnEnter)
|
|
frame:SetScript("OnLeave",Control_OnLeave)
|
|
|
|
frame:EnableMouse()
|
|
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
|
|
end
|
|
|
|
function WaterfallButton.prototype:SetText(text)
|
|
self.frame:SetText(text)
|
|
end
|
|
|
|
function WaterfallButton.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("exec",nil)
|
|
end
|
|
|
|
function WaterfallButton.prototype:Refresh()
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.frame:Disable()
|
|
else
|
|
self.frame:Enable()
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
-----------------
|
|
-- Keybinding Class --
|
|
-----------------
|
|
|
|
local function Keybinding_OnClick( button)
|
|
local self = this.obj
|
|
|
|
if button == "LeftButton" or button == "RightButton" then
|
|
if self.waitingForKey then
|
|
this:EnableKeyboard(false)
|
|
self.msgframe:Hide()
|
|
this:UnlockHighlight()
|
|
self.waitingForKey = nil
|
|
else
|
|
this:EnableKeyboard(true)
|
|
self.parent:ClearFocus()
|
|
self.msgframe:Show()
|
|
this:LockHighlight()
|
|
self.waitingForKey = true
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function Keybinding_OnKeyDown( key)
|
|
local self = this.obj
|
|
if self.waitingForKey then
|
|
local keyPressed = key;
|
|
if keyPressed == "ESCAPE" then
|
|
keyPressed = ""
|
|
else
|
|
if ( keyPressed == "BUTTON1" or keyPressed == "BUTTON2" ) then
|
|
return;
|
|
end
|
|
if ( keyPressed == "UNKNOWN" ) then
|
|
return;
|
|
end
|
|
if ( keyPressed == "SHIFT" or keyPressed == "CTRL" or keyPressed == "ALT") then
|
|
return;
|
|
end
|
|
if ( keyPressed == "LSHIFT" or keyPressed == "LCTRL" or keyPressed == "LALT") then
|
|
return;
|
|
end
|
|
if ( keyPressed == "RSHIFT" or keyPressed == "RCTRL" or keyPressed == "RALT") then
|
|
return;
|
|
end
|
|
if ( IsShiftKeyDown() ) then
|
|
keyPressed = "SHIFT-"..keyPressed;
|
|
end
|
|
if ( IsControlKeyDown() ) then
|
|
keyPressed = "CTRL-"..keyPressed;
|
|
end
|
|
if ( IsAltKeyDown() ) then
|
|
keyPressed = "ALT-"..keyPressed;
|
|
end
|
|
end
|
|
|
|
if self.setFunc and not self.disabled then
|
|
local validated = true
|
|
if keyPressed == "" then
|
|
keyPressed = nil
|
|
else
|
|
if self.keybindingOnly and not self.keybindingOnly[keyPressed] then
|
|
validated = false
|
|
end
|
|
if self.keybindingExcept and self.keybindingExcept[keyPressed] then
|
|
validated = false
|
|
end
|
|
end
|
|
if validated then
|
|
self.setFunc(getArgs(self,"setArg",1,keyPressed))
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
self:Refresh()
|
|
|
|
this:EnableKeyboard(false)
|
|
self.msgframe:Hide()
|
|
this:UnlockHighlight()
|
|
self.waitingForKey = nil
|
|
end
|
|
end
|
|
|
|
local function Keybinding_OnMouseDown( button)
|
|
if ( button == "LeftButton" or button == "RightButton" ) then
|
|
return
|
|
elseif ( button == "MiddleButton" ) then
|
|
button = "BUTTON3";
|
|
elseif ( button == "Button4" ) then
|
|
button = "BUTTON4"
|
|
elseif ( button == "Button5" ) then
|
|
button = "BUTTON5"
|
|
end
|
|
Keybinding_OnKeyDown( button)
|
|
end
|
|
|
|
local function keybindingMsgFixWidth()
|
|
this:SetWidth(this.msg:GetWidth()+10)
|
|
this:SetScript("OnUpdate",nil)
|
|
end
|
|
|
|
function WaterfallKeybinding.prototype:init()
|
|
WaterfallKeybinding.super.prototype.init(self,"Button","UIPanelButtonTemplate")
|
|
local frame = self.frame
|
|
--local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
local text = frame:GetFontString()
|
|
text:SetPoint("LEFT",frame,"LEFT",7,0)
|
|
text:SetPoint("RIGHT",frame,"RIGHT",-7,0)
|
|
|
|
frame:SetScript("OnClick",Keybinding_OnClick)
|
|
frame:SetScript("OnKeyDown",Keybinding_OnKeyDown)
|
|
frame:SetScript("OnEnter",Control_OnEnter)
|
|
frame:SetScript("OnLeave",Control_OnLeave)
|
|
frame:SetScript("OnMouseDown",Keybinding_OnMouseDown)
|
|
frame:RegisterForClicks("AnyDown")
|
|
frame:EnableMouse()
|
|
|
|
frame:SetHeight(24)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
|
|
local msgframe = CreateFrame("Frame",nil,UIParent)
|
|
msgframe:SetHeight(30)
|
|
msgframe:SetBackdrop(ControlBackdrop)
|
|
msgframe:SetBackdropColor(0,0,0)
|
|
msgframe:SetFrameStrata("DIALOG")
|
|
msgframe:SetFrameLevel(20)
|
|
self.msgframe = msgframe
|
|
local msg = msgframe:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel")
|
|
msgframe.msg = msg
|
|
msg:SetPoint("TOPLEFT",msgframe,"TOPLEFT",5,-5)
|
|
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
|
|
msgframe:SetPoint("TOP",frame,"BOTTOM",0,-2)
|
|
msgframe:Hide()
|
|
end
|
|
|
|
function WaterfallKeybinding.prototype:SetText(text)
|
|
self.frame:SetText(text)
|
|
end
|
|
|
|
function WaterfallKeybinding.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("exec",nil)
|
|
self.waitingForKey = nil
|
|
self.msgframe:Hide()
|
|
end
|
|
|
|
function WaterfallKeybinding.prototype:Refresh()
|
|
if self.getFunc then
|
|
local text = self.getFunc(getArgs(self,"getArg",1))
|
|
self:SetText(text or "")
|
|
end
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.frame:Disable()
|
|
else
|
|
self.frame:Enable()
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
-----------------
|
|
-- Slider Class --
|
|
-----------------
|
|
|
|
local function Slider_OnValueChanged()
|
|
local self = this.obj
|
|
if not this.setup then
|
|
local func = self.setFunc
|
|
local newvalue
|
|
newvalue = this:GetValue()
|
|
if newvalue ~= self.value and not self.disabled then
|
|
if self.bigStep > 0 then
|
|
self.value = math.floor((newvalue - self.min) / self.bigStep + 0.5) * self.bigStep + self.min
|
|
else
|
|
self.value = newvalue
|
|
end
|
|
if func and not self.isInit then
|
|
if (self.finalSetOnly) then
|
|
self.finalSetValue = self.value
|
|
else
|
|
func(getArgs(this.obj,"setArg",1,self.value))
|
|
end
|
|
end
|
|
end
|
|
if self.value then
|
|
this.obj.valuetext:SetText(math.floor(self.value*10)/10)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function Slider_OnMouseUp()
|
|
local self = this.obj
|
|
if (self.finalSetValue) then
|
|
local func = self.setFunc
|
|
if func then
|
|
func(getArgs(this.obj,"setArg",1,self.finalSetValue))
|
|
end
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
|
|
local SliderBackdrop = {
|
|
bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
|
|
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
|
|
tile = true, tileSize = 8, edgeSize = 8,
|
|
insets = { left = 3, right = 3, top = 6, bottom = 6 }
|
|
}
|
|
|
|
function WaterfallSlider.prototype:init()
|
|
WaterfallSlider.super.prototype.init(self,"Frame")
|
|
local frame = self.frame
|
|
|
|
self.slider = CreateFrame("Slider",nil,frame)
|
|
local slider = self.slider
|
|
slider:SetScript("OnEnter",Control_OnEnter)
|
|
slider:SetScript("OnLeave",Control_OnLeave)
|
|
slider:SetScript("OnMouseUp", Slider_OnMouseUp)
|
|
slider.obj = self
|
|
slider:SetOrientation("HORIZONTAL")
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
slider:SetHeight(17)
|
|
slider:SetHitRectInsets(0,0,-10,-10)
|
|
slider:SetBackdrop(SliderBackdrop)
|
|
self.text = slider:CreateFontString(nil,"ARTWORK","GameFontNormalSmall")
|
|
self.text:SetPoint("TOP",frame,"TOP",0,-2)
|
|
|
|
self.lowtext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
|
|
self.lowtext:SetPoint("TOPLEFT",slider,"BOTTOMLEFT",2,3)
|
|
|
|
self.hightext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
|
|
self.hightext:SetPoint("TOPRIGHT",slider,"BOTTOMRIGHT",-2,3)
|
|
|
|
self.valuetext = slider:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
|
|
self.valuetext:SetPoint("TOP",slider,"BOTTOM",0,3)
|
|
|
|
|
|
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
|
|
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
frame:SetHeight(40)
|
|
slider:SetPoint("TOP",self.text,"BOTTOM",0,0)
|
|
slider:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
slider:SetPoint("RIGHT",frame,"RIGHT",0,0)
|
|
|
|
if self.getFunc then
|
|
self.isInit = true
|
|
self.value = self.getFunc(getArgs(self,"getArg",1))
|
|
self.isInit = nil
|
|
end
|
|
slider:SetValue(self.value or 0)
|
|
slider:SetScript("OnValueChanged",Slider_OnValueChanged)
|
|
|
|
end
|
|
|
|
function WaterfallSlider.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("get",nil)
|
|
self:SetFunc("set",nil)
|
|
self.min = nil
|
|
self.max = nil
|
|
self.step = nil
|
|
self.value = nil
|
|
self.parent = nil
|
|
self.disabled = nil
|
|
end
|
|
|
|
function WaterfallSlider.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
end
|
|
|
|
function WaterfallSlider.prototype:Refresh()
|
|
local frame = self.slider
|
|
frame.setup = true
|
|
frame:SetMinMaxValues(self.min or 0,self.max or 100)
|
|
self.lowtext:SetText(self.min or 0)
|
|
self.hightext:SetText(self.max or 100)
|
|
frame:SetValueStep(self.step or 1)
|
|
frame.setup = nil
|
|
if self.getFunc then
|
|
local newvalue
|
|
newvalue = self.getFunc(getArgs(self,"getArg",1))
|
|
if newvalue ~= self.value then
|
|
self.isInit = true
|
|
frame:SetValue(newvalue)
|
|
self.isInit = nil
|
|
end
|
|
end
|
|
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.slider:EnableMouse(false)
|
|
self.text:SetTextColor(.5,.5,.5)
|
|
self.hightext:SetTextColor(.5,.5,.5)
|
|
self.lowtext:SetTextColor(.5,.5,.5)
|
|
self.valuetext:SetTextColor(.5,.5,.5)
|
|
else
|
|
self.slider:EnableMouse(true)
|
|
self.text:SetTextColor(1,1,1)
|
|
self.hightext:SetTextColor(1,1,1)
|
|
self.lowtext:SetTextColor(1,1,1)
|
|
self.valuetext:SetTextColor(1,1,1)
|
|
end
|
|
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
-------------------
|
|
-- TextBox Class --
|
|
-------------------
|
|
|
|
local function TextBox_OnEscapePressed()
|
|
this:ClearFocus()
|
|
end
|
|
|
|
local function TextBox_OnEnterPressed()
|
|
local self = this.obj
|
|
local value = this:GetText()
|
|
if self.toNumber then
|
|
value = tonumber(value)
|
|
--TODO: same message as a failed validation
|
|
if not value then return end
|
|
end
|
|
if self.setFunc and not self.disabled then
|
|
local validated = true
|
|
if type(self.validateFunc) == "function" then
|
|
validated = self.validateFunc(getArgs(self,"validateArg",1,value))
|
|
if validated and self.validateModifies then
|
|
value = validated
|
|
local setOnTextChanged = self.setOnTextChanged
|
|
self.setOnTextChanged = nil
|
|
this:SetText(value)
|
|
self.setOnTextChanged = setOnTextChanged
|
|
end
|
|
elseif type(self.validateFunc) == "table" then
|
|
validated = self.validateFunc[value]
|
|
end
|
|
--TODO: message for failed validation
|
|
if validated then
|
|
if self.parseList then
|
|
self.setFunc(getArgs(self,"setArg",1,parseList(value)))
|
|
else
|
|
self.setFunc(getArgs(self,"setArg",1,value))
|
|
end
|
|
end
|
|
if self.getFunc == false then
|
|
self:SetText("")
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function TextBox_OnTextChanged()
|
|
local self = this.obj
|
|
local value = this:GetText()
|
|
if self.setOnTextChanged then
|
|
TextBox_OnEnterPressed()
|
|
end
|
|
if self.changedFunc and not self.disabled then
|
|
if self.parseList then
|
|
self.changedFunc(getArgs(self,"changedArg",1,parseList(value)))
|
|
else
|
|
self.changedFunc(getArgs(self,"changedArg",1,value))
|
|
end
|
|
end
|
|
end
|
|
|
|
function WaterfallTextBox.prototype:init()
|
|
WaterfallTextBox.super.prototype.init(self,"EditBox")
|
|
local frame = self.frame
|
|
--local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
--self.text = text
|
|
frame:SetScript("OnEnter",Control_OnEnter)
|
|
frame:SetScript("OnLeave",Control_OnLeave)
|
|
frame:SetFontObject(ChatFontNormal)
|
|
frame:SetScript("OnEscapePressed",TextBox_OnEscapePressed)
|
|
frame:SetScript("OnEnterPressed",TextBox_OnEnterPressed)
|
|
frame:SetScript("OnTextChanged",TextBox_OnTextChanged)
|
|
frame:SetTextInsets(5,5,3,3)
|
|
frame:SetMaxLetters(256)
|
|
frame:SetAutoFocus(false)
|
|
frame:SetHeight(26)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
frame:SetBackdrop(ControlBackdrop)
|
|
frame:SetBackdropColor(0,0,0)
|
|
end
|
|
|
|
local function UglyScrollLeft()
|
|
this:HighlightText(0,1);
|
|
this:Insert(" "..strsub(this:GetText(),1,1));
|
|
this:HighlightText(0,1);
|
|
this:Insert("");
|
|
this:SetScript("OnUpdate", nil);
|
|
end
|
|
|
|
function WaterfallTextBox.prototype:SetText(text)
|
|
self.frame:SetText(text)
|
|
self.frame:SetScript("OnUpdate", UglyScrollLeft);
|
|
end
|
|
|
|
function WaterfallTextBox.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self.setOnTextChanged = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("get",nil)
|
|
self:SetFunc("set",nil)
|
|
self:SetFunc("changed",nil)
|
|
end
|
|
|
|
function WaterfallTextBox.prototype:Refresh()
|
|
if self.getFunc then
|
|
local text = self.getFunc(getArgs(self,"getArg",1))
|
|
if text then
|
|
self:SetText(text)
|
|
end
|
|
end
|
|
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.frame:EnableMouse(false)
|
|
self.frame:ClearFocus()
|
|
self.frame:SetTextColor(0.5,0.5,0.5)
|
|
else
|
|
self.frame:EnableMouse(true)
|
|
self.frame:SetTextColor(1,1,1)
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
|
|
--------------------
|
|
-- DropDown Class --
|
|
--------------------
|
|
|
|
local function Dropdown_OnEnterPressed()
|
|
local self = this.obj
|
|
if self.setFunc and not self.disabled then
|
|
local ret
|
|
if self.strict and this.value then
|
|
ret = this.value
|
|
else
|
|
ret = this:GetText()
|
|
end
|
|
if self.parseList then
|
|
self.setFunc(getArgs(self,"setArg",1,parseList(ret)))
|
|
else
|
|
self.setFunc(getArgs(self,"setArg",1,ret))
|
|
end
|
|
if self.causesRefresh or self.fullRefresh then
|
|
self.parent:Refresh(self.fullRefresh)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function Dropdown_TogglePullout()
|
|
local self = this.obj
|
|
if self.open then
|
|
self.open = nil
|
|
self.pullout:Hide()
|
|
else
|
|
self.open = true
|
|
self:BuildPullout()
|
|
if self.lines[1] and self.lines[1]:IsShown() then
|
|
self.pullout:Show()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function Dropdown_OnHide()
|
|
this.obj.pullout:Hide()
|
|
end
|
|
|
|
local function Dropdown_LineClicked()
|
|
local self = this.obj
|
|
self.open = false
|
|
self.pullout:Hide()
|
|
self.editbox:SetText(this.text:GetText())
|
|
self.editbox.value = this.value
|
|
Dropdown_OnEnterPressed(self.editbox)
|
|
end
|
|
|
|
local function Dropdown_LineEnter()
|
|
this.highlight:Show()
|
|
end
|
|
|
|
local function Dropdown_LineLeave()
|
|
this.highlight:Hide()
|
|
end
|
|
|
|
function WaterfallDropdown.prototype:init()
|
|
WaterfallDropdown.super.prototype.init(self,"Frame")
|
|
local frame = self.frame
|
|
frame.obj = self
|
|
--local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
--self.text = text
|
|
local editbox = CreateFrame("EditBox",nil,frame)
|
|
self.editbox = editbox
|
|
editbox.obj = self
|
|
editbox:SetFontObject(ChatFontNormal)
|
|
editbox:SetScript("OnEscapePressed",TextBox_OnEscapePressed)
|
|
editbox:SetScript("OnEnterPressed",Dropdown_OnEnterPressed)
|
|
frame:SetScript("OnEnter",Control_OnEnter)
|
|
frame:SetScript("OnLeave",Control_OnLeave)
|
|
editbox:SetScript("OnEnter",Control_OnEnter)
|
|
editbox:SetScript("OnLeave",Control_OnLeave)
|
|
editbox:SetTextInsets(5,5,3,3)
|
|
editbox:SetMaxLetters(256)
|
|
editbox:SetAutoFocus(false)
|
|
editbox:SetBackdrop(ControlBackdrop)
|
|
editbox:SetBackdropColor(0,0,0)
|
|
|
|
editbox:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
|
editbox:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-20,0)
|
|
local button = CreateFrame("Button",nil,frame)
|
|
self.button = button
|
|
button.obj = self
|
|
button:SetWidth(24)
|
|
button:SetHeight(24)
|
|
button:SetScript("OnEnter",Control_OnEnter)
|
|
button:SetScript("OnLeave",Control_OnLeave)
|
|
button:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up")
|
|
button:GetNormalTexture():SetTexCoord(.09,.91,.09,.91)
|
|
button:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down")
|
|
button:GetPushedTexture():SetTexCoord(.09,.91,.09,.91)
|
|
button:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled")
|
|
button:GetDisabledTexture():SetTexCoord(.09,.91,.09,.91)
|
|
button:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD")
|
|
button:GetHighlightTexture():SetTexCoord(.09,.91,.09,.91)
|
|
button:SetPoint("RIGHT",frame,"RIGHT",0,0)
|
|
button:SetScript("OnClick",Dropdown_TogglePullout)
|
|
frame:SetHeight(26)
|
|
frame:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
frame:SetScript("OnHide",Dropdown_OnHide)
|
|
local pullout = CreateFrame("Frame",nil,UIParent)
|
|
self.pullout = pullout
|
|
frame:EnableMouse()
|
|
pullout:SetBackdrop(ControlBackdrop)
|
|
pullout:SetBackdropColor(0,0,0)
|
|
pullout:SetFrameStrata("DIALOG")
|
|
pullout:SetFrameLevel(20)
|
|
pullout:SetPoint("TOPLEFT",frame,"BOTTOMLEFT",0,0)
|
|
pullout:SetPoint("TOPRIGHT",frame,"BOTTOMRIGHT",-24,0)
|
|
pullout:SetClampedToScreen(true)
|
|
pullout:Hide()
|
|
|
|
self.lines = {}
|
|
end
|
|
|
|
function WaterfallDropdown.prototype:SetText(text)
|
|
self.editbox:SetText(text)
|
|
end
|
|
|
|
function WaterfallDropdown.prototype:CleanUp()
|
|
self.frame:ClearAllPoints()
|
|
self.frame:Hide()
|
|
self.width = nil
|
|
self.height = nil
|
|
self.noNewLine = nil
|
|
self.causesRefresh = nil
|
|
self.fullRefresh = nil
|
|
self.treeRefresh = nil
|
|
self:SetText("")
|
|
self:SetFunc("disabled",nil)
|
|
self:SetFunc("get",nil)
|
|
self:SetFunc("set",nil)
|
|
self.editbox.value = nil
|
|
self.columns = nil
|
|
end
|
|
|
|
function WaterfallDropdown.prototype:Refresh()
|
|
local list = self.list
|
|
if self.getFunc then
|
|
local newval = self.getFunc(getArgs(self,"getArg",1))
|
|
if newval then
|
|
if self.strict then
|
|
if type(list) == "table" then
|
|
local value
|
|
for k, text in pairs(list) do
|
|
if type(k) == "string" then
|
|
value = k
|
|
else
|
|
value = text
|
|
end
|
|
if newval == value then
|
|
self:SetText(text)
|
|
self.editbox.value = value
|
|
break
|
|
end
|
|
end
|
|
elseif type(list) == "function" then
|
|
for i, text, value in list() do
|
|
if newval == value then
|
|
self:SetText(text)
|
|
self.editbox.value = value
|
|
break
|
|
end
|
|
end
|
|
end
|
|
else
|
|
self.editbox:SetText(newval)
|
|
self.editbox.value = newval
|
|
end
|
|
else
|
|
self.editbox:SetText("")
|
|
self.editbox.value = newval
|
|
end
|
|
end
|
|
|
|
if self.disabledFunc then
|
|
self.disabled = self.disabledFunc(getArgs(self,"disabledArg",1))
|
|
if self.inverseDisabled then
|
|
self.disabled = not self.disabled
|
|
end
|
|
end
|
|
if self.disabled then
|
|
self.editbox:EnableMouse(false)
|
|
self.editbox:ClearFocus()
|
|
self.editbox:SetTextColor(0.5,0.5,0.5)
|
|
self.button:Disable()
|
|
else
|
|
self.button:Enable()
|
|
if self.strict then
|
|
self.editbox:EnableMouse(false)
|
|
self.editbox:ClearFocus()
|
|
self.editbox:SetTextColor(1,1,1)
|
|
else
|
|
self.editbox:EnableMouse(true)
|
|
self.editbox:SetTextColor(1,1,1)
|
|
end
|
|
end
|
|
if self.width then
|
|
self:SetWidth(self.width)
|
|
else
|
|
self:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
end
|
|
|
|
local function div(a,b)
|
|
return a - math.floor(a/b)*b
|
|
end
|
|
|
|
local ddsort = {}
|
|
function WaterfallDropdown.prototype:BuildPullout()
|
|
local list = self.list
|
|
local lines = self.lines
|
|
local totalheight = 10
|
|
self:ClearPullout()
|
|
if type(list) == "table" then
|
|
for k, v in pairs(list) do
|
|
tinsert(ddsort,k)
|
|
end
|
|
table.sort(ddsort)
|
|
local columns = tonumber(self.columns)
|
|
local columnHeight, columnWidth
|
|
local columnCount = 0
|
|
self.pullout:ClearAllPoints()
|
|
if (columns) then
|
|
columnHeight = math.floor((table.getn(ddsort)) / columns) + 2
|
|
columnWidth = self.pullout:GetWidth()
|
|
self.pullout:SetPoint("TOPLEFT",self.frame,"BOTTOMRIGHT", -1 * DEFAULT_CONTROL_WIDTH * columns - 24,0)
|
|
self.pullout:SetPoint("TOPRIGHT",self.frame,"BOTTOMRIGHT",-24,0)
|
|
else
|
|
self.pullout:SetPoint("TOPLEFT",self.frame,"BOTTOMRIGHT", -1 * DEFAULT_CONTROL_WIDTH - 24,0)
|
|
self.pullout:SetPoint("TOPRIGHT",self.frame,"BOTTOMRIGHT",-24,0)
|
|
columnHeight = table.getn(ddsort) + 1
|
|
end
|
|
for i, value in pairs(ddsort) do
|
|
local text = list[value]
|
|
if (div((i - 1), (columnHeight - 1)) == 0) then
|
|
columnCount = columnCount + 1
|
|
end
|
|
if (lines[i]) then
|
|
self:UpdateLine(lines[i], math.mod(i-1, (columnHeight-1)), columnCount)
|
|
else
|
|
lines[i] = self:CreateLine(math.mod(i-1, (columnHeight-1)), columnCount)
|
|
end
|
|
if i == 1 then
|
|
lines[i]:SetPoint("TOP",self.pullout,"TOP",0,-5)
|
|
else
|
|
if (columns and (div((i - 1), columnHeight) == 0)) then
|
|
lines[i]:SetPoint("TOP",self.pullout,"TOP",0,-5)
|
|
else
|
|
lines[i]:SetPoint("TOP",lines[i-1],"BOTTOM",0,0)
|
|
end
|
|
end
|
|
lines[i].text:SetText(text)
|
|
if type(value) == "string" then
|
|
lines[i].value = value
|
|
else
|
|
lines[i].value = text
|
|
end
|
|
if lines[i].value == self.editbox.value and self.getFunc then
|
|
lines[i].check:Show()
|
|
else
|
|
lines[i].check:Hide()
|
|
end
|
|
lines[i]:Show()
|
|
end
|
|
totalheight = totalheight + 17 * (columnHeight-1)
|
|
for k in pairs(ddsort) do
|
|
ddsort[k] = nil
|
|
end
|
|
table_setn(ddsort,0)
|
|
elseif type(list) == "function" then
|
|
for i, text, value in list() do
|
|
if not lines[i] then
|
|
lines[i] = self:CreateLine()
|
|
if i == 1 then
|
|
lines[i]:SetPoint("TOP",self.pullout,"TOP",0,-5)
|
|
else
|
|
lines[i]:SetPoint("TOP",lines[i-1],"BOTTOM",0,0)
|
|
end
|
|
end
|
|
lines[i].text:SetText(text)
|
|
lines[i].value = value
|
|
lines[i]:Show()
|
|
totalheight = totalheight + 17
|
|
end
|
|
end
|
|
self.pullout:SetHeight(totalheight)
|
|
end
|
|
|
|
function WaterfallDropdown.prototype:ClearPullout()
|
|
if self.lines then
|
|
for i, line in ipairs(self.lines) do
|
|
line.text:SetText("")
|
|
line:Hide()
|
|
end
|
|
end
|
|
self.pullout:SetHeight(10)
|
|
self.pullout:SetWidth(DEFAULT_CONTROL_WIDTH)
|
|
end
|
|
|
|
-- For large list, if specified, 0 based row, 1 based column gives a grid.
|
|
function WaterfallDropdown.prototype:CreateLine(row, column)
|
|
local frame = CreateFrame("Button",nil,self.pullout)
|
|
frame.obj = self
|
|
|
|
frame.text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
|
frame.text:SetTextColor(1,1,1)
|
|
frame.text:SetJustifyH("LEFT")
|
|
|
|
frame:SetFrameLevel(25)
|
|
frame:SetFrameStrata("DIALOG")
|
|
|
|
local highlight = frame:CreateTexture(nil, "OVERLAY")
|
|
frame.highlight = highlight
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
|
|
local check = frame:CreateTexture("OVERLAY")
|
|
frame.check = check
|
|
check:SetWidth(16)
|
|
check:SetHeight(16)
|
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
|
|
frame:SetScript("OnClick",Dropdown_LineClicked)
|
|
frame:SetScript("OnEnter",Dropdown_LineEnter)
|
|
frame:SetScript("OnLeave",Dropdown_LineLeave)
|
|
return self:UpdateLine(frame, row, column)
|
|
end
|
|
|
|
|
|
function WaterfallDropdown.prototype:UpdateLine(frame, row, column)
|
|
if (column) then
|
|
frame:SetPoint("TOPLEFT",self.pullout,"TOPLEFT",6 + (column - 1) * DEFAULT_CONTROL_WIDTH,-5 - row*17)
|
|
frame:SetPoint("BOTTOMRIGHT",self.pullout,"TOPLEFT",-6 + column * DEFAULT_CONTROL_WIDTH,-5 - (row+1)*17)
|
|
else
|
|
frame:SetPoint("LEFT",self.pullout,"LEFT",6,0)
|
|
frame:SetPoint("RIGHT",self.pullout,"RIGHT",-6,0)
|
|
end
|
|
|
|
frame.text:SetPoint("TOPLEFT",frame,"TOPLEFT",16,0)
|
|
frame.text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
|
|
|
frame.highlight:SetAllPoints(frame)
|
|
frame.highlight:Hide()
|
|
|
|
frame.check:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
|
|
return frame
|
|
end
|
|
|
|
-----------------------------
|
|
-- WaterfallTreeView Class --
|
|
-----------------------------
|
|
|
|
local function treeviewOnSizeChanged()
|
|
this.obj:SizeChanged()
|
|
end
|
|
local function treeviewOnMouseWheel()
|
|
this.obj:MoveScroll(arg1)
|
|
end
|
|
local function treeviewOnScrollValueChanged()
|
|
this.obj:SetScroll(arg1)
|
|
end
|
|
local function treeviewSizerOnMouseUp()
|
|
this:GetParent():StopMovingOrSizing() this.obj.parent:ReAnchorTree()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:init(parent)
|
|
WaterfallTreeView.super.prototype.init(self)
|
|
--Parent WaterfallFrame Object
|
|
self.parent = parent
|
|
local frame = CreateFrame("Frame",nil,parent.frame)
|
|
frame.obj = self
|
|
local scrollframe = CreateFrame("ScrollFrame",nil,frame)
|
|
local scrollchild = CreateFrame("Frame",nil,scrollframe)
|
|
local scrollbar = CreateFrame("Slider",nil,scrollframe,"UIPanelScrollBarTemplate")
|
|
frame:SetBackdrop(ControlBackdrop)
|
|
frame:SetBackdropBorderColor(0.6, 0.6, 0.6)
|
|
frame:SetBackdropColor(0.1, 0.1, 0.1)
|
|
frame:SetScript("OnSizeChanged", treeviewOnSizeChanged)
|
|
frame:SetFrameLevel(2)
|
|
frame:SetFrameStrata("DIALOG")
|
|
frame:SetResizable(true)
|
|
|
|
self.scrollframe = scrollframe
|
|
self.scrollchild = scrollchild
|
|
self.frame = frame
|
|
self.scrollbar = scrollbar
|
|
|
|
scrollframe:SetScrollChild(scrollchild)
|
|
scrollframe:SetPoint("TOPLEFT",frame,"TOPLEFT",8,-12)
|
|
scrollframe:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-28,12)
|
|
scrollframe:EnableMouseWheel(true)
|
|
scrollframe:SetScript("OnMouseWheel", treeviewOnMouseWheel)
|
|
scrollframe.obj = self
|
|
|
|
scrollchild:SetPoint("TOPLEFT",scrollframe,"TOPLEFT",0,0)
|
|
scrollchild:SetPoint("TOPRIGHT",scrollframe,"TOPRIGHT",0,0)
|
|
scrollchild:SetHeight(400)
|
|
|
|
scrollbar:SetPoint("TOPLEFT",scrollframe,"TOPRIGHT",0,-16)
|
|
scrollbar:SetPoint("BOTTOMLEFT",scrollframe,"BOTTOMRIGHT",0,16)
|
|
scrollbar:SetMinMaxValues(0,1000)
|
|
scrollbar:SetValueStep(1)
|
|
scrollbar:SetValue(0)
|
|
scrollbar:SetWidth(16)
|
|
scrollbar:SetScript("OnValueChanged", treeviewOnScrollValueChanged)
|
|
self.scrollvalue = 0
|
|
scrollchild.lines = {}
|
|
self.linetables = {}
|
|
self.sections = {}
|
|
scrollbar.obj = self
|
|
|
|
local sizer = CreateFrame("Frame",nil,frame)
|
|
sizer:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
|
|
sizer:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
|
sizer:SetWidth(7)
|
|
sizer:EnableMouse()
|
|
sizer:SetScript("OnMouseDown",sizereOnMouseDown)
|
|
sizer:SetScript("OnMouseUp", treeviewSizerOnMouseUp)
|
|
self.sizer = sizer
|
|
sizer.obj = self
|
|
|
|
self:Refresh()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:SetScroll(value)
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local viewheight = frame:GetHeight()
|
|
local height = child:GetHeight()
|
|
local offset
|
|
if viewheight > height then
|
|
offset = 0
|
|
else
|
|
offset = floor((height - viewheight) / 1000.0 * value)
|
|
end
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",0,offset)
|
|
child:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,offset)
|
|
child.offset = offset
|
|
|
|
self.scrollvalue = value
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:SizeChanged()
|
|
self:FixScroll()
|
|
self.parent:ReAnchorTree()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:MoveScroll(value)
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
|
if height > viewheight then
|
|
self.scrollbar:Hide()
|
|
else
|
|
self.scrollbar:Show()
|
|
local diff = height - viewheight
|
|
local delta = 1
|
|
if value < 0 then
|
|
delta = -1
|
|
end
|
|
self.scrollbar:SetValue(math.min(math.max(self.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:FixScroll()
|
|
if self.noFixScroll then return end
|
|
local frame, child = self.scrollframe, self.scrollchild
|
|
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
|
local offset = self.scrollchild.offset
|
|
if not offset then
|
|
offset = 0
|
|
end
|
|
local curvalue = self.scrollbar:GetValue()
|
|
|
|
if viewheight < height then
|
|
self.scrollbar:Hide()
|
|
self.scrollbar:SetValue(0)
|
|
else
|
|
self.scrollbar:Show()
|
|
local value = (offset / (viewheight - height) * 1000)
|
|
if value > 1000 then value = 1000 end
|
|
self.scrollbar:SetValue(value)
|
|
self:SetScroll(value)
|
|
if value < 1000 then
|
|
child:ClearAllPoints()
|
|
child:SetPoint("TOPLEFT",frame,"TOPLEFT",0,offset)
|
|
child:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,offset)
|
|
child.offset = offset
|
|
end
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:ToggleExpand(id)
|
|
self.status[id] = not self.status[id]
|
|
self:Refresh()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:Refresh(noupdate)
|
|
self.noFixScroll = true
|
|
self:Clear()
|
|
if not self.contents then return end
|
|
if self.contentsFunc and not noupdate then
|
|
self.parent.controlcount = 0
|
|
currentframe = self.parent
|
|
self.contentsFunc(self.contents, self.status, getArgs(self, "contentsArg", 1))
|
|
currentframe = nil
|
|
end
|
|
if self.type == "SECTIONS" then
|
|
for i, section in ipairs(self.contents) do
|
|
if not section.hidden then
|
|
self:AddSection(i,section)
|
|
end
|
|
end
|
|
local height = 0
|
|
for i, section in ipairs(self.sections) do
|
|
height = height + section:GetHeight()
|
|
end
|
|
self.scrollchild:SetHeight(height+3)
|
|
else
|
|
local level = 0
|
|
local index = 1
|
|
for i, line in ipairs(self.contents) do
|
|
if not line.hidden then
|
|
index = self:AddLine(index,line,level)
|
|
end
|
|
end
|
|
self.scrollchild:SetHeight(index*16)
|
|
end
|
|
self.noFixScroll = nil
|
|
self:FixScroll()
|
|
end
|
|
|
|
local function isSectionSelected(section, selected)
|
|
if not selected then return end
|
|
if section.id == selected then
|
|
return true
|
|
end
|
|
for i,v in ipairs(section.lines) do
|
|
if i <= section.numlines then
|
|
if v.id == selected then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:Collapse()
|
|
for k in pairs(self.status) do
|
|
self.status[k] = false
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:AddSection(index,line)
|
|
local sections = self.sections
|
|
local id = line.id
|
|
if not sections[index] then
|
|
sections[index] = getObj(WaterfallTreeSection,self)
|
|
local section = sections[index]
|
|
section:SetParent(self)
|
|
if index == 1 then
|
|
section:SetPoint("TOPLEFT",self.scrollchild,"TOPLEFT",0,0)
|
|
section:SetPoint("TOPRIGHT",self.scrollchild,"TOPRIGHT",0,0)
|
|
else
|
|
section:SetPoint("TOPLEFT",sections[index-1],"BOTTOMLEFT",0,0)
|
|
section:SetPoint("TOPRIGHT",sections[index-1],"BOTTOMRIGHT",0,0)
|
|
end
|
|
end
|
|
local section = sections[index]
|
|
section:SetText(line.text)
|
|
section:SetID(line.id)
|
|
section:SetTooltipText(line.tooltipTitle,line.tooltipText)
|
|
if self.status[id] == nil then
|
|
self.status[id] = not not line.isOpen
|
|
end
|
|
|
|
local handler = line.handler
|
|
local disabled = checkNegatable(line.disabled,handler)
|
|
section.disabled = disabled
|
|
section:SetColor(self.parent:GetColor())
|
|
if line.hasOptions then
|
|
section:AddLine(line.text,line.id,line.id == self.selected,disabled,line.tooltipTitle,line.tooltipText)
|
|
end
|
|
local firstid
|
|
for i, item in ipairs(line) do
|
|
if not item.hidden then
|
|
if not firstid then
|
|
firstid = item.id
|
|
end
|
|
local itemdisabled = checkNegatable(item.disabled,handler)
|
|
section:AddLine(item.text,item.id,item.id == self.selected,itemdisabled or disabled,item.tooltipTitle,item.tooltipText)
|
|
end
|
|
end
|
|
if self.selected == section.id and not line.hasOptions then
|
|
self:SetSelected(firstid)
|
|
return
|
|
end
|
|
|
|
if isSectionSelected(section, self.selected) then
|
|
self.status[section.id] = true
|
|
end
|
|
section:SetExpanded(self.status[line.id] and not disabled)
|
|
section:Show()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:Clear()
|
|
for i, frame in ipairs(self.scrollchild.lines) do
|
|
releaseObj(frame)
|
|
self.scrollchild.lines[i] = nil
|
|
end
|
|
for k in pairs(self.linetables) do
|
|
self.linetables[k] = nil
|
|
end
|
|
for i, section in ipairs(self.sections) do
|
|
releaseObj(section)
|
|
self.sections[i] = nil
|
|
end
|
|
self.numlines = 0
|
|
self.scrollchild:SetHeight(1)
|
|
self:FixScroll()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:ClearSelection()
|
|
self.selected = nil
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:GetSelected()
|
|
return self.selected
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:SetSelected(lineid, noupdate)
|
|
self.selected = lineid
|
|
self:Refresh(noupdate)
|
|
if not noupdate then
|
|
self.parent:ChangePane(lineid)
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:AddLine(index,line,level,disabled)
|
|
local lines = self.scrollchild.lines
|
|
local text, hasChildren, isSelected, isOpen
|
|
text = line.text or ""
|
|
hasChildren = table.getn(line) > 0
|
|
local id = line.id
|
|
if self.status[id] == nil then
|
|
self.status[id] = not not line.isOpen
|
|
end
|
|
isOpen = self.status[id] and not disabled
|
|
isSelected = self.selected == id
|
|
if not lines[index] then
|
|
lines[index] = getObj(WaterfallTreeLine)
|
|
lines[index]:SetParent(self)
|
|
end
|
|
local disabled
|
|
if type(line.disabled) == "function" then
|
|
disabled = line.disabled()
|
|
else
|
|
disabled = line.disabled
|
|
end
|
|
lines[index]:Setup(index,id,text,level,hasChildren,isSelected,isOpen,disabled)
|
|
lines[index]:SetTooltipText(line.tooltipTitle,line.tooltipText)
|
|
lines[index]:SetIcon(line.icon)
|
|
self.linetables[index] = line
|
|
index = index + 1
|
|
if isOpen then
|
|
for i, childline in ipairs(line) do
|
|
if not childline.hidden then
|
|
index = self:AddLine(index,childline,level+1)
|
|
end
|
|
end
|
|
end
|
|
|
|
return index
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:SetType(type)
|
|
if not type then
|
|
self.type = "TREE"
|
|
else
|
|
self.type = type
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:SetContent(contents, status, func, ...)
|
|
self.contents = contents
|
|
self.status = status
|
|
self.contentsFunc = func
|
|
local i = 1
|
|
while self["contentsArg"..i] do
|
|
self["contentsArg"..i] = nil
|
|
i = i + 1
|
|
end
|
|
for i = 1 , table.getn(arg) do
|
|
self["contentsArg"..i] = arg[i]
|
|
end
|
|
self:Refresh()
|
|
self:FixScroll()
|
|
end
|
|
|
|
function WaterfallTreeView.prototype:CleanUp()
|
|
self.contents = nil
|
|
self.selected = nil
|
|
self.contentsFunc = nil
|
|
local i = 1
|
|
while self["contentsArg"..i] do
|
|
self["contentsArg"..i] = nil
|
|
i = i + 1
|
|
end
|
|
self.selected = nil
|
|
self:Refresh()
|
|
end
|
|
|
|
--------------------
|
|
-- WaterfallTreeLine Class --
|
|
--------------------
|
|
|
|
local function TreeLine_OnEnter()
|
|
if not this.obj.disabled then
|
|
this.highlight:SetAlpha(1)
|
|
this.highlight:Show()
|
|
showGameTooltip(this.obj)
|
|
end
|
|
end
|
|
|
|
local function TreeLine_OnLeave()
|
|
if not this.obj.isSelected then
|
|
this.highlight:Hide()
|
|
else
|
|
this.highlight:SetAlpha(0.7)
|
|
end
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function TreeLine_OnClick()
|
|
|
|
if not this.obj.disabled then
|
|
this.obj.parent:SetSelected(this.obj.id)
|
|
end
|
|
end
|
|
|
|
local function TreeLine_OnExpandClick()
|
|
|
|
if not this.obj.disabled then
|
|
this.obj.parent:ToggleExpand(this.obj.id)
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:init()
|
|
WaterfallTreeLine.super.prototype.init(self)
|
|
local frame = CreateFrame("Button",nil,nil)
|
|
self.frame = frame
|
|
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
|
|
text:SetJustifyH("LEFT")
|
|
text:SetTextColor(1,1,1)
|
|
frame:SetHeight(16)
|
|
frame:EnableMouse(true)
|
|
frame:SetScript("OnEnter",TreeLine_OnEnter)
|
|
frame:SetScript("OnLeave",TreeLine_OnLeave)
|
|
frame:SetScript("OnClick",TreeLine_OnClick)
|
|
frame:SetFrameLevel(10)
|
|
frame:SetFrameStrata("DIALOG")
|
|
|
|
local highlight = frame:CreateTexture(nil, "BACKGROUND")
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(frame)
|
|
highlight:Hide()
|
|
|
|
local expand = CreateFrame("Button",nil,frame)
|
|
expand.obj = self
|
|
expand:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
|
|
expand:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down")
|
|
expand:SetDisabledTexture("Interface\\Buttons\\UI-PlusButton-Disabled")
|
|
expand:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
|
|
expand:SetScript("OnClick",TreeLine_OnExpandClick)
|
|
expand:SetFrameLevel(21)
|
|
expand:SetWidth(16)
|
|
expand:SetHeight(16)
|
|
|
|
local icon = frame:CreateTexture(nil,"OVERLAY")
|
|
icon:SetWidth(16)
|
|
icon:SetHeight(16)
|
|
icon:SetPoint("LEFT",expand,"RIGHT",1,0)
|
|
self.icon = icon
|
|
|
|
|
|
expand:SetPoint("LEFT",frame,"LEFT",0,0)
|
|
text:SetPoint("LEFT",icon,"RIGHT",2,0)
|
|
text:SetPoint("RIGHT",frame,"RIGHT",0,0)
|
|
|
|
frame.obj = self
|
|
frame.text = text
|
|
frame.highlight = highlight
|
|
frame.expand = expand
|
|
self.expand = expand
|
|
self.highlight = highlight
|
|
self.text = text
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:UpdateExpandButton()
|
|
local expand = self.expand
|
|
if self.hasChildren then
|
|
if self.isOpen then
|
|
expand:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up")
|
|
expand:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down")
|
|
expand:SetDisabledTexture("Interface\\Buttons\\UI-MinusButton-Disabled")
|
|
expand:Enable()
|
|
expand:SetWidth(16)
|
|
else
|
|
if self.disabled then
|
|
expand:Disable()
|
|
else
|
|
expand:Enable()
|
|
end
|
|
expand:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
|
|
expand:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down")
|
|
expand:SetDisabledTexture("Interface\\Buttons\\UI-PlusButton-Disabled")
|
|
|
|
expand:SetWidth(16)
|
|
end
|
|
else
|
|
expand:SetNormalTexture(nil)
|
|
expand:SetPushedTexture(nil)
|
|
expand:SetDisabledTexture(nil)
|
|
expand:Disable()
|
|
expand:SetWidth(16)
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:CleanUp()
|
|
self:ClearAllPoints()
|
|
self:Hide()
|
|
self:SetText("")
|
|
self.disabled = nil
|
|
self.handler = nil
|
|
self.name = nil
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:Setup(index, id, text, level, hasChildren, isSelected, isOpen, disabled)
|
|
self.level = level
|
|
self.hasChildren = hasChildren
|
|
self.isSelected = isSelected
|
|
self.isOpen = isOpen and not disabled
|
|
self.index = index
|
|
self.id = id
|
|
self.disabled = disabled
|
|
|
|
self:UpdateExpandButton()
|
|
|
|
self.expand:SetPoint("LEFT",self.frame,"LEFT",level*8,0)
|
|
self:SetText(text)
|
|
if disabled then
|
|
self.text:SetTextColor(0.5,0.5,0.5)
|
|
else
|
|
self.text:SetTextColor(1,1,1)
|
|
end
|
|
self.frame:SetPoint("TOPLEFT",self.parent.scrollchild,"TOPLEFT",0,-(index-1)*16)
|
|
self.frame:SetPoint("TOPRIGHT",self.parent.scrollchild,"TOPRIGHT",0,-(index-1)*16)
|
|
if self.isSelected then
|
|
self.highlight:Show()
|
|
self.highlight:SetAlpha(0.7)
|
|
else
|
|
self.highlight:Hide()
|
|
end
|
|
self.frame:Show()
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:SetIcon(iconpath)
|
|
local icon = self.icon
|
|
if iconpath then
|
|
icon:SetTexture(iconpath)
|
|
icon:SetWidth(16)
|
|
else
|
|
icon:SetTexture(nil)
|
|
icon:SetWidth(1)
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:SetText(text)
|
|
self.text:SetText(text)
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:SetTooltipText(title,text)
|
|
self.tooltipTitle = title
|
|
self.tooltipText = text
|
|
end
|
|
|
|
function WaterfallTreeLine.prototype:SetParent(parent)
|
|
self.parent = parent
|
|
self.frame.parent = parent
|
|
self.frame:SetParent(parent.scrollchild)
|
|
end
|
|
|
|
-----------------------
|
|
-- TreeSection Class --
|
|
-----------------------
|
|
|
|
local function SectionTitle_OnClick()
|
|
local self = this.obj
|
|
local parent = self.parent
|
|
if not self.disabled then
|
|
local selected = self.parent.selected
|
|
local lines = self.lines
|
|
if self.expanded then
|
|
--search before changing pane, since it will release and reinit this section
|
|
local found
|
|
for i = 1, self.numlines do
|
|
if lines[i].id == selected then
|
|
found = true
|
|
end
|
|
end
|
|
--if expanded close
|
|
|
|
-- if one of our children is selected then clear the pane
|
|
if found then
|
|
parent.selected = nil
|
|
parent:ToggleExpand(self.id)
|
|
parent:SetSelected(nil)
|
|
else
|
|
parent:ToggleExpand(self.id)
|
|
end
|
|
else
|
|
--save before changing pane, since it will release and reinit this section
|
|
local newid
|
|
if lines[1] then
|
|
newid = lines[1].id
|
|
end
|
|
parent:ToggleExpand(self.id)
|
|
if newid and not parent.selected then
|
|
parent:SetSelected(newid)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SectionTitle_OnEnter()
|
|
local self = this.obj
|
|
if not self.disabled then
|
|
self.hover = true
|
|
self:UpdateColor()
|
|
end
|
|
showGameTooltip(self)
|
|
end
|
|
|
|
local function SectionTitle_OnLeave()
|
|
local self = this.obj
|
|
self.hover = false
|
|
self:UpdateColor()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function SectionItem_OnEnter()
|
|
if not this.disabled then
|
|
this.highlight:SetAlpha(1)
|
|
this.highlight:Show()
|
|
showGameTooltip()
|
|
end
|
|
end
|
|
|
|
local function SectionItem_OnClick()
|
|
|
|
if not this.disabled then
|
|
this.obj.parent:SetSelected(this.id)
|
|
end
|
|
end
|
|
|
|
local function SectionItem_OnLeave()
|
|
if not this.isSelected then
|
|
this.highlight:Hide()
|
|
else
|
|
this.highlight:SetAlpha(0.7)
|
|
end
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:init(parent)
|
|
WaterfallTreeSection.super.prototype.init(self)
|
|
|
|
self.parent = parent
|
|
local frame = CreateFrame("Frame",nil,parent.scrollchild)
|
|
frame.obj = self
|
|
self.frame = frame
|
|
frame:SetBackdrop(PaneBackdrop)
|
|
frame:SetBackdropBorderColor(0.6, 0.6, 0.6)
|
|
frame:SetBackdropColor(0.1, 0.1, 0.1)
|
|
frame:SetFrameLevel(10)
|
|
frame:SetFrameStrata("DIALOG")
|
|
|
|
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
self.titletext = titletext
|
|
titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",0,-5)
|
|
titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-5)
|
|
titletext:SetHeight(16)
|
|
titletext:SetText("Section")
|
|
titletext:SetTextColor(1,1,1)
|
|
|
|
local arrow = frame:CreateTexture(nil,"OVERLAY")
|
|
self.arrow = arrow
|
|
arrow:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-6,-4)
|
|
arrow:SetWidth(20)
|
|
arrow:SetHeight(20)
|
|
arrow:SetTexture("Interface\\MiniMap\\ROTATING-MINIMAPARROW")
|
|
|
|
local r,g,b = 1, 0.6, 0
|
|
self.colorR = r
|
|
self.colorG = g
|
|
self.colorB = b
|
|
local titlebar = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar = titlebar
|
|
local titlebar2 = frame:CreateTexture(nil,"BACKGROUND")
|
|
self.titlebar2 = titlebar2
|
|
titlebar:SetPoint("TOPLEFT",frame,"TOPLEFT",4,-4)
|
|
titlebar:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-4,-4)
|
|
titlebar:SetHeight(10)
|
|
titlebar2:SetPoint("TOPLEFT",titlebar,"BOTTOMLEFT",0,0)
|
|
titlebar2:SetPoint("TOPRIGHT",titlebar,"BOTTOMRIGHT",0,0)
|
|
titlebar2:SetHeight(10)
|
|
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
|
|
local title = CreateFrame("Button",nil,frame)
|
|
self.title = title
|
|
title:EnableMouse()
|
|
title.obj = self
|
|
title:SetScript("OnClick", SectionTitle_OnClick)
|
|
title:SetScript("OnEnter", SectionTitle_OnEnter)
|
|
title:SetScript("OnLeave", SectionTitle_OnLeave)
|
|
title:SetPoint("TOPLEFT",titlebar,"TOPLEFT",0,0)
|
|
title:SetPoint("BOTTOMRIGHT",titlebar2,"BOTTOMRIGHT",0,0)
|
|
|
|
self.lines = {}
|
|
self.numlines = 0
|
|
|
|
frame:SetWidth(100)
|
|
frame:SetHeight(100)
|
|
self.expanded = true
|
|
|
|
|
|
|
|
frame:SetPoint("CENTER",UIParent,"CENTER")
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:SetParent(parent)
|
|
self.parent = parent
|
|
self.frame:SetParent(parent.scrollchild)
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:UpdateColor()
|
|
local r,g,b
|
|
self.arrow:Show()
|
|
if self.disabled then
|
|
r,g,b = 0.5,0.5,0.5
|
|
self.arrow:Hide()
|
|
elseif self.hover then
|
|
r,g,b = self.colorR+((1-self.colorR)/2), self.colorG+((1-self.colorG)/2), self.colorB+((1-self.colorB)/2)
|
|
else
|
|
r,g,b = self.colorR, self.colorG, self.colorB
|
|
end
|
|
|
|
local titlebar = self.titlebar
|
|
local titlebar2 = self.titlebar2
|
|
titlebar:SetGradientAlpha("VERTICAL",r*0.6,g*0.6,b*0.6,1,r,g,b,1)
|
|
titlebar:SetTexture(r,g,b,1)
|
|
titlebar2:SetGradientAlpha("VERTICAL",r*0.9,g*0.9,b*0.9,1,r*0.6,g*0.6,b*0.6,1)
|
|
titlebar2:SetTexture(r,g,b,1)
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:SetColor(r,g,b)
|
|
if r and g and b then
|
|
self.colorR, self.colorG, self.colorB = r,g,b
|
|
end
|
|
self:UpdateColor()
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:ToggleExpand()
|
|
self:SetExpanded(not self.expanded)
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:SetText(text)
|
|
self.titletext:SetText(text)
|
|
end
|
|
|
|
|
|
function WaterfallTreeSection.prototype:SetTooltipText(title,text)
|
|
self.tooltipTitle = title
|
|
self.tooltipText = text
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:SetID(id)
|
|
self.id = id
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:AddLine(text,id,selected,disabled,tooltipTitle,tooltipText)
|
|
local numlines = self.numlines + 1
|
|
self.numlines = numlines
|
|
local lines = self.lines
|
|
if not lines[numlines] then
|
|
self:CreateLine(numlines)
|
|
end
|
|
local line = lines[numlines]
|
|
|
|
line.text:SetText(text)
|
|
line.id = id
|
|
line.disabled = disabled
|
|
line.isSelected = selected
|
|
line.tooltipTitle = tooltipTitle
|
|
line.tooltipText = tooltipText
|
|
if selected then
|
|
line.highlight:SetAlpha(0.7)
|
|
line.highlight:Show()
|
|
else
|
|
line.highlight:Hide()
|
|
end
|
|
if disabled then
|
|
line.text:SetTextColor(0.5,0.5,0.5)
|
|
else
|
|
line.text:SetTextColor(1,1,1)
|
|
end
|
|
line:Show()
|
|
self:FixHeight()
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:SetExpanded(expanded)
|
|
self.expanded = expanded
|
|
local lines = self.lines
|
|
if self.expanded then
|
|
for i = 1, self.numlines do
|
|
lines[i]:Show()
|
|
end
|
|
self.arrow:SetTexCoord(.18,.85,.15,.82)
|
|
else
|
|
for i = 1, table.getn(lines) do
|
|
lines[i]:Hide()
|
|
end
|
|
self.arrow:SetTexCoord(.85,.18,.82,.15)
|
|
end
|
|
self:FixHeight()
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:FixHeight()
|
|
if self.expanded then
|
|
self.frame:SetHeight(33 + self.numlines * 18)
|
|
else
|
|
self.frame:SetHeight(28)
|
|
end
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:CreateLine(index)
|
|
local frame = self.frame
|
|
self.lines[index] = CreateFrame("Button",nil,frame)
|
|
local line = self.lines[index]
|
|
line.obj = self
|
|
|
|
line:SetScript("OnEnter",SectionItem_OnEnter)
|
|
line:SetScript("OnLeave",SectionItem_OnLeave)
|
|
line:SetScript("OnClick",SectionItem_OnClick)
|
|
|
|
line:SetPoint("LEFT",frame,"LEFT",5,0)
|
|
line:SetPoint("RIGHT",frame,"RIGHT",-5,0)
|
|
line:SetHeight(16)
|
|
if index == 1 then
|
|
line:SetPoint("TOP",frame,"TOP",0,-28)
|
|
else
|
|
line:SetPoint("TOP",self.lines[index-1],"BOTTOM",0,-2)
|
|
end
|
|
|
|
local text = line:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
|
line.text = text
|
|
text:SetAllPoints(line)
|
|
text:SetTextColor(1,1,1)
|
|
|
|
local highlight = line:CreateTexture(nil, "BACKGROUND")
|
|
line.highlight = highlight
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(line)
|
|
highlight:Hide()
|
|
end
|
|
|
|
function WaterfallTreeSection.prototype:CleanUp()
|
|
for i = 1, table.getn(self.lines) do
|
|
self.lines[i]:Hide()
|
|
end
|
|
self.numlines = 0
|
|
self.frame:Hide()
|
|
self.frame:ClearAllPoints()
|
|
self.id = nil
|
|
self.disabled = nil
|
|
self.colorR = 1
|
|
self.colorG = 0.6
|
|
self.colorB = 0
|
|
end
|
|
|
|
local function activate(self, oldLib, oldDeactivate)
|
|
if oldLib and oldLib.registry then
|
|
self.registry = oldLib.registry
|
|
else
|
|
self.registry = {}
|
|
end
|
|
if oldDeactivate then
|
|
oldDeactivate(oldLib)
|
|
end
|
|
end
|
|
|
|
AceLibrary:Register(Waterfall, MAJOR_VERSION, MINOR_VERSION, activate)
|
|
Waterfall = AceLibrary("Waterfall-1.0")
|