You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
5.1 KiB
187 lines
5.1 KiB
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- https://tradeskillmaster.com --
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
local TSM = select(2, ...) ---@type TSM
|
|
local NineSlice = TSM.Init("Util.NineSlice") ---@class Util.NineSlice
|
|
local NineSliceTexture = TSM.Include("LibTSMClass").DefineClass("NineSliceTexture") ---@class NineSliceTexture
|
|
local private = {
|
|
styles = {},
|
|
}
|
|
local PART_ANCHORS = {
|
|
topLeft = {
|
|
{ "TOPLEFT" },
|
|
},
|
|
bottomLeft = {
|
|
{ "BOTTOMLEFT" },
|
|
},
|
|
topRight = {
|
|
{ "TOPRIGHT" },
|
|
},
|
|
bottomRight = {
|
|
{ "BOTTOMRIGHT" },
|
|
},
|
|
left = {
|
|
{ "TOPLEFT", "topLeft", "BOTTOMLEFT" },
|
|
{ "BOTTOMLEFT", "bottomLeft", "TOPLEFT" },
|
|
},
|
|
right = {
|
|
{ "TOPRIGHT", "topRight", "BOTTOMRIGHT" },
|
|
{ "BOTTOMRIGHT", "bottomRight", "TOPRIGHT" },
|
|
},
|
|
top = {
|
|
{ "TOPLEFT", "topLeft", "TOPRIGHT" },
|
|
{ "TOPRIGHT", "topRight", "TOPLEFT" },
|
|
},
|
|
bottom = {
|
|
{ "BOTTOMLEFT", "bottomLeft", "BOTTOMRIGHT" },
|
|
{ "BOTTOMRIGHT", "bottomRight", "BOTTOMLEFT" },
|
|
},
|
|
center = {
|
|
{ "TOPLEFT", "topLeft", "BOTTOMRIGHT" },
|
|
{ "BOTTOMRIGHT", "bottomRight", "TOPLEFT" },
|
|
},
|
|
}
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Module Functions
|
|
-- ============================================================================
|
|
|
|
---Registers a nine-slice style.
|
|
---@param key string The style key
|
|
---@param info table The style info table
|
|
function NineSlice.RegisterStyle(key, info)
|
|
assert(not private.styles[key])
|
|
private.styles[key] = info
|
|
for part in pairs(PART_ANCHORS) do
|
|
-- allowed to be missing the center part
|
|
if part ~= "center" or info[part] ~= nil then
|
|
assert(type(info[part].texture) == "string")
|
|
assert(#info[part].coord == 4)
|
|
assert(info[part].width > 0)
|
|
assert(info[part].height > 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
---Create an nine-slice object.
|
|
---@param frame table The parent frame
|
|
---@param subLayer? number The texture subLayer
|
|
---@return NineSliceTexture @The nine-slice texture
|
|
function NineSlice.New(frame, subLayer)
|
|
return NineSliceTexture(frame, subLayer)
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- NineSliceTexture Class Methods
|
|
-- ============================================================================
|
|
|
|
function NineSliceTexture:__init(frame, subLayer)
|
|
self._frame = frame
|
|
self._parts = {}
|
|
self._styleKey = nil
|
|
|
|
-- create all the textures
|
|
for part in pairs(PART_ANCHORS) do
|
|
local texture = frame:CreateTexture(nil, "BACKGROUND", nil, subLayer or 0)
|
|
texture:SetBlendMode("BLEND")
|
|
self._parts[part] = texture
|
|
end
|
|
|
|
-- set the points for all the textures
|
|
for part, info in pairs(PART_ANCHORS) do
|
|
for _, point in ipairs(info) do
|
|
if #point == 1 then
|
|
self._parts[part]:SetPoint(unpack(point))
|
|
elseif #point == 3 then
|
|
local anchor, relFrame, relAnchor = unpack(point)
|
|
relFrame = self._parts[relFrame]
|
|
assert(relFrame)
|
|
self._parts[part]:SetPoint(anchor, relFrame, relAnchor)
|
|
else
|
|
error("Invalid point")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---Hides the nine-slice
|
|
function NineSliceTexture:Hide()
|
|
for _, texture in pairs(self._parts) do
|
|
texture:Hide()
|
|
end
|
|
end
|
|
|
|
---Sets the style key.
|
|
---@param key string The style key
|
|
function NineSliceTexture:SetStyle(key)
|
|
local style = private.styles[key]
|
|
for part, texture in pairs(self._parts) do
|
|
local partStyle = style[part]
|
|
if partStyle then
|
|
texture:Show()
|
|
else
|
|
texture:Hide()
|
|
end
|
|
end
|
|
if self._styleKey == key then
|
|
return
|
|
end
|
|
self._styleKey = key
|
|
for part, texture in pairs(self._parts) do
|
|
local partStyle = style[part]
|
|
if partStyle then
|
|
texture:ClearAllPoints()
|
|
for i, point in ipairs(PART_ANCHORS[part]) do
|
|
local anchor, relFrame, relAnchor, xOff, yOff = nil, nil, nil, 0, 0
|
|
if partStyle.offset then
|
|
xOff, yOff = unpack(partStyle.offset[i])
|
|
end
|
|
if #point == 1 then
|
|
anchor = unpack(point)
|
|
elseif #point == 3 then
|
|
anchor, relFrame, relAnchor = unpack(point)
|
|
relFrame = self._parts[relFrame]
|
|
assert(relFrame)
|
|
else
|
|
error("Invalid point")
|
|
end
|
|
if relFrame then
|
|
texture:SetPoint(anchor, relFrame, relAnchor, xOff, yOff)
|
|
else
|
|
texture:SetPoint(anchor, xOff, yOff)
|
|
end
|
|
end
|
|
texture:SetSize(partStyle.width, partStyle.height)
|
|
texture:SetTexture(partStyle.texture)
|
|
texture:SetTexCoord(unpack(partStyle.coord))
|
|
end
|
|
end
|
|
end
|
|
|
|
---Sets the vertex color as a 0 to 1 RGBA value.
|
|
---@param r number
|
|
---@param g number
|
|
---@param b number
|
|
---@param a number
|
|
function NineSliceTexture:SetVertexColor(r, g, b, a)
|
|
for part in pairs(PART_ANCHORS) do
|
|
self:SetPartVertexColor(part, r, g, b, a)
|
|
end
|
|
end
|
|
|
|
---Sets the vertex color of a single part as a 0 to 1 RGBA value.
|
|
---@param part string
|
|
---@param r number
|
|
---@param g number
|
|
---@param b number
|
|
---@param a number
|
|
function NineSliceTexture:SetPartVertexColor(part, r, g, b, a)
|
|
self._parts[part]:SetVertexColor(r, g, b, a)
|
|
end
|
|
|