initial commit
This commit is contained in:
238
Core/UI/Elements/ViewContainer.lua
Normal file
238
Core/UI/Elements/ViewContainer.lua
Normal file
@@ -0,0 +1,238 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
--- ViewContainer UI Element Class.
|
||||
-- A view container allows the content to be changed depending on the selected view (called the path). It is a subclass of the @{Container} class.
|
||||
-- @classmod ViewContainer
|
||||
|
||||
local _, TSM = ...
|
||||
local ViewContainer = TSM.Include("LibTSMClass").DefineClass("ViewContainer", TSM.UI.Container)
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
UIElements.Register(ViewContainer)
|
||||
TSM.UI.ViewContainer = ViewContainer
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Public Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function ViewContainer.__init(self)
|
||||
local frame = UIElements.CreateFrame(self, "Frame")
|
||||
self.__super:__init(frame)
|
||||
self._pathsList = {}
|
||||
self._contextTable = nil
|
||||
self._defaultContextTable = nil
|
||||
end
|
||||
|
||||
function ViewContainer.Acquire(self)
|
||||
self._path = nil
|
||||
self._navCallback = nil
|
||||
self.__super:Acquire()
|
||||
end
|
||||
|
||||
function ViewContainer.Release(self)
|
||||
wipe(self._pathsList)
|
||||
self.__super:Release()
|
||||
self._contextTable = nil
|
||||
self._defaultContextTable = nil
|
||||
end
|
||||
|
||||
function ViewContainer.SetLayout(self, layout)
|
||||
error("ViewContainer doesn't support this method")
|
||||
end
|
||||
|
||||
function ViewContainer.AddChild(self, child)
|
||||
error("ViewContainer doesn't support this method")
|
||||
end
|
||||
|
||||
function ViewContainer.AddChildNoLayout(self, child)
|
||||
error("ViewContainer doesn't support this method")
|
||||
end
|
||||
|
||||
--- Set the navigation callback.
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam function callback The function called when the selected path changes to get the new content
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.SetNavCallback(self, callback)
|
||||
self._navCallback = callback
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a path (view).
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam string path The path
|
||||
-- @tparam[opt=false] boolean setSelected Set this as the selected path (view)
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.AddPath(self, path, setSelected)
|
||||
tinsert(self._pathsList, path)
|
||||
if self._contextTable then
|
||||
assert(setSelected == nil, "Cannot set selected path when using a context table")
|
||||
local newPathIndex = Table.KeyByValue(self._pathsList, path)
|
||||
if self._contextTable.pathIndex == newPathIndex then
|
||||
self:SetPath(path)
|
||||
end
|
||||
elseif setSelected then
|
||||
self:SetPath(path)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Renames a path (view).
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam string path The new path
|
||||
-- @tparam number index The index of the path to change
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.RenamePath(self, path, index)
|
||||
local changePath = self._pathsList[index] == self._path
|
||||
self._pathsList[index] = path
|
||||
|
||||
if changePath then
|
||||
self:SetPath(path)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the selected path (view).
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam string path The selected path
|
||||
-- @tparam boolean redraw Whether or not to redraw the view container
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.SetPath(self, path, redraw)
|
||||
if path ~= self._path then
|
||||
local child = self:_GetChild()
|
||||
if child then
|
||||
assert(#self._layoutChildren == 1)
|
||||
self:RemoveChild(child)
|
||||
child:Release()
|
||||
end
|
||||
self.__super:AddChild(self:_navCallback(path))
|
||||
self._path = path
|
||||
-- Save the path index of the new selected path to the context table
|
||||
if self._contextTable then
|
||||
self._contextTable.pathIndex = Table.KeyByValue(self._pathsList, path)
|
||||
end
|
||||
end
|
||||
if redraw then
|
||||
self:Draw()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Reload the current view.
|
||||
-- @tparam ViewContainer self The view container object
|
||||
function ViewContainer.ReloadContent(self)
|
||||
local path = self._path
|
||||
self._path = nil
|
||||
self:SetPath(path, true)
|
||||
end
|
||||
|
||||
--- Get the current path (view).
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @treturn string The current path
|
||||
function ViewContainer.GetPath(self)
|
||||
return self._path
|
||||
end
|
||||
|
||||
--- Get a list of the paths for the view container.
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @treturn table The path list
|
||||
function ViewContainer.GetPathList(self)
|
||||
return self._pathsList
|
||||
end
|
||||
|
||||
function ViewContainer.Draw(self)
|
||||
self.__super.__super:Draw()
|
||||
local child = self:_GetChild()
|
||||
local childFrame = child:_GetBaseFrame()
|
||||
|
||||
-- set the child to be full-size
|
||||
childFrame:ClearAllPoints()
|
||||
local xOffset, yOffset = child:_GetMarginAnchorOffsets("BOTTOMLEFT")
|
||||
local paddingXOffset, paddingYOffset = self:_GetPaddingAnchorOffsets("BOTTOMLEFT")
|
||||
xOffset = xOffset + paddingXOffset - self:_GetContentPadding("LEFT")
|
||||
yOffset = yOffset + paddingYOffset - self:_GetContentPadding("BOTTOM")
|
||||
childFrame:SetPoint("BOTTOMLEFT", xOffset, yOffset)
|
||||
xOffset, yOffset = child:_GetMarginAnchorOffsets("TOPRIGHT")
|
||||
paddingXOffset, paddingYOffset = self:_GetPaddingAnchorOffsets("TOPRIGHT")
|
||||
xOffset = xOffset + paddingXOffset - self:_GetContentPadding("RIGHT")
|
||||
yOffset = yOffset + paddingYOffset - self:_GetContentPadding("TOP")
|
||||
childFrame:SetPoint("TOPRIGHT", xOffset, yOffset)
|
||||
child:Draw()
|
||||
|
||||
-- draw the no-layout children
|
||||
for _, noLayoutChild in ipairs(self._noLayoutChildren) do
|
||||
noLayoutChild:Draw()
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets the context table.
|
||||
-- This table can be used to save which tab is active, refrenced by the path index
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam table tbl The context table
|
||||
-- @tparam table defaultTbl Default values
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.SetContextTable(self, tbl, defaultTbl)
|
||||
assert(defaultTbl.pathIndex ~= nil)
|
||||
tbl.pathIndex = tbl.pathIndex or defaultTbl.pathIndex
|
||||
self._contextTable = tbl
|
||||
self._defaultContextTable = defaultTbl
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the context table from a settings object.
|
||||
-- @tparam ViewContainer self The view container object
|
||||
-- @tparam Settings settings The settings object
|
||||
-- @tparam string key The setting key
|
||||
-- @treturn ViewContainer The view container object
|
||||
function ViewContainer.SetSettingsContext(self, settings, key)
|
||||
return self:SetContextTable(settings[key], settings:GetDefaultReadOnly(key))
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function ViewContainer._GetMinimumDimension(self, dimension)
|
||||
if dimension == "WIDTH" then
|
||||
local width = self._width
|
||||
if width then
|
||||
return width, false
|
||||
else
|
||||
return self:_GetChild():_GetMinimumDimension(dimension)
|
||||
end
|
||||
elseif dimension == "HEIGHT" then
|
||||
local height = self._height
|
||||
if height then
|
||||
return height, false
|
||||
else
|
||||
return self:_GetChild():_GetMinimumDimension(dimension)
|
||||
end
|
||||
else
|
||||
error("Invalid dimension: "..tostring(dimension))
|
||||
end
|
||||
end
|
||||
|
||||
function ViewContainer._GetContentPadding(self, side)
|
||||
if side == "TOP" then
|
||||
return 0
|
||||
elseif side == "BOTTOM" then
|
||||
return 0
|
||||
elseif side == "LEFT" then
|
||||
return 0
|
||||
elseif side == "RIGHT" then
|
||||
return 0
|
||||
else
|
||||
error("Invalid side: "..tostring(side))
|
||||
end
|
||||
end
|
||||
|
||||
function ViewContainer._GetChild(self)
|
||||
return self._layoutChildren[1]
|
||||
end
|
||||
Reference in New Issue
Block a user