239 lines
7.5 KiB
Lua
239 lines
7.5 KiB
Lua
-- ------------------------------------------------------------------------------ --
|
|
-- 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
|