747 lignes
20 Kio
Lua
747 lignes
20 Kio
Lua
|
local AceGUI = LibStub("AceGUI-3.0")
|
||
|
|
||
|
-- Lua APIs
|
||
|
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
||
|
local math_min, math_max, floor = math.min, math.max, floor
|
||
|
local select, tremove, unpack = select, table.remove, unpack
|
||
|
|
||
|
-- WoW APIs
|
||
|
local CreateFrame, UIParent = CreateFrame, UIParent
|
||
|
|
||
|
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||
|
-- List them here for Mikk's FindGlobals script
|
||
|
-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
|
||
|
|
||
|
-- Recycling functions
|
||
|
local new, del
|
||
|
do
|
||
|
local pool = setmetatable({},{__mode='k'})
|
||
|
function new()
|
||
|
local t = next(pool)
|
||
|
if t then
|
||
|
pool[t] = nil
|
||
|
return t
|
||
|
else
|
||
|
return {}
|
||
|
end
|
||
|
end
|
||
|
function del(t)
|
||
|
for k in pairs(t) do
|
||
|
t[k] = nil
|
||
|
end
|
||
|
pool[t] = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--------------
|
||
|
-- TreeView --
|
||
|
--------------
|
||
|
|
||
|
do
|
||
|
local Type = "TreeGroup"
|
||
|
local Version = 23
|
||
|
|
||
|
local DEFAULT_TREE_WIDTH = 175
|
||
|
local DEFAULT_TREE_SIZABLE = true
|
||
|
|
||
|
local PaneBackdrop = {
|
||
|
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||
|
tile = true, tileSize = 16, edgeSize = 16,
|
||
|
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||
|
}
|
||
|
|
||
|
local DraggerBackdrop = {
|
||
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||
|
edgeFile = nil,
|
||
|
tile = true, tileSize = 16, edgeSize = 0,
|
||
|
insets = { left = 3, right = 3, top = 7, bottom = 7 }
|
||
|
}
|
||
|
|
||
|
local function OnAcquire(self)
|
||
|
self:SetTreeWidth(DEFAULT_TREE_WIDTH,DEFAULT_TREE_SIZABLE)
|
||
|
self:EnableButtonTooltips(true)
|
||
|
end
|
||
|
|
||
|
local function OnRelease(self)
|
||
|
|
||
|
self.frame:ClearAllPoints()
|
||
|
self.frame:Hide()
|
||
|
self.status = nil
|
||
|
for k, v in pairs(self.localstatus) do
|
||
|
if k == "groups" then
|
||
|
for k2 in pairs(v) do
|
||
|
v[k2] = nil
|
||
|
end
|
||
|
else
|
||
|
self.localstatus[k] = nil
|
||
|
end
|
||
|
end
|
||
|
self.localstatus.scrollvalue = 0
|
||
|
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
|
||
|
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
|
||
|
end
|
||
|
|
||
|
local function GetButtonParents(line)
|
||
|
local parent = line.parent
|
||
|
if parent and parent.value then
|
||
|
return parent.value, GetButtonParents(parent)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function GetButtonUniqueValue(line)
|
||
|
local parent = line.parent
|
||
|
if parent and parent.value then
|
||
|
return GetButtonUniqueValue(parent).."\001"..line.value
|
||
|
else
|
||
|
return line.value
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function ButtonOnClick(this)
|
||
|
local self = this.obj
|
||
|
self:Fire("OnClick",this.uniquevalue, this.selected)
|
||
|
if not this.selected then
|
||
|
self:SetSelected(this.uniquevalue)
|
||
|
this.selected = true
|
||
|
this:LockHighlight()
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
AceGUI:ClearFocus()
|
||
|
end
|
||
|
|
||
|
local function ExpandOnClick(this)
|
||
|
local button = this.button
|
||
|
local self = button.obj
|
||
|
local status = (self.status or self.localstatus).groups
|
||
|
status[button.uniquevalue] = not status[button.uniquevalue]
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
|
||
|
local function ButtonOnDoubleClick(button)
|
||
|
local self = button.obj
|
||
|
local status = self.status or self.localstatus
|
||
|
local status = (self.status or self.localstatus).groups
|
||
|
status[button.uniquevalue] = not status[button.uniquevalue]
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
|
||
|
local function EnableButtonTooltips(self, enable)
|
||
|
self.enabletooltips = enable
|
||
|
end
|
||
|
|
||
|
local function Button_OnEnter(this)
|
||
|
local self = this.obj
|
||
|
self:Fire("OnButtonEnter", this.uniquevalue, this)
|
||
|
|
||
|
if self.enabletooltips then
|
||
|
GameTooltip:SetOwner(this, "ANCHOR_NONE")
|
||
|
GameTooltip:SetPoint("LEFT",this,"RIGHT")
|
||
|
GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, 1)
|
||
|
|
||
|
GameTooltip:Show()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function Button_OnLeave(this)
|
||
|
local self = this.obj
|
||
|
self:Fire("OnButtonLeave", this.uniquevalue, this)
|
||
|
|
||
|
if self.enabletooltips then
|
||
|
GameTooltip:Hide()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
local buttoncount = 1
|
||
|
local function CreateButton(self)
|
||
|
local button = CreateFrame("Button",("AceGUI30TreeButton%d"):format(buttoncount),self.treeframe, "OptionsListButtonTemplate")
|
||
|
buttoncount = buttoncount + 1
|
||
|
button.obj = self
|
||
|
|
||
|
local icon = button:CreateTexture(nil, "OVERLAY")
|
||
|
icon:SetWidth(14)
|
||
|
icon:SetHeight(14)
|
||
|
button.icon = icon
|
||
|
|
||
|
button:SetScript("OnClick",ButtonOnClick)
|
||
|
button:SetScript("OnDoubleClick", ButtonOnDoubleClick)
|
||
|
button:SetScript("OnEnter",Button_OnEnter)
|
||
|
button:SetScript("OnLeave",Button_OnLeave)
|
||
|
|
||
|
button.toggle.button = button
|
||
|
button.toggle:SetScript("OnClick",ExpandOnClick)
|
||
|
|
||
|
return button
|
||
|
end
|
||
|
|
||
|
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
|
||
|
local self = button.obj
|
||
|
local toggle = button.toggle
|
||
|
local frame = self.frame
|
||
|
local text = treeline.text or ""
|
||
|
local icon = treeline.icon
|
||
|
local iconCoords = treeline.iconCoords
|
||
|
local level = treeline.level
|
||
|
local value = treeline.value
|
||
|
local uniquevalue = treeline.uniquevalue
|
||
|
local disabled = treeline.disabled
|
||
|
|
||
|
button.treeline = treeline
|
||
|
button.value = value
|
||
|
button.uniquevalue = uniquevalue
|
||
|
if selected then
|
||
|
button:LockHighlight()
|
||
|
button.selected = true
|
||
|
else
|
||
|
button:UnlockHighlight()
|
||
|
button.selected = false
|
||
|
end
|
||
|
local normalTexture = button:GetNormalTexture()
|
||
|
local line = button.line
|
||
|
button.level = level
|
||
|
if ( level == 1 ) then
|
||
|
button:SetNormalFontObject("GameFontNormal")
|
||
|
button:SetHighlightFontObject("GameFontHighlight")
|
||
|
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
||
|
else
|
||
|
button:SetNormalFontObject("GameFontHighlightSmall")
|
||
|
button:SetHighlightFontObject("GameFontHighlightSmall")
|
||
|
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
||
|
end
|
||
|
|
||
|
if disabled then
|
||
|
button:EnableMouse(false)
|
||
|
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
|
||
|
else
|
||
|
button.text:SetText(text)
|
||
|
button:EnableMouse(true)
|
||
|
end
|
||
|
|
||
|
if icon then
|
||
|
button.icon:SetTexture(icon)
|
||
|
button.icon:SetPoint("LEFT", button, "LEFT", 8 * level, (level == 1) and 0 or 1)
|
||
|
else
|
||
|
button.icon:SetTexture(nil)
|
||
|
end
|
||
|
|
||
|
if iconCoords then
|
||
|
button.icon:SetTexCoord(unpack(iconCoords))
|
||
|
else
|
||
|
button.icon:SetTexCoord(0, 1, 0, 1)
|
||
|
end
|
||
|
|
||
|
if canExpand then
|
||
|
if not isExpanded then
|
||
|
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
|
||
|
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
|
||
|
else
|
||
|
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
|
||
|
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
|
||
|
end
|
||
|
toggle:Show()
|
||
|
else
|
||
|
toggle:Hide()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
local function OnScrollValueChanged(this, value)
|
||
|
if this.obj.noupdate then return end
|
||
|
local self = this.obj
|
||
|
local status = self.status or self.localstatus
|
||
|
status.scrollvalue = value
|
||
|
self:RefreshTree()
|
||
|
AceGUI:ClearFocus()
|
||
|
end
|
||
|
|
||
|
-- called to set an external table to store status in
|
||
|
local function SetStatusTable(self, status)
|
||
|
assert(type(status) == "table")
|
||
|
self.status = status
|
||
|
if not status.groups then
|
||
|
status.groups = {}
|
||
|
end
|
||
|
if not status.scrollvalue then
|
||
|
status.scrollvalue = 0
|
||
|
end
|
||
|
if not status.treewidth then
|
||
|
status.treewidth = DEFAULT_TREE_WIDTH
|
||
|
end
|
||
|
if not status.treesizable then
|
||
|
status.treesizable = DEFAULT_TREE_SIZABLE
|
||
|
end
|
||
|
self:SetTreeWidth(status.treewidth,status.treesizable)
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
|
||
|
--sets the tree to be displayed
|
||
|
--[[
|
||
|
example tree
|
||
|
|
||
|
Alpha
|
||
|
Bravo
|
||
|
-Charlie
|
||
|
-Delta
|
||
|
-Echo
|
||
|
Foxtrot
|
||
|
|
||
|
tree = {
|
||
|
{
|
||
|
value = "A",
|
||
|
text = "Alpha"
|
||
|
},
|
||
|
{
|
||
|
value = "B",
|
||
|
text = "Bravo",
|
||
|
children = {
|
||
|
{
|
||
|
value = "C",
|
||
|
text = "Charlie"
|
||
|
},
|
||
|
{
|
||
|
value = "D",
|
||
|
text = "Delta"
|
||
|
children = {
|
||
|
{
|
||
|
value = "E",
|
||
|
text = "Echo"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
value = "F",
|
||
|
text = "Foxtrot"
|
||
|
},
|
||
|
}
|
||
|
]]
|
||
|
local function SetTree(self, tree, filter)
|
||
|
self.filter = filter
|
||
|
if tree then
|
||
|
assert(type(tree) == "table")
|
||
|
end
|
||
|
self.tree = tree
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
|
||
|
local function ShouldDisplayLevel(tree)
|
||
|
local result = false
|
||
|
for k, v in ipairs(tree) do
|
||
|
if v.children == nil and v.visible ~= false then
|
||
|
result = true
|
||
|
elseif v.children then
|
||
|
result = result or ShouldDisplayLevel(v.children)
|
||
|
end
|
||
|
if result then return result end
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
local function addLine(self, v, tree, level, parent)
|
||
|
local line = new()
|
||
|
line.value = v.value
|
||
|
line.text = v.text
|
||
|
line.icon = v.icon
|
||
|
line.iconCoords = v.iconCoords
|
||
|
line.disabled = v.disabled
|
||
|
line.tree = tree
|
||
|
line.level = level
|
||
|
line.parent = parent
|
||
|
line.visible = v.visible
|
||
|
line.uniquevalue = GetButtonUniqueValue(line)
|
||
|
if v.children then
|
||
|
line.hasChildren = true
|
||
|
else
|
||
|
line.hasChildren = nil
|
||
|
end
|
||
|
self.lines[#self.lines+1] = line
|
||
|
return line
|
||
|
end
|
||
|
|
||
|
local function BuildLevel(self, tree, level, parent)
|
||
|
local groups = (self.status or self.localstatus).groups
|
||
|
local hasChildren = self.hasChildren
|
||
|
|
||
|
for i, v in ipairs(tree) do
|
||
|
if v.children then
|
||
|
if not self.filter or ShouldDisplayLevel(v.children) then
|
||
|
local line = addLine(self, v, tree, level, parent)
|
||
|
if groups[line.uniquevalue] then
|
||
|
self:BuildLevel(v.children, level+1, line)
|
||
|
end
|
||
|
end
|
||
|
elseif v.visible ~= false or not self.filter then
|
||
|
addLine(self, v, tree, level, parent)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--fire an update after one frame to catch the treeframes height
|
||
|
local function FirstFrameUpdate(this)
|
||
|
local self = this.obj
|
||
|
this:SetScript("OnUpdate",nil)
|
||
|
self:RefreshTree()
|
||
|
end
|
||
|
|
||
|
local function ResizeUpdate(this)
|
||
|
this.obj:RefreshTree()
|
||
|
end
|
||
|
|
||
|
local function RefreshTree(self)
|
||
|
local buttons = self.buttons
|
||
|
local lines = self.lines
|
||
|
|
||
|
for i, v in ipairs(buttons) do
|
||
|
v:Hide()
|
||
|
end
|
||
|
while lines[1] do
|
||
|
local t = tremove(lines)
|
||
|
for k in pairs(t) do
|
||
|
t[k] = nil
|
||
|
end
|
||
|
del(t)
|
||
|
end
|
||
|
|
||
|
if not self.tree then return end
|
||
|
--Build the list of visible entries from the tree and status tables
|
||
|
local status = self.status or self.localstatus
|
||
|
local groupstatus = status.groups
|
||
|
local tree = self.tree
|
||
|
|
||
|
local treeframe = self.treeframe
|
||
|
|
||
|
self:BuildLevel(tree, 1)
|
||
|
|
||
|
local numlines = #lines
|
||
|
|
||
|
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
|
||
|
|
||
|
local first, last
|
||
|
|
||
|
if numlines <= maxlines then
|
||
|
--the whole tree fits in the frame
|
||
|
status.scrollvalue = 0
|
||
|
self:ShowScroll(false)
|
||
|
first, last = 1, numlines
|
||
|
else
|
||
|
self:ShowScroll(true)
|
||
|
--scrolling will be needed
|
||
|
self.noupdate = true
|
||
|
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
|
||
|
--check if we are scrolled down too far
|
||
|
if numlines - status.scrollvalue < maxlines then
|
||
|
status.scrollvalue = numlines - maxlines
|
||
|
self.scrollbar:SetValue(status.scrollvalue)
|
||
|
end
|
||
|
self.noupdate = nil
|
||
|
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
||
|
end
|
||
|
|
||
|
local buttonnum = 1
|
||
|
for i = first, last do
|
||
|
local line = lines[i]
|
||
|
local button = buttons[buttonnum]
|
||
|
if not button then
|
||
|
button = self:CreateButton()
|
||
|
|
||
|
buttons[buttonnum] = button
|
||
|
button:SetParent(treeframe)
|
||
|
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
|
||
|
button:ClearAllPoints()
|
||
|
if i == 1 then
|
||
|
if self.showscroll then
|
||
|
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
||
|
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
||
|
else
|
||
|
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
||
|
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
||
|
end
|
||
|
else
|
||
|
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
|
||
|
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
|
||
|
button:Show()
|
||
|
buttonnum = buttonnum + 1
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
local function SetSelected(self, value)
|
||
|
local status = self.status or self.localstatus
|
||
|
if status.selected ~= value then
|
||
|
status.selected = value
|
||
|
self:Fire("OnGroupSelected", value)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function BuildUniqueValue(...)
|
||
|
local n = select('#', ...)
|
||
|
if n == 1 then
|
||
|
return ...
|
||
|
else
|
||
|
return (...).."\001"..BuildUniqueValue(select(2,...))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function Select(self, uniquevalue, ...)
|
||
|
self.filter = false
|
||
|
local status = self.status or self.localstatus
|
||
|
local groups = status.groups
|
||
|
for i = 1, select('#', ...) do
|
||
|
groups[BuildUniqueValue(select(i, ...))] = true
|
||
|
end
|
||
|
status.selected = uniquevalue
|
||
|
self:RefreshTree()
|
||
|
self:Fire("OnGroupSelected", uniquevalue)
|
||
|
end
|
||
|
|
||
|
local function SelectByPath(self, ...)
|
||
|
self:Select(BuildUniqueValue(...), ...)
|
||
|
end
|
||
|
|
||
|
--Selects a tree node by UniqueValue
|
||
|
local function SelectByValue(self, uniquevalue)
|
||
|
self:Select(uniquevalue, ("\001"):split(uniquevalue))
|
||
|
end
|
||
|
|
||
|
|
||
|
local function ShowScroll(self, show)
|
||
|
self.showscroll = show
|
||
|
if show then
|
||
|
self.scrollbar:Show()
|
||
|
if self.buttons[1] then
|
||
|
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
||
|
end
|
||
|
else
|
||
|
self.scrollbar:Hide()
|
||
|
if self.buttons[1] then
|
||
|
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function OnWidthSet(self, width)
|
||
|
local content = self.content
|
||
|
local treeframe = self.treeframe
|
||
|
local status = self.status or self.localstatus
|
||
|
status.fullwidth = width
|
||
|
|
||
|
local contentwidth = width - status.treewidth - 20
|
||
|
if contentwidth < 0 then
|
||
|
contentwidth = 0
|
||
|
end
|
||
|
content:SetWidth(contentwidth)
|
||
|
content.width = contentwidth
|
||
|
|
||
|
local maxtreewidth = math_min(400, width - 50)
|
||
|
|
||
|
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
|
||
|
self:SetTreeWidth(maxtreewidth, status.treesizable)
|
||
|
end
|
||
|
treeframe:SetMaxResize(maxtreewidth,1600)
|
||
|
end
|
||
|
|
||
|
|
||
|
local function OnHeightSet(self, height)
|
||
|
local content = self.content
|
||
|
local contentheight = height - 20
|
||
|
if contentheight < 0 then
|
||
|
contentheight = 0
|
||
|
end
|
||
|
content:SetHeight(contentheight)
|
||
|
content.height = contentheight
|
||
|
end
|
||
|
|
||
|
|
||
|
local function TreeOnMouseWheel(this, delta)
|
||
|
local self = this.obj
|
||
|
if self.showscroll then
|
||
|
local scrollbar = self.scrollbar
|
||
|
local min, max = scrollbar:GetMinMaxValues()
|
||
|
local value = scrollbar:GetValue()
|
||
|
local newvalue = math_min(max,math_max(min,value - delta))
|
||
|
if value ~= newvalue then
|
||
|
scrollbar:SetValue(newvalue)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function SetTreeWidth(self, treewidth, resizable)
|
||
|
if not resizable then
|
||
|
if type(treewidth) == 'number' then
|
||
|
resizable = false
|
||
|
elseif type(treewidth) == 'boolean' then
|
||
|
resizable = treewidth
|
||
|
treewidth = DEFAULT_TREE_WIDTH
|
||
|
else
|
||
|
resizable = false
|
||
|
treewidth = DEFAULT_TREE_WIDTH
|
||
|
end
|
||
|
end
|
||
|
self.treeframe:SetWidth(treewidth)
|
||
|
self.dragger:EnableMouse(resizable)
|
||
|
|
||
|
local status = self.status or self.localstatus
|
||
|
status.treewidth = treewidth
|
||
|
status.treesizable = resizable
|
||
|
|
||
|
-- recalculate the content width
|
||
|
if status.fullwidth then
|
||
|
self:OnWidthSet(status.fullwidth)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function draggerLeave(this)
|
||
|
this:SetBackdropColor(1, 1, 1, 0)
|
||
|
end
|
||
|
|
||
|
local function draggerEnter(this)
|
||
|
this:SetBackdropColor(1, 1, 1, 0.8)
|
||
|
end
|
||
|
|
||
|
local function draggerDown(this)
|
||
|
local treeframe = this:GetParent()
|
||
|
treeframe:StartSizing("RIGHT")
|
||
|
end
|
||
|
|
||
|
local function draggerUp(this)
|
||
|
local treeframe = this:GetParent()
|
||
|
local self = treeframe.obj
|
||
|
local frame = treeframe:GetParent()
|
||
|
treeframe:StopMovingOrSizing()
|
||
|
--treeframe:SetScript("OnUpdate", nil)
|
||
|
treeframe:SetUserPlaced(false)
|
||
|
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
||
|
treeframe:SetHeight(0)
|
||
|
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
||
|
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
||
|
|
||
|
local status = self.status or self.localstatus
|
||
|
status.treewidth = treeframe:GetWidth()
|
||
|
|
||
|
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
|
||
|
-- recalculate the content width
|
||
|
treeframe.obj:OnWidthSet(status.fullwidth)
|
||
|
-- update the layout of the content
|
||
|
treeframe.obj:DoLayout()
|
||
|
end
|
||
|
|
||
|
local function LayoutFinished(self, width, height)
|
||
|
if self.noAutoHeight then return end
|
||
|
self:SetHeight((height or 0) + 20)
|
||
|
end
|
||
|
|
||
|
local createdcount = 0
|
||
|
local function Constructor()
|
||
|
local frame = CreateFrame("Frame",nil,UIParent)
|
||
|
local self = {}
|
||
|
self.type = Type
|
||
|
self.lines = {}
|
||
|
self.levels = {}
|
||
|
self.buttons = {}
|
||
|
self.hasChildren = {}
|
||
|
self.localstatus = {}
|
||
|
self.localstatus.groups = {}
|
||
|
self.filter = false
|
||
|
|
||
|
local treeframe = CreateFrame("Frame",nil,frame)
|
||
|
treeframe.obj = self
|
||
|
treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
||
|
treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
||
|
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
||
|
treeframe:SetScript("OnUpdate",FirstFrameUpdate)
|
||
|
treeframe:SetScript("OnSizeChanged",ResizeUpdate)
|
||
|
|
||
|
treeframe:EnableMouseWheel(true)
|
||
|
treeframe:SetScript("OnMouseWheel", TreeOnMouseWheel)
|
||
|
treeframe:SetBackdrop(PaneBackdrop)
|
||
|
treeframe:SetBackdropColor(0.1,0.1,0.1,0.5)
|
||
|
treeframe:SetBackdropBorderColor(0.4,0.4,0.4)
|
||
|
|
||
|
treeframe:SetResizable(true)
|
||
|
treeframe:SetMinResize(100, 1)
|
||
|
treeframe:SetMaxResize(400,1600)
|
||
|
local dragger = CreateFrame("Frame", nil, treeframe)
|
||
|
dragger:SetWidth(8)
|
||
|
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
|
||
|
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
|
||
|
dragger:SetBackdrop(DraggerBackdrop)
|
||
|
dragger:SetBackdropColor(1, 1, 1, 0)
|
||
|
dragger:SetScript("OnMouseDown", draggerDown)
|
||
|
dragger:SetScript("OnMouseUp", draggerUp)
|
||
|
dragger:SetScript("OnEnter", draggerEnter)
|
||
|
dragger:SetScript("OnLeave", draggerLeave)
|
||
|
|
||
|
self.dragger = dragger
|
||
|
self.treeframe = treeframe
|
||
|
self.OnRelease = OnRelease
|
||
|
self.OnAcquire = OnAcquire
|
||
|
|
||
|
self.SetTree = SetTree
|
||
|
self.SetTreeWidth = SetTreeWidth
|
||
|
self.RefreshTree = RefreshTree
|
||
|
self.SetStatusTable = SetStatusTable
|
||
|
self.BuildLevel = BuildLevel
|
||
|
self.CreateButton = CreateButton
|
||
|
self.SetSelected = SetSelected
|
||
|
self.ShowScroll = ShowScroll
|
||
|
self.SetStatusTable = SetStatusTable
|
||
|
self.Select = Select
|
||
|
self.SelectByValue = SelectByValue
|
||
|
self.SelectByPath = SelectByPath
|
||
|
self.OnWidthSet = OnWidthSet
|
||
|
self.OnHeightSet = OnHeightSet
|
||
|
self.EnableButtonTooltips = EnableButtonTooltips
|
||
|
--self.Filter = Filter
|
||
|
self.LayoutFinished = LayoutFinished
|
||
|
|
||
|
self.frame = frame
|
||
|
frame.obj = self
|
||
|
|
||
|
createdcount = createdcount + 1
|
||
|
local scrollbar = CreateFrame("Slider",("AceConfigDialogTreeGroup%dScrollBar"):format(createdcount),treeframe,"UIPanelScrollBarTemplate")
|
||
|
self.scrollbar = scrollbar
|
||
|
local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
|
||
|
scrollbg:SetAllPoints(scrollbar)
|
||
|
scrollbg:SetTexture(0,0,0,0.4)
|
||
|
scrollbar.obj = self
|
||
|
self.noupdate = true
|
||
|
scrollbar:SetPoint("TOPRIGHT",treeframe,"TOPRIGHT",-10,-26)
|
||
|
scrollbar:SetPoint("BOTTOMRIGHT",treeframe,"BOTTOMRIGHT",-10,26)
|
||
|
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
|
||
|
scrollbar:SetMinMaxValues(0,0)
|
||
|
self.localstatus.scrollvalue = 0
|
||
|
scrollbar:SetValueStep(1)
|
||
|
scrollbar:SetValue(0)
|
||
|
scrollbar:SetWidth(16)
|
||
|
self.noupdate = nil
|
||
|
|
||
|
local border = CreateFrame("Frame",nil,frame)
|
||
|
self.border = border
|
||
|
border:SetPoint("TOPLEFT",treeframe,"TOPRIGHT", 0,0)
|
||
|
border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
||
|
|
||
|
border:SetBackdrop(PaneBackdrop)
|
||
|
border:SetBackdropColor(0.1,0.1,0.1,0.5)
|
||
|
border:SetBackdropBorderColor(0.4,0.4,0.4)
|
||
|
|
||
|
--Container Support
|
||
|
local content = CreateFrame("Frame",nil,border)
|
||
|
self.content = content
|
||
|
content.obj = self
|
||
|
content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
|
||
|
content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
|
||
|
|
||
|
AceGUI:RegisterAsContainer(self)
|
||
|
--AceGUI:RegisterAsWidget(self)
|
||
|
return self
|
||
|
end
|
||
|
|
||
|
AceGUI:RegisterWidgetType(Type,Constructor,Version)
|
||
|
end
|