319 lines
9.3 KiB
Lua
319 lines
9.3 KiB
Lua
|
-- ------------------------------------------------------------------------------ --
|
||
|
-- TradeSkillMaster --
|
||
|
-- https://tradeskillmaster.com --
|
||
|
-- All Rights Reserved - Detailed license information included with addon. --
|
||
|
-- ------------------------------------------------------------------------------ --
|
||
|
|
||
|
--- Theme Functions.
|
||
|
-- @module Theme
|
||
|
|
||
|
local _, TSM = ...
|
||
|
local Theme = TSM.Init("Util.Theme")
|
||
|
local FontPaths = TSM.Include("Data.FontPaths")
|
||
|
local Table = TSM.Include("Util.Table")
|
||
|
local Color = TSM.Include("Util.Color")
|
||
|
local FontObject = TSM.Include("Util.FontObject")
|
||
|
local private = {
|
||
|
callbacks = {},
|
||
|
names = {},
|
||
|
colorSets = {},
|
||
|
currentColorSet = nil,
|
||
|
fontFrame = nil,
|
||
|
currentFontSet = nil,
|
||
|
}
|
||
|
local THEME_COLOR_KEYS = {
|
||
|
FRAME_BG = true,
|
||
|
PRIMARY_BG = true,
|
||
|
PRIMARY_BG_ALT = true,
|
||
|
ACTIVE_BG = true,
|
||
|
ACTIVE_BG_ALT = true,
|
||
|
}
|
||
|
local STATIC_COLORS = {
|
||
|
INDICATOR = Color.NewFromHex("#ffd839"),
|
||
|
INDICATOR_ALT = Color.NewFromHex("#79a2ff"),
|
||
|
INDICATOR_DISABLED = Color.NewFromHex("#6f5819"),
|
||
|
|
||
|
TEXT = Color.NewFromHex("#ffffff"),
|
||
|
TEXT_ALT = Color.NewFromHex("#e2e2e2"),
|
||
|
TEXT_DISABLED = Color.NewFromHex("#424242"),
|
||
|
}
|
||
|
local FEEDBACK_COLORS = {
|
||
|
RED = Color.NewFromHex("#f72d20"),
|
||
|
YELLOW = Color.NewFromHex("#e1f720"),
|
||
|
GREEN = Color.NewFromHex("#4ff720"),
|
||
|
BLUE = Color.NewFromHex("#2076f7"),
|
||
|
ORANGE = Color.NewFromHex("#f77a20"),
|
||
|
}
|
||
|
local BLIZZARD_COLOR = Color.NewFromHex("#00b4ff")
|
||
|
local GROUP_COLORS = {
|
||
|
Color.NewFromHex("#fcf141"),
|
||
|
Color.NewFromHex("#bdaec6"),
|
||
|
Color.NewFromHex("#06a2cb"),
|
||
|
Color.NewFromHex("#ffb85c"),
|
||
|
Color.NewFromHex("#51b599"),
|
||
|
}
|
||
|
local PROFESSION_DIFFICULTY_COLORS = {
|
||
|
optimal = Color.NewFromHex("#ff8040"),
|
||
|
medium = Color.NewFromHex("#ffff00"),
|
||
|
easy = Color.NewFromHex("#40c040"),
|
||
|
trivial = Color.NewFromHex("#808080"),
|
||
|
header = Color.NewFromHex("#ffd100"),
|
||
|
subheader = Color.NewFromHex("#ffd100"),
|
||
|
nodifficulty = Color.NewFromHex("#f5f5f5"),
|
||
|
}
|
||
|
-- NOTE: there is a global ITEM_QUALITY_COLORS so we need to use another name
|
||
|
local TSM_ITEM_QUALITY_COLORS = {
|
||
|
[0] = Color.NewFromHex("#9d9d9d"),
|
||
|
[1] = Color.NewFromHex("#ffffff"),
|
||
|
[2] = Color.NewFromHex("#1eff00"),
|
||
|
[3] = Color.NewFromHex("#0070dd"),
|
||
|
[4] = Color.NewFromHex("#a334ee"),
|
||
|
[5] = Color.NewFromHex("#ff8000"),
|
||
|
[6] = Color.NewFromHex("#e6cc80"),
|
||
|
[7] = Color.NewFromHex("#00ccff"),
|
||
|
[8] = Color.NewFromHex("#00ccff"),
|
||
|
}
|
||
|
local AUCTION_PCT_COLORS = {
|
||
|
{ -- blue
|
||
|
color = "BLUE",
|
||
|
value = 50,
|
||
|
},
|
||
|
{ -- green
|
||
|
color = "GREEN",
|
||
|
value = 80,
|
||
|
},
|
||
|
{ -- yellow
|
||
|
color = "YELLOW",
|
||
|
value = 110,
|
||
|
},
|
||
|
{ -- orange
|
||
|
color = "ORANGE",
|
||
|
value = 135,
|
||
|
},
|
||
|
{ -- red
|
||
|
color = "RED",
|
||
|
value = math.huge,
|
||
|
},
|
||
|
default = "TEXT",
|
||
|
bid = "TEXT_ALT",
|
||
|
}
|
||
|
local CONSTANTS = {
|
||
|
COL_SPACING = 8,
|
||
|
SCROLLBAR_MARGIN = 4,
|
||
|
SCROLLBAR_WIDTH = 4,
|
||
|
MOUSE_WHEEL_SCROLL_AMOUNT = 60,
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Module Loading
|
||
|
-- ============================================================================
|
||
|
|
||
|
Theme:OnModuleLoad(function()
|
||
|
Table.SetReadOnly(STATIC_COLORS)
|
||
|
Table.SetReadOnly(FEEDBACK_COLORS)
|
||
|
Table.SetReadOnly(GROUP_COLORS)
|
||
|
Table.SetReadOnly(PROFESSION_DIFFICULTY_COLORS)
|
||
|
Table.SetReadOnly(TSM_ITEM_QUALITY_COLORS)
|
||
|
Table.SetReadOnly(CONSTANTS)
|
||
|
|
||
|
-- create a frame to load fonts
|
||
|
private.fontFrame = CreateFrame("Frame", nil, UIParent)
|
||
|
private.fontFrame.texts = {}
|
||
|
private.fontFrame:SetAllPoints()
|
||
|
private.fontFrame:SetScript("OnUpdate", private.FontFrameOnUpdate)
|
||
|
|
||
|
-- TODO: eventually allow for different font sets?
|
||
|
private.currentFontSet = {
|
||
|
HEADING_H5 = FontObject.New(FontPaths.GetBodyRegular(), 20, 28),
|
||
|
BODY_BODY1 = FontObject.New(FontPaths.GetBodyRegular(), 16, 24),
|
||
|
BODY_BODY1_BOLD = FontObject.New(FontPaths.GetBodyBold(), 16, 24),
|
||
|
BODY_BODY2 = FontObject.New(FontPaths.GetBodyRegular(), 14, 20),
|
||
|
BODY_BODY2_MEDIUM = FontObject.New(FontPaths.GetBodyMedium(), 14, 20),
|
||
|
BODY_BODY2_BOLD = FontObject.New(FontPaths.GetBodyBold(), 14, 20),
|
||
|
BODY_BODY3 = FontObject.New(FontPaths.GetBodyRegular(), 12, 20),
|
||
|
BODY_BODY3_MEDIUM = FontObject.New(FontPaths.GetBodyMedium(), 12, 20),
|
||
|
ITEM_BODY1 = FontObject.New(FontPaths.GetItem(), 16, 24),
|
||
|
ITEM_BODY2 = FontObject.New(FontPaths.GetItem(), 14, 20),
|
||
|
ITEM_BODY3 = FontObject.New(FontPaths.GetItem(), 12, 20),
|
||
|
TABLE_TABLE1 = FontObject.New(FontPaths.GetTable(), 12, 20),
|
||
|
}
|
||
|
|
||
|
-- load the fonts
|
||
|
for _, obj in pairs(private.currentFontSet) do
|
||
|
local fontPath = obj:GetWowFont()
|
||
|
private.QueueFontLoad(fontPath)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Module Functions
|
||
|
-- ============================================================================
|
||
|
|
||
|
--- Registers a callback when the theme changes.
|
||
|
-- @tparam function callback The callback function
|
||
|
function Theme.RegisterChangeCallback(callback)
|
||
|
assert(type(callback) == "function")
|
||
|
tinsert(private.callbacks, callback)
|
||
|
end
|
||
|
|
||
|
--- Registers a new color set.
|
||
|
-- @tparam string key The key which represents the color set
|
||
|
-- @tparam string name The name of the color set
|
||
|
-- @tparam table colorSet The colors which make up the color set (with keys specified in `THEME_COLOR_KEYS`)
|
||
|
function Theme.RegisterColorSet(key, name, colorSet)
|
||
|
assert(not private.colorSets[key])
|
||
|
for k in pairs(THEME_COLOR_KEYS) do
|
||
|
assert(Color.IsInstance(colorSet[k]))
|
||
|
end
|
||
|
private.names[key] = name
|
||
|
private.colorSets[key] = colorSet
|
||
|
end
|
||
|
|
||
|
--- Sets the active color set.
|
||
|
-- @tparam string key The key which represents the color set
|
||
|
function Theme.SetActiveColorSet(key)
|
||
|
assert(private.colorSets[key])
|
||
|
if private.currentColorSet == private.colorSets[key] then
|
||
|
return
|
||
|
end
|
||
|
private.currentColorSet = private.colorSets[key]
|
||
|
for _, callback in ipairs(private.callbacks) do
|
||
|
callback()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function Theme.GetThemeName(key)
|
||
|
return private.names[key]
|
||
|
end
|
||
|
|
||
|
--- Gets the color object from the current active color set.
|
||
|
-- @tparam string key The key of the color to get
|
||
|
-- @treturn Color The color object
|
||
|
function Theme.GetColor(key, themeKey)
|
||
|
local colorKey, tintPct, opacityPct = strmatch(key, "^([A-Z_]+)([%-%+]?[0-9A-Z_]*)%%?([0-9A-Z_]*)$")
|
||
|
tintPct = tonumber(tintPct) or (tintPct ~= "" and tintPct or nil)
|
||
|
opacityPct = tonumber(opacityPct) or (opacityPct ~= "" and opacityPct or nil)
|
||
|
assert(colorKey)
|
||
|
local color = nil
|
||
|
if THEME_COLOR_KEYS[colorKey] then
|
||
|
color = themeKey and private.colorSets[themeKey][colorKey] or private.currentColorSet[colorKey]
|
||
|
else
|
||
|
color = STATIC_COLORS[colorKey]
|
||
|
end
|
||
|
assert(color)
|
||
|
if tintPct then
|
||
|
color = color:GetTint(tintPct)
|
||
|
end
|
||
|
if opacityPct then
|
||
|
color = color:GetOpacity(opacityPct)
|
||
|
end
|
||
|
return color
|
||
|
end
|
||
|
|
||
|
--- Gets the color object for a given feedback color key.
|
||
|
-- @tparam string key The key of the feedback color to get
|
||
|
-- @treturn Color The color object
|
||
|
function Theme.GetFeedbackColor(key)
|
||
|
return FEEDBACK_COLORS[key]
|
||
|
end
|
||
|
|
||
|
--- Gets the color object for Blizzard GMs.
|
||
|
-- @treturn Color The color object
|
||
|
function Theme.GetBlizzardColor()
|
||
|
return BLIZZARD_COLOR
|
||
|
end
|
||
|
|
||
|
--- Gets the color object for a given group level.
|
||
|
-- @tparam number level The level of the group (1-based)
|
||
|
-- @treturn Color The color object
|
||
|
function Theme.GetGroupColor(level)
|
||
|
level = ((level - 1) % #GROUP_COLORS) + 1
|
||
|
return GROUP_COLORS[level]
|
||
|
end
|
||
|
|
||
|
function Theme.GetProfessionDifficultyColor(difficulty)
|
||
|
return PROFESSION_DIFFICULTY_COLORS[difficulty]
|
||
|
end
|
||
|
|
||
|
function Theme.GetItemQualityColor(quality)
|
||
|
return TSM_ITEM_QUALITY_COLORS[quality]
|
||
|
end
|
||
|
|
||
|
function Theme.GetAuctionPercentColor(pct)
|
||
|
if pct == "BID" then
|
||
|
return Theme.GetColor(AUCTION_PCT_COLORS.bid)
|
||
|
end
|
||
|
for _, info in ipairs(AUCTION_PCT_COLORS) do
|
||
|
if pct < info.value then
|
||
|
return Theme.GetFeedbackColor(info.color)
|
||
|
end
|
||
|
end
|
||
|
return Theme.GetColor(AUCTION_PCT_COLORS.default)
|
||
|
end
|
||
|
|
||
|
--- Gets the font object from the current active font set.
|
||
|
-- @tparam string key The key of the font to get
|
||
|
-- @treturn FontObject The font object
|
||
|
function Theme.GetFont(key)
|
||
|
local fontObj = private.currentFontSet[key]
|
||
|
assert(fontObj)
|
||
|
return fontObj
|
||
|
end
|
||
|
|
||
|
--- Gets the column spacing constant value.
|
||
|
-- @treturn number The column spacing
|
||
|
function Theme.GetColSpacing()
|
||
|
return CONSTANTS.COL_SPACING
|
||
|
end
|
||
|
|
||
|
--- Gets the scrollbar margin constant value.
|
||
|
-- @treturn number The scrollbar margin
|
||
|
function Theme.GetScrollbarMargin()
|
||
|
return CONSTANTS.SCROLLBAR_MARGIN
|
||
|
end
|
||
|
|
||
|
--- Gets the scrollbar width constant value.
|
||
|
-- @treturn number The scrollbar width
|
||
|
function Theme.GetScrollbarWidth()
|
||
|
return CONSTANTS.SCROLLBAR_WIDTH
|
||
|
end
|
||
|
|
||
|
--- Gets the scrollbar width constant value.
|
||
|
-- @treturn number The scrollbar width
|
||
|
function Theme.GetMouseWheelScrollAmount()
|
||
|
return CONSTANTS.MOUSE_WHEEL_SCROLL_AMOUNT
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
-- ============================================================================
|
||
|
-- Private Helper Functions
|
||
|
-- ============================================================================
|
||
|
|
||
|
function private.QueueFontLoad(path)
|
||
|
if private.fontFrame.texts[path] then
|
||
|
return
|
||
|
end
|
||
|
local fontString = private.fontFrame:CreateFontString()
|
||
|
fontString:SetPoint("CENTER")
|
||
|
fontString:SetWidth(10000)
|
||
|
fontString:SetHeight(6)
|
||
|
fontString:SetFont(path, 6)
|
||
|
fontString:SetText("1")
|
||
|
private.fontFrame.texts[path] = fontString
|
||
|
private.fontFrame:Show()
|
||
|
end
|
||
|
|
||
|
function private.FontFrameOnUpdate(frame)
|
||
|
for _, fontString in pairs(frame.texts) do
|
||
|
if fontString:IsVisible() then
|
||
|
assert(fontString:GetStringWidth() > 0, "Text not loaded: "..tostring(fontString:GetFont()))
|
||
|
fontString:Hide()
|
||
|
end
|
||
|
end
|
||
|
frame:Hide()
|
||
|
end
|