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.
227 lines
7.9 KiB
227 lines
7.9 KiB
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- https://tradeskillmaster.com --
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
local TSM = select(2, ...) ---@type TSM
|
|
local TextureAtlas = TSM.Init("Util.TextureAtlas") ---@class Util.TextureAtlas
|
|
local Color = TSM.Include("Util.Color")
|
|
local Theme = TSM.Include("Util.Theme")
|
|
local private = {
|
|
files = {},
|
|
}
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Module Functions
|
|
-- ============================================================================
|
|
|
|
---Adds textures from a texture pack file.
|
|
---@param key string The key for the file
|
|
---@param info table The table describing the textures within the file
|
|
function TextureAtlas.RegisterFile(key, info)
|
|
assert(type(key) == "string" and type(info) == "table")
|
|
assert(not private.files[key])
|
|
private.files[key] = info
|
|
end
|
|
|
|
---Extracts registered file info.
|
|
---@param key string The key for the file
|
|
---@return table @The file info
|
|
function TextureAtlas.ExtractFileInfo(key)
|
|
local fileInfo, coord, colorKey, flip = private.SplitTexturePath(key)
|
|
assert(not colorKey and not flip)
|
|
return {
|
|
texture = fileInfo.path,
|
|
coord = { private.GetTexCoord(fileInfo, coord) },
|
|
}
|
|
end
|
|
|
|
---Check if a texture key is valid.
|
|
---@param key string The texture key
|
|
---@return boolean @Whether or not the key is valid
|
|
function TextureAtlas.IsValid(key)
|
|
local fileInfo, coord = private.SplitTexturePath(key)
|
|
return fileInfo and coord and true or false
|
|
end
|
|
|
|
---Gets the color key component of a texture key.
|
|
---@param key string The texture key
|
|
---@return ThemeColorKey @The color key
|
|
function TextureAtlas.GetColorKey(key)
|
|
local fileInfo, _, colorKey = private.SplitTexturePath(key)
|
|
assert(fileInfo)
|
|
return colorKey
|
|
end
|
|
|
|
---Gets the width and height of a texture.
|
|
---@param key string The texture key
|
|
---@return number @The width
|
|
---@return number @The height
|
|
function TextureAtlas.GetSize(key)
|
|
local fileInfo, coord = private.SplitTexturePath(key)
|
|
assert(fileInfo and coord)
|
|
local minX, maxX, minY, maxY = unpack(coord)
|
|
local width = (maxX - minX) / fileInfo.scale
|
|
local height = (maxY - minY) / fileInfo.scale
|
|
return width, height
|
|
end
|
|
|
|
---Gets the width of a texture.
|
|
---@param key string The texture key
|
|
---@return number @The width
|
|
function TextureAtlas.GetWidth(key)
|
|
local width = TextureAtlas.GetSize(key)
|
|
return width
|
|
end
|
|
|
|
---Gets the height of a texture.
|
|
---@param key string The texture key
|
|
---@return number @The height
|
|
function TextureAtlas.GetHeight(key)
|
|
local _, height = TextureAtlas.GetSize(key)
|
|
return height
|
|
end
|
|
|
|
---Sets the visible texture of a texture widget.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetTexture(texture, key)
|
|
local fileInfo, coord, colorKey, flip = private.SplitTexturePath(key)
|
|
texture:SetTexture(fileInfo.path)
|
|
texture:SetTexCoord(private.GetTexCoord(fileInfo, coord, flip))
|
|
if colorKey then
|
|
texture:SetVertexColor(Theme.GetColor(colorKey):GetFractionalRGBA())
|
|
else
|
|
texture:SetVertexColor(1, 1, 1, 1)
|
|
end
|
|
end
|
|
|
|
---Sets the size of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetSize(texture, key)
|
|
local width, height = TextureAtlas.GetSize(key)
|
|
texture:SetWidth(width)
|
|
texture:SetHeight(height)
|
|
end
|
|
|
|
---Sets the widget of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetWidth(texture, key)
|
|
texture:SetWidth(TextureAtlas.GetWidth(key))
|
|
end
|
|
|
|
---Sets the height of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetHeight(texture, key)
|
|
texture:SetHeight(TextureAtlas.GetHeight(key))
|
|
end
|
|
|
|
---Sets the visible texture and width of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetTextureAndWidth(texture, key)
|
|
TextureAtlas.SetTexture(texture, key)
|
|
TextureAtlas.SetWidth(texture, key)
|
|
end
|
|
|
|
---Sets the visible texture and height of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetTextureAndHeight(texture, key)
|
|
TextureAtlas.SetTexture(texture, key)
|
|
TextureAtlas.SetHeight(texture, key)
|
|
end
|
|
|
|
---Sets the visible texture and size of a texture widget to match a texture key.
|
|
---@param texture Texture The texture widget
|
|
---@param key string The texture key
|
|
function TextureAtlas.SetTextureAndSize(texture, key)
|
|
TextureAtlas.SetTexture(texture, key)
|
|
TextureAtlas.SetSize(texture, key)
|
|
end
|
|
|
|
---Gets a UI escape code sequence for a texture.
|
|
---@param key string The texture key
|
|
---@return string @The escape code sequence
|
|
function TextureAtlas.GetTextureLink(key)
|
|
local width, height = TextureAtlas.GetSize(key)
|
|
local fileInfo, coord, colorKey, flip = private.SplitTexturePath(key)
|
|
assert(fileInfo and coord)
|
|
local minX, maxX, minY, maxY = private.GetTexCoord(fileInfo, coord, flip, true)
|
|
local r, g, b, a = 255, 255, 255, 255
|
|
if colorKey then
|
|
r, g, b, a = Theme.GetColor(colorKey):GetRGBA()
|
|
end
|
|
assert(a == 255)
|
|
return "|T"..strjoin(":", fileInfo.path, width, height, 0, 0, fileInfo.width, fileInfo.height, minX, maxX, minY, maxY, r, g, b).."|t"
|
|
end
|
|
|
|
---Creates a colored texture key.
|
|
---@param key string The texture key to add the color to
|
|
---@param colorKey ThemeColorKey The theme color key
|
|
---@return string @The escape code sequence
|
|
function TextureAtlas.GetColoredKey(key, colorKey)
|
|
local fileInfo, _, existingColor = private.SplitTexturePath(key)
|
|
assert(fileInfo and not existingColor)
|
|
local color = Theme.GetColor(colorKey)
|
|
assert(color and not color:Equals(Color.GetTransparent()))
|
|
return key.."#"..colorKey
|
|
end
|
|
|
|
---Crestes a vertically flipped texture key.
|
|
---@param key string The texture key to flip
|
|
---@return string @The flipped texture key
|
|
function TextureAtlas.GetFlippedVerticallyKey(key)
|
|
local fileInfo, _, existingColor, existingMirror = private.SplitTexturePath(key)
|
|
assert(fileInfo and not existingColor and not existingMirror)
|
|
return key.."@v"
|
|
end
|
|
|
|
---Crestes a horizontally flipped texture key.
|
|
---@param key string The texture key to flip
|
|
---@return string @The flipped texture key
|
|
function TextureAtlas.GetFlippedHorizontallyKey(key)
|
|
local fileInfo, _, existingColor, existingMirror = private.SplitTexturePath(key)
|
|
assert(fileInfo and not existingColor and not existingMirror)
|
|
return key.."@h"
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Private Helper Functions
|
|
-- ============================================================================
|
|
|
|
function private.SplitTexturePath(key)
|
|
local file, entry, colorKey, flip, colorKey2 = strmatch(key, "^([^%.]+)%.([^#@]+)(#?[0-9a-fA-Z_%+%-]*)@?([hv]?)(#?[0-9a-fA-Z_%+%-]*)$")
|
|
colorKey = (colorKey ~= "" and colorKey) or (colorKey2 ~= "" and colorKey2) or nil
|
|
flip = flip ~= "" and flip or nil
|
|
local fileInfo = file and private.files[file]
|
|
-- remove the leading '#' from theme color keys
|
|
colorKey = colorKey and strsub(colorKey, 2) or nil
|
|
return fileInfo, fileInfo and fileInfo.coord[entry], colorKey, flip
|
|
end
|
|
|
|
function private.GetTexCoord(fileInfo, coord, flip, nonNormalized)
|
|
local minX, maxX, minY, maxY = unpack(coord)
|
|
if flip == "h" then
|
|
minX, maxX = maxX, minX
|
|
elseif flip == "v" then
|
|
minY, maxY = maxY, minY
|
|
elseif flip then
|
|
error("Invalid flip direction: "..tostring(flip))
|
|
end
|
|
if not nonNormalized then
|
|
minX = minX / fileInfo.width
|
|
maxX = maxX / fileInfo.width
|
|
minY = minY / fileInfo.height
|
|
maxY = maxY / fileInfo.height
|
|
end
|
|
return minX, maxX, minY, maxY
|
|
end
|
|
|