208 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-- ------------------------------------------------------------------------------ --
 | 
						|
--                                TradeSkillMaster                                --
 | 
						|
--                          https://tradeskillmaster.com                          --
 | 
						|
--    All Rights Reserved - Detailed license information included with addon.     --
 | 
						|
-- ------------------------------------------------------------------------------ --
 | 
						|
 | 
						|
--- Container UI Element Class.
 | 
						|
-- A container is an abstract element class which simply contains other elements. It is a subclass of the @{Element} class.
 | 
						|
-- @classmod Container
 | 
						|
 | 
						|
local _, TSM = ...
 | 
						|
local TempTable = TSM.Include("Util.TempTable")
 | 
						|
local Table = TSM.Include("Util.Table")
 | 
						|
local Container = TSM.Include("LibTSMClass").DefineClass("Container", TSM.UI.Element, "ABSTRACT")
 | 
						|
local UIElements = TSM.Include("UI.UIElements")
 | 
						|
UIElements.Register(Container)
 | 
						|
TSM.UI.Container = Container
 | 
						|
local private = {}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
-- ============================================================================
 | 
						|
-- Public Class Methods
 | 
						|
-- ============================================================================
 | 
						|
 | 
						|
function Container.__init(self, frame)
 | 
						|
	self.__super:__init(frame)
 | 
						|
 | 
						|
	self._children = {}
 | 
						|
	self._layoutChildren = {}
 | 
						|
	self._noLayoutChildren = {}
 | 
						|
end
 | 
						|
 | 
						|
function Container.Release(self)
 | 
						|
	self:ReleaseAllChildren()
 | 
						|
	self.__super:Release()
 | 
						|
end
 | 
						|
 | 
						|
--- Release all child elements.
 | 
						|
-- @tparam Container self The container object
 | 
						|
function Container.ReleaseAllChildren(self)
 | 
						|
	for _, child in ipairs(self._children) do
 | 
						|
		child:Release()
 | 
						|
	end
 | 
						|
	wipe(self._children)
 | 
						|
	wipe(self._layoutChildren)
 | 
						|
	wipe(self._noLayoutChildren)
 | 
						|
end
 | 
						|
 | 
						|
--- Add a child element.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam Element child The child element
 | 
						|
-- @treturn Container The container object
 | 
						|
function Container.AddChild(self, child)
 | 
						|
	self:_AddChildHelper(child, true)
 | 
						|
	return self
 | 
						|
end
 | 
						|
 | 
						|
--- Add a child element when the required condition is true.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam boolean condition The required condition
 | 
						|
-- @tparam Element child The child element
 | 
						|
-- @treturn Container The container object
 | 
						|
function Container.AddChildIf(self, condition, child)
 | 
						|
	if not condition then
 | 
						|
		child:Release()
 | 
						|
		return self
 | 
						|
	end
 | 
						|
	self:_AddChildHelper(child, true)
 | 
						|
	return self
 | 
						|
end
 | 
						|
 | 
						|
--- Add a child element before another one.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam string beforeId The id of the child element to add this one before
 | 
						|
-- @tparam Element child The child element
 | 
						|
-- @treturn Container The container object
 | 
						|
function Container.AddChildBeforeById(self, beforeId, child)
 | 
						|
	self:_AddChildHelper(child, true, beforeId)
 | 
						|
	return self
 | 
						|
end
 | 
						|
 | 
						|
--- Add child elements using a function.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam function func The function to call and pass this container object
 | 
						|
-- @tparam vararg ... Additional arguments to pass to the function
 | 
						|
-- @treturn Container The container object
 | 
						|
function Container.AddChildrenWithFunction(self, func, ...)
 | 
						|
	func(self, ...)
 | 
						|
	return self
 | 
						|
end
 | 
						|
 | 
						|
--- Add a child element which is not involved in layout.
 | 
						|
-- The layout of this child must be explicitly done by the application code.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam Element child The child element
 | 
						|
-- @treturn Container The container object
 | 
						|
function Container.AddChildNoLayout(self, child)
 | 
						|
	self:_AddChildHelper(child, false)
 | 
						|
	return self
 | 
						|
end
 | 
						|
 | 
						|
--- Remove a child element.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @tparam Element child The child element to remove
 | 
						|
function Container.RemoveChild(self, child)
 | 
						|
	assert(child:__isa(TSM.UI.Element) and child:_GetBaseFrame():GetParent())
 | 
						|
	child:_GetBaseFrame():SetParent(nil)
 | 
						|
	Table.RemoveByValue(self._children, child)
 | 
						|
	Table.RemoveByValue(self._layoutChildren, child)
 | 
						|
	Table.RemoveByValue(self._noLayoutChildren, child)
 | 
						|
	child:_SetParentElement(nil)
 | 
						|
end
 | 
						|
 | 
						|
function Container.HasChildById(self, childId)
 | 
						|
	for _, child in ipairs(self._children) do
 | 
						|
		if child._id == childId then
 | 
						|
			return true
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return false
 | 
						|
end
 | 
						|
 | 
						|
--- Gets the number of child elements involved in layout.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @treturn number The number of elements
 | 
						|
function Container.GetNumLayoutChildren(self)
 | 
						|
	local count = 0
 | 
						|
	for _ in self:LayoutChildrenIterator() do
 | 
						|
		count = count + 1
 | 
						|
	end
 | 
						|
	return count
 | 
						|
end
 | 
						|
 | 
						|
--- Iterates through the child elements involved in layout.
 | 
						|
-- @tparam Container self The container object
 | 
						|
-- @return An iterator with the following fields: `index, child`
 | 
						|
function Container.LayoutChildrenIterator(self)
 | 
						|
	local children = TempTable.Acquire()
 | 
						|
	for _, child in ipairs(self._layoutChildren) do
 | 
						|
		if child:IsVisible() then
 | 
						|
			tinsert(children, child)
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return TempTable.Iterator(children)
 | 
						|
end
 | 
						|
 | 
						|
--- Shows all child elements.
 | 
						|
-- @tparam Container self The container object
 | 
						|
function Container.ShowAllChildren(self)
 | 
						|
	for _, child in ipairs(self._layoutChildren) do
 | 
						|
		if not child:IsVisible() then
 | 
						|
			child:Show()
 | 
						|
		end
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
function Container.Draw(self)
 | 
						|
	self.__super:Draw()
 | 
						|
	for _, child in ipairs(self._children) do
 | 
						|
		child:Draw()
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
 | 
						|
-- ============================================================================
 | 
						|
-- Container - Private Class Methods
 | 
						|
-- ============================================================================
 | 
						|
 | 
						|
function Container._AddChildHelper(self, child, layout, beforeId)
 | 
						|
	assert(child:__isa(TSM.UI.Element) and not child:_GetBaseFrame():GetParent())
 | 
						|
	child:_GetBaseFrame():SetParent(self:_GetBaseFrame())
 | 
						|
	tinsert(self._children, private.GetElementInsertIndex(self._children, beforeId), child)
 | 
						|
	if layout then
 | 
						|
		tinsert(self._layoutChildren, private.GetElementInsertIndex(self._layoutChildren, beforeId), child)
 | 
						|
	else
 | 
						|
		tinsert(self._noLayoutChildren, private.GetElementInsertIndex(self._noLayoutChildren, beforeId), child)
 | 
						|
	end
 | 
						|
	child:_SetParentElement(self)
 | 
						|
	child:Show()
 | 
						|
end
 | 
						|
 | 
						|
function Container._ClearBaseElementCache(self)
 | 
						|
	self.__super:_ClearBaseElementCache()
 | 
						|
	for _, child in ipairs(self._children) do
 | 
						|
		child:_ClearBaseElementCache()
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
 | 
						|
-- ============================================================================
 | 
						|
-- Private Helper Functions
 | 
						|
-- ============================================================================
 | 
						|
 | 
						|
function private.GetElementInsertIndex(tbl, beforeId)
 | 
						|
	if not beforeId then
 | 
						|
		return #tbl + 1
 | 
						|
	end
 | 
						|
	for i, element in ipairs(tbl) do
 | 
						|
		if element._id == beforeId then
 | 
						|
			return i
 | 
						|
		end
 | 
						|
	end
 | 
						|
	error("Invalid beforeId: "..tostring(beforeId))
 | 
						|
end
 |