diff Libs/AceGUI-3.0/widgets/AceGUIWidget-TreeGroup.lua @ 0:169f5211fc7f

First public revision. At this point ItemAuditor watches mail for auctions sold or purchased, watches for buy/sell (money and 1 item type change) and conversions/tradeskills. Milling isn't working yet because there is too much time between the first event and the last event.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Thu, 20 May 2010 19:22:19 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/AceGUI-3.0/widgets/AceGUIWidget-TreeGroup.lua	Thu May 20 19:22:19 2010 -0700
@@ -0,0 +1,746 @@
+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