Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: TreeGroup Container Tercio@23: Container that uses a tree control to switch between groups. Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local Type, Version = "TreeGroup", 37 Tercio@23: local AceGUI = LibStub and LibStub("AceGUI-3.0", true) Tercio@23: if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end Tercio@23: Tercio@23: -- Lua APIs Tercio@23: local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type Tercio@23: local math_min, math_max, floor = math.min, math.max, floor Tercio@23: local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat Tercio@23: Tercio@23: -- WoW APIs Tercio@23: local CreateFrame, UIParent = CreateFrame, UIParent Tercio@23: Tercio@23: -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded Tercio@23: -- List them here for Mikk's FindGlobals script Tercio@23: -- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE Tercio@23: Tercio@23: -- Recycling functions Tercio@23: local new, del Tercio@23: do Tercio@23: local pool = setmetatable({},{__mode='k'}) Tercio@23: function new() Tercio@23: local t = next(pool) Tercio@23: if t then Tercio@23: pool[t] = nil Tercio@23: return t Tercio@23: else Tercio@23: return {} Tercio@23: end Tercio@23: end Tercio@23: function del(t) Tercio@23: for k in pairs(t) do Tercio@23: t[k] = nil Tercio@23: end Tercio@23: pool[t] = true Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local DEFAULT_TREE_WIDTH = 175 Tercio@23: local DEFAULT_TREE_SIZABLE = true Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Support functions Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local function GetButtonUniqueValue(line) Tercio@23: local parent = line.parent Tercio@23: if parent and parent.value then Tercio@23: return GetButtonUniqueValue(parent).."\001"..line.value Tercio@23: else Tercio@23: return line.value Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function UpdateButton(button, treeline, selected, canExpand, isExpanded) Tercio@23: local self = button.obj Tercio@23: local toggle = button.toggle Tercio@23: local frame = self.frame Tercio@23: local text = treeline.text or "" Tercio@23: local icon = treeline.icon Tercio@23: local iconCoords = treeline.iconCoords Tercio@23: local level = treeline.level Tercio@23: local value = treeline.value Tercio@23: local uniquevalue = treeline.uniquevalue Tercio@23: local disabled = treeline.disabled Tercio@23: Tercio@23: button.treeline = treeline Tercio@23: button.value = value Tercio@23: button.uniquevalue = uniquevalue Tercio@23: if selected then Tercio@23: button:LockHighlight() Tercio@23: button.selected = true Tercio@23: else Tercio@23: button:UnlockHighlight() Tercio@23: button.selected = false Tercio@23: end Tercio@23: local normalTexture = button:GetNormalTexture() Tercio@23: local line = button.line Tercio@23: button.level = level Tercio@23: if ( level == 1 ) then Tercio@23: button:SetNormalFontObject("GameFontNormal") Tercio@23: button:SetHighlightFontObject("GameFontHighlight") Tercio@23: button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2) Tercio@23: else Tercio@23: button:SetNormalFontObject("GameFontHighlightSmall") Tercio@23: button:SetHighlightFontObject("GameFontHighlightSmall") Tercio@23: button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2) Tercio@23: end Tercio@23: Tercio@23: if disabled then Tercio@23: button:EnableMouse(false) Tercio@23: button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE) Tercio@23: else Tercio@23: button.text:SetText(text) Tercio@23: button:EnableMouse(true) Tercio@23: end Tercio@23: Tercio@23: if icon then Tercio@23: button.icon:SetTexture(icon) Tercio@23: button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1) Tercio@23: else Tercio@23: button.icon:SetTexture(nil) Tercio@23: end Tercio@23: Tercio@23: if iconCoords then Tercio@23: button.icon:SetTexCoord(unpack(iconCoords)) Tercio@23: else Tercio@23: button.icon:SetTexCoord(0, 1, 0, 1) Tercio@23: end Tercio@23: Tercio@23: if canExpand then Tercio@23: if not isExpanded then Tercio@23: toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP") Tercio@23: toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN") Tercio@23: else Tercio@23: toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP") Tercio@23: toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN") Tercio@23: end Tercio@23: toggle:Show() Tercio@23: else Tercio@23: toggle:Hide() Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function ShouldDisplayLevel(tree) Tercio@23: local result = false Tercio@23: for k, v in ipairs(tree) do Tercio@23: if v.children == nil and v.visible ~= false then Tercio@23: result = true Tercio@23: elseif v.children then Tercio@23: result = result or ShouldDisplayLevel(v.children) Tercio@23: end Tercio@23: if result then return result end Tercio@23: end Tercio@23: return false Tercio@23: end Tercio@23: Tercio@23: local function addLine(self, v, tree, level, parent) Tercio@23: local line = new() Tercio@23: line.value = v.value Tercio@23: line.text = v.text Tercio@23: line.icon = v.icon Tercio@23: line.iconCoords = v.iconCoords Tercio@23: line.disabled = v.disabled Tercio@23: line.tree = tree Tercio@23: line.level = level Tercio@23: line.parent = parent Tercio@23: line.visible = v.visible Tercio@23: line.uniquevalue = GetButtonUniqueValue(line) Tercio@23: if v.children then Tercio@23: line.hasChildren = true Tercio@23: else Tercio@23: line.hasChildren = nil Tercio@23: end Tercio@23: self.lines[#self.lines+1] = line Tercio@23: return line Tercio@23: end Tercio@23: Tercio@23: --fire an update after one frame to catch the treeframes height Tercio@23: local function FirstFrameUpdate(frame) Tercio@23: local self = frame.obj Tercio@23: frame:SetScript("OnUpdate", nil) Tercio@23: self:RefreshTree() Tercio@23: end Tercio@23: Tercio@23: local function BuildUniqueValue(...) Tercio@23: local n = select('#', ...) Tercio@23: if n == 1 then Tercio@23: return ... Tercio@23: else Tercio@23: return (...).."\001"..BuildUniqueValue(select(2,...)) Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Scripts Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local function Expand_OnClick(frame) Tercio@23: local button = frame.button Tercio@23: local self = button.obj Tercio@23: local status = (self.status or self.localstatus).groups Tercio@23: status[button.uniquevalue] = not status[button.uniquevalue] Tercio@23: self:RefreshTree() Tercio@23: end Tercio@23: Tercio@23: local function Button_OnClick(frame) Tercio@23: local self = frame.obj Tercio@23: self:Fire("OnClick", frame.uniquevalue, frame.selected) Tercio@23: if not frame.selected then Tercio@23: self:SetSelected(frame.uniquevalue) Tercio@23: frame.selected = true Tercio@23: frame:LockHighlight() Tercio@23: self:RefreshTree() Tercio@23: end Tercio@23: AceGUI:ClearFocus() Tercio@23: end Tercio@23: Tercio@23: local function Button_OnDoubleClick(button) Tercio@23: local self = button.obj Tercio@23: local status = self.status or self.localstatus Tercio@23: local status = (self.status or self.localstatus).groups Tercio@23: status[button.uniquevalue] = not status[button.uniquevalue] Tercio@23: self:RefreshTree() Tercio@23: end Tercio@23: Tercio@23: local function Button_OnEnter(frame) Tercio@23: local self = frame.obj Tercio@23: self:Fire("OnButtonEnter", frame.uniquevalue, frame) Tercio@23: Tercio@23: if self.enabletooltips then Tercio@23: GameTooltip:SetOwner(frame, "ANCHOR_NONE") Tercio@23: GameTooltip:SetPoint("LEFT",frame,"RIGHT") Tercio@23: GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, true) Tercio@23: Tercio@23: GameTooltip:Show() Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function Button_OnLeave(frame) Tercio@23: local self = frame.obj Tercio@23: self:Fire("OnButtonLeave", frame.uniquevalue, frame) Tercio@23: Tercio@23: if self.enabletooltips then Tercio@23: GameTooltip:Hide() Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function OnScrollValueChanged(frame, value) Tercio@23: if frame.obj.noupdate then return end Tercio@23: local self = frame.obj Tercio@23: local status = self.status or self.localstatus Tercio@23: status.scrollvalue = floor(value + 0.5) Tercio@23: self:RefreshTree() Tercio@23: AceGUI:ClearFocus() Tercio@23: end Tercio@23: Tercio@23: local function Tree_OnSizeChanged(frame) Tercio@23: frame.obj:RefreshTree() Tercio@23: end Tercio@23: Tercio@23: local function Tree_OnMouseWheel(frame, delta) Tercio@23: local self = frame.obj Tercio@23: if self.showscroll then Tercio@23: local scrollbar = self.scrollbar Tercio@23: local min, max = scrollbar:GetMinMaxValues() Tercio@23: local value = scrollbar:GetValue() Tercio@23: local newvalue = math_min(max,math_max(min,value - delta)) Tercio@23: if value ~= newvalue then Tercio@23: scrollbar:SetValue(newvalue) Tercio@23: end Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function Dragger_OnLeave(frame) Tercio@23: frame:SetBackdropColor(1, 1, 1, 0) Tercio@23: end Tercio@23: Tercio@23: local function Dragger_OnEnter(frame) Tercio@23: frame:SetBackdropColor(1, 1, 1, 0.8) Tercio@23: end Tercio@23: Tercio@23: local function Dragger_OnMouseDown(frame) Tercio@23: local treeframe = frame:GetParent() Tercio@23: treeframe:StartSizing("RIGHT") Tercio@23: end Tercio@23: Tercio@23: local function Dragger_OnMouseUp(frame) Tercio@23: local treeframe = frame:GetParent() Tercio@23: local self = treeframe.obj Tercio@23: local frame = treeframe:GetParent() Tercio@23: treeframe:StopMovingOrSizing() Tercio@23: --treeframe:SetScript("OnUpdate", nil) Tercio@23: treeframe:SetUserPlaced(false) Tercio@23: --Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize Tercio@23: treeframe:SetHeight(0) Tercio@23: treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0) Tercio@23: treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0) Tercio@23: Tercio@23: local status = self.status or self.localstatus Tercio@23: status.treewidth = treeframe:GetWidth() Tercio@23: Tercio@23: treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth()) Tercio@23: -- recalculate the content width Tercio@23: treeframe.obj:OnWidthSet(status.fullwidth) Tercio@23: -- update the layout of the content Tercio@23: treeframe.obj:DoLayout() Tercio@23: end Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Methods Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local methods = { Tercio@23: ["OnAcquire"] = function(self) Tercio@23: self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE) Tercio@23: self:EnableButtonTooltips(true) Tercio@23: end, Tercio@23: Tercio@23: ["OnRelease"] = function(self) Tercio@23: self.status = nil Tercio@23: for k, v in pairs(self.localstatus) do Tercio@23: if k == "groups" then Tercio@23: for k2 in pairs(v) do Tercio@23: v[k2] = nil Tercio@23: end Tercio@23: else Tercio@23: self.localstatus[k] = nil Tercio@23: end Tercio@23: end Tercio@23: self.localstatus.scrollvalue = 0 Tercio@23: self.localstatus.treewidth = DEFAULT_TREE_WIDTH Tercio@23: self.localstatus.treesizable = DEFAULT_TREE_SIZABLE Tercio@23: end, Tercio@23: Tercio@23: ["EnableButtonTooltips"] = function(self, enable) Tercio@23: self.enabletooltips = enable Tercio@23: end, Tercio@23: Tercio@23: ["CreateButton"] = function(self) Tercio@23: local num = AceGUI:GetNextWidgetNum("TreeGroupButton") Tercio@23: local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate") Tercio@23: button.obj = self Tercio@23: Tercio@23: local icon = button:CreateTexture(nil, "OVERLAY") Tercio@23: icon:SetWidth(14) Tercio@23: icon:SetHeight(14) Tercio@23: button.icon = icon Tercio@23: Tercio@23: button:SetScript("OnClick",Button_OnClick) Tercio@23: button:SetScript("OnDoubleClick", Button_OnDoubleClick) Tercio@23: button:SetScript("OnEnter",Button_OnEnter) Tercio@23: button:SetScript("OnLeave",Button_OnLeave) Tercio@23: Tercio@23: button.toggle.button = button Tercio@23: button.toggle:SetScript("OnClick",Expand_OnClick) Tercio@23: Tercio@23: return button Tercio@23: end, Tercio@23: Tercio@23: ["SetStatusTable"] = function(self, status) Tercio@23: assert(type(status) == "table") Tercio@23: self.status = status Tercio@23: if not status.groups then Tercio@23: status.groups = {} Tercio@23: end Tercio@23: if not status.scrollvalue then Tercio@23: status.scrollvalue = 0 Tercio@23: end Tercio@23: if not status.treewidth then Tercio@23: status.treewidth = DEFAULT_TREE_WIDTH Tercio@23: end Tercio@23: if status.treesizable == nil then Tercio@23: status.treesizable = DEFAULT_TREE_SIZABLE Tercio@23: end Tercio@23: self:SetTreeWidth(status.treewidth,status.treesizable) Tercio@23: self:RefreshTree() Tercio@23: end, Tercio@23: Tercio@23: --sets the tree to be displayed Tercio@23: ["SetTree"] = function(self, tree, filter) Tercio@23: self.filter = filter Tercio@23: if tree then Tercio@23: assert(type(tree) == "table") Tercio@23: end Tercio@23: self.tree = tree Tercio@23: self:RefreshTree() Tercio@23: end, Tercio@23: Tercio@23: ["BuildLevel"] = function(self, tree, level, parent) Tercio@23: local groups = (self.status or self.localstatus).groups Tercio@23: local hasChildren = self.hasChildren Tercio@23: Tercio@23: for i, v in ipairs(tree) do Tercio@23: if v.children then Tercio@23: if not self.filter or ShouldDisplayLevel(v.children) then Tercio@23: local line = addLine(self, v, tree, level, parent) Tercio@23: if groups[line.uniquevalue] then Tercio@23: self:BuildLevel(v.children, level+1, line) Tercio@23: end Tercio@23: end Tercio@23: elseif v.visible ~= false or not self.filter then Tercio@23: addLine(self, v, tree, level, parent) Tercio@23: end Tercio@23: end Tercio@23: end, Tercio@23: Tercio@23: ["RefreshTree"] = function(self,scrollToSelection) Tercio@23: local buttons = self.buttons Tercio@23: local lines = self.lines Tercio@23: Tercio@23: for i, v in ipairs(buttons) do Tercio@23: v:Hide() Tercio@23: end Tercio@23: while lines[1] do Tercio@23: local t = tremove(lines) Tercio@23: for k in pairs(t) do Tercio@23: t[k] = nil Tercio@23: end Tercio@23: del(t) Tercio@23: end Tercio@23: Tercio@23: if not self.tree then return end Tercio@23: --Build the list of visible entries from the tree and status tables Tercio@23: local status = self.status or self.localstatus Tercio@23: local groupstatus = status.groups Tercio@23: local tree = self.tree Tercio@23: Tercio@23: local treeframe = self.treeframe Tercio@23: Tercio@23: status.scrollToSelection = status.scrollToSelection or scrollToSelection -- needs to be cached in case the control hasn't been drawn yet (code bails out below) Tercio@23: Tercio@23: self:BuildLevel(tree, 1) Tercio@23: Tercio@23: local numlines = #lines Tercio@23: Tercio@23: local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18)) Tercio@23: if maxlines <= 0 then return end Tercio@23: Tercio@23: local first, last Tercio@23: Tercio@23: scrollToSelection = status.scrollToSelection Tercio@23: status.scrollToSelection = nil Tercio@23: Tercio@23: if numlines <= maxlines then Tercio@23: --the whole tree fits in the frame Tercio@23: status.scrollvalue = 0 Tercio@23: self:ShowScroll(false) Tercio@23: first, last = 1, numlines Tercio@23: else Tercio@23: self:ShowScroll(true) Tercio@23: --scrolling will be needed Tercio@23: self.noupdate = true Tercio@23: self.scrollbar:SetMinMaxValues(0, numlines - maxlines) Tercio@23: --check if we are scrolled down too far Tercio@23: if numlines - status.scrollvalue < maxlines then Tercio@23: status.scrollvalue = numlines - maxlines Tercio@23: end Tercio@23: self.noupdate = nil Tercio@23: first, last = status.scrollvalue+1, status.scrollvalue + maxlines Tercio@23: --show selection? Tercio@23: if scrollToSelection and status.selected then Tercio@23: local show Tercio@23: for i,line in ipairs(lines) do -- find the line number Tercio@23: if line.uniquevalue==status.selected then Tercio@23: show=i Tercio@23: end Tercio@23: end Tercio@23: if not show then Tercio@23: -- selection was deleted or something? Tercio@23: elseif show>=first and show<=last then Tercio@23: -- all good Tercio@23: else Tercio@23: -- scrolling needed! Tercio@23: if show 100 and status.treewidth > maxtreewidth then Tercio@23: self:SetTreeWidth(maxtreewidth, status.treesizable) Tercio@23: end Tercio@23: treeframe:SetMaxResize(maxtreewidth, 1600) Tercio@23: end, Tercio@23: Tercio@23: ["OnHeightSet"] = function(self, height) Tercio@23: local content = self.content Tercio@23: local contentheight = height - 20 Tercio@23: if contentheight < 0 then Tercio@23: contentheight = 0 Tercio@23: end Tercio@23: content:SetHeight(contentheight) Tercio@23: content.height = contentheight Tercio@23: end, Tercio@23: Tercio@23: ["SetTreeWidth"] = function(self, treewidth, resizable) Tercio@23: if not resizable then Tercio@23: if type(treewidth) == 'number' then Tercio@23: resizable = false Tercio@23: elseif type(treewidth) == 'boolean' then Tercio@23: resizable = treewidth Tercio@23: treewidth = DEFAULT_TREE_WIDTH Tercio@23: else Tercio@23: resizable = false Tercio@23: treewidth = DEFAULT_TREE_WIDTH Tercio@23: end Tercio@23: end Tercio@23: self.treeframe:SetWidth(treewidth) Tercio@23: self.dragger:EnableMouse(resizable) Tercio@23: Tercio@23: local status = self.status or self.localstatus Tercio@23: status.treewidth = treewidth Tercio@23: status.treesizable = resizable Tercio@23: Tercio@23: -- recalculate the content width Tercio@23: if status.fullwidth then Tercio@23: self:OnWidthSet(status.fullwidth) Tercio@23: end Tercio@23: end, Tercio@23: Tercio@23: ["GetTreeWidth"] = function(self) Tercio@23: local status = self.status or self.localstatus Tercio@23: return status.treewidth or DEFAULT_TREE_WIDTH Tercio@23: end, Tercio@23: Tercio@23: ["LayoutFinished"] = function(self, width, height) Tercio@23: if self.noAutoHeight then return end Tercio@23: self:SetHeight((height or 0) + 20) Tercio@23: end Tercio@23: } Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Constructor Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local PaneBackdrop = { Tercio@23: bgFile = "Interface\\ChatFrame\\ChatFrameBackground", Tercio@23: edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", Tercio@23: tile = true, tileSize = 16, edgeSize = 16, Tercio@23: insets = { left = 3, right = 3, top = 5, bottom = 3 } Tercio@23: } Tercio@23: Tercio@23: local DraggerBackdrop = { Tercio@23: bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", Tercio@23: edgeFile = nil, Tercio@23: tile = true, tileSize = 16, edgeSize = 0, Tercio@23: insets = { left = 3, right = 3, top = 7, bottom = 7 } Tercio@23: } Tercio@23: Tercio@23: local function Constructor() Tercio@23: local num = AceGUI:GetNextWidgetNum(Type) Tercio@23: local frame = CreateFrame("Frame", nil, UIParent) Tercio@23: Tercio@23: local treeframe = CreateFrame("Frame", nil, frame) Tercio@23: treeframe:SetPoint("TOPLEFT") Tercio@23: treeframe:SetPoint("BOTTOMLEFT") Tercio@23: treeframe:SetWidth(DEFAULT_TREE_WIDTH) Tercio@23: treeframe:EnableMouseWheel(true) Tercio@23: treeframe:SetBackdrop(PaneBackdrop) Tercio@23: treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5) Tercio@23: treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4) Tercio@23: treeframe:SetResizable(true) Tercio@23: treeframe:SetMinResize(100, 1) Tercio@23: treeframe:SetMaxResize(400, 1600) Tercio@23: treeframe:SetScript("OnUpdate", FirstFrameUpdate) Tercio@23: treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged) Tercio@23: treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel) Tercio@23: Tercio@23: local dragger = CreateFrame("Frame", nil, treeframe) Tercio@23: dragger:SetWidth(8) Tercio@23: dragger:SetPoint("TOP", treeframe, "TOPRIGHT") Tercio@23: dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT") Tercio@23: dragger:SetBackdrop(DraggerBackdrop) Tercio@23: dragger:SetBackdropColor(1, 1, 1, 0) Tercio@23: dragger:SetScript("OnEnter", Dragger_OnEnter) Tercio@23: dragger:SetScript("OnLeave", Dragger_OnLeave) Tercio@23: dragger:SetScript("OnMouseDown", Dragger_OnMouseDown) Tercio@23: dragger:SetScript("OnMouseUp", Dragger_OnMouseUp) Tercio@23: Tercio@23: local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate") Tercio@23: scrollbar:SetScript("OnValueChanged", nil) Tercio@23: scrollbar:SetPoint("TOPRIGHT", -10, -26) Tercio@23: scrollbar:SetPoint("BOTTOMRIGHT", -10, 26) Tercio@23: scrollbar:SetMinMaxValues(0,0) Tercio@23: scrollbar:SetValueStep(1) Tercio@23: scrollbar:SetValue(0) Tercio@23: scrollbar:SetWidth(16) Tercio@23: scrollbar:SetScript("OnValueChanged", OnScrollValueChanged) Tercio@23: Tercio@23: local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") Tercio@23: scrollbg:SetAllPoints(scrollbar) Tercio@23: scrollbg:SetTexture(0,0,0,0.4) Tercio@23: Tercio@23: local border = CreateFrame("Frame",nil,frame) Tercio@23: border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT") Tercio@23: border:SetPoint("BOTTOMRIGHT") Tercio@23: border:SetBackdrop(PaneBackdrop) Tercio@23: border:SetBackdropColor(0.1, 0.1, 0.1, 0.5) Tercio@23: border:SetBackdropBorderColor(0.4, 0.4, 0.4) Tercio@23: Tercio@23: --Container Support Tercio@23: local content = CreateFrame("Frame", nil, border) Tercio@23: content:SetPoint("TOPLEFT", 10, -10) Tercio@23: content:SetPoint("BOTTOMRIGHT", -10, 10) Tercio@23: Tercio@23: local widget = { Tercio@23: frame = frame, Tercio@23: lines = {}, Tercio@23: levels = {}, Tercio@23: buttons = {}, Tercio@23: hasChildren = {}, Tercio@23: localstatus = { groups = {}, scrollvalue = 0 }, Tercio@23: filter = false, Tercio@23: treeframe = treeframe, Tercio@23: dragger = dragger, Tercio@23: scrollbar = scrollbar, Tercio@23: border = border, Tercio@23: content = content, Tercio@23: type = Type Tercio@23: } Tercio@23: for method, func in pairs(methods) do Tercio@23: widget[method] = func Tercio@23: end Tercio@23: treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget Tercio@23: Tercio@23: return AceGUI:RegisterAsContainer(widget) Tercio@23: end Tercio@23: Tercio@23: AceGUI:RegisterWidgetType(Type, Constructor, Version)