317 lines
12 KiB
Lua
317 lines
12 KiB
Lua
SFrames.Config = {
|
|
-- Default Settings
|
|
width = 220,
|
|
height = 50,
|
|
portraitWidth = 50,
|
|
castbarHeight = 18,
|
|
|
|
colors = {
|
|
backdrop = { r = 0.15, g = 0.10, b = 0.15, a = 0.8 }, -- Pinkish dark tint
|
|
border = { r = 1.0, g = 0.5, b = 0.8, a = 1 }, -- Cute pink border
|
|
power = {
|
|
[0] = { r = 0.0, g = 0.0, b = 1.0 }, -- Mana
|
|
[1] = { r = 1.0, g = 0.0, b = 0.0 }, -- Rage
|
|
[2] = { r = 1.0, g = 0.5, b = 0.0 }, -- Focus
|
|
[3] = { r = 1.0, g = 1.0, b = 0.0 }, -- Energy
|
|
[4] = { r = 0.0, g = 1.0, b = 1.0 }, -- Happiness
|
|
},
|
|
class = {
|
|
["WARRIOR"] = { r = 0.78, g = 0.61, b = 0.43 },
|
|
["MAGE"] = { r = 0.41, g = 0.8, b = 0.94 },
|
|
["ROGUE"] = { r = 1.0, g = 0.96, b = 0.41 },
|
|
["DRUID"] = { r = 1.0, g = 0.49, b = 0.04 },
|
|
["HUNTER"] = { r = 0.67, g = 0.83, b = 0.45 },
|
|
["SHAMAN"] = { r = 0.14, g = 0.35, b = 1.0 },
|
|
["PRIEST"] = { r = 1.0, g = 1.0, b = 1.0 },
|
|
["WARLOCK"] = { r = 0.58, g = 0.51, b = 0.79 },
|
|
["PALADIN"] = { r = 0.96, g = 0.55, b = 0.73 },
|
|
}
|
|
}
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Theme Engine
|
|
--------------------------------------------------------------------------------
|
|
|
|
SFrames.Theme = {}
|
|
SFrames.ActiveTheme = {}
|
|
|
|
local function HSVtoRGB(h, s, v)
|
|
if s <= 0 then return v, v, v end
|
|
h = h - math.floor(h / 360) * 360
|
|
local hh = h / 60
|
|
local i = math.floor(hh)
|
|
local f = hh - i
|
|
local p = v * (1 - s)
|
|
local q = v * (1 - s * f)
|
|
local t = v * (1 - s * (1 - f))
|
|
if i == 0 then return v, t, p
|
|
elseif i == 1 then return q, v, p
|
|
elseif i == 2 then return p, v, t
|
|
elseif i == 3 then return p, q, v
|
|
elseif i == 4 then return t, p, v
|
|
else return v, p, q end
|
|
end
|
|
|
|
local function toHexChar(n)
|
|
if n < 10 then return string.char(48 + n) end
|
|
return string.char(97 + n - 10)
|
|
end
|
|
|
|
local function RGBtoHex(r, g, b)
|
|
local rr = math.floor(r * 255 + 0.5)
|
|
local gg = math.floor(g * 255 + 0.5)
|
|
local bb = math.floor(b * 255 + 0.5)
|
|
return "ff"
|
|
.. toHexChar(math.floor(rr / 16)) .. toHexChar(rr - math.floor(rr / 16) * 16)
|
|
.. toHexChar(math.floor(gg / 16)) .. toHexChar(gg - math.floor(gg / 16) * 16)
|
|
.. toHexChar(math.floor(bb / 16)) .. toHexChar(bb - math.floor(bb / 16) * 16)
|
|
end
|
|
|
|
SFrames.Theme.Presets = {}
|
|
SFrames.Theme.Presets["pink"] = { name = "樱粉", hue = 330, satMul = 1.00 }
|
|
SFrames.Theme.Presets["frost"] = { name = "霜蓝", hue = 210, satMul = 1.00 }
|
|
SFrames.Theme.Presets["emerald"] = { name = "翠绿", hue = 140, satMul = 0.85 }
|
|
SFrames.Theme.Presets["flame"] = { name = "炎橙", hue = 25, satMul = 0.90 }
|
|
SFrames.Theme.Presets["shadow"] = { name = "暗紫", hue = 270, satMul = 0.90 }
|
|
SFrames.Theme.Presets["golden"] = { name = "金辉", hue = 45, satMul = 0.80 }
|
|
SFrames.Theme.Presets["teal"] = { name = "碧青", hue = 175, satMul = 0.85 }
|
|
SFrames.Theme.Presets["crimson"] = { name = "绯红", hue = 5, satMul = 1.00 }
|
|
SFrames.Theme.Presets["holy"] = { name = "圣光", hue = 220, satMul = 0.15 }
|
|
|
|
SFrames.Theme.PresetOrder = { "pink", "frost", "emerald", "flame", "shadow", "golden", "teal", "crimson", "holy" }
|
|
|
|
SFrames.Theme.Presets["c_warrior"] = { name = "战士", hue = 31, satMul = 0.90, swatchRGB = {0.78, 0.61, 0.43} }
|
|
SFrames.Theme.Presets["c_paladin"] = { name = "圣骑士", hue = 334, satMul = 0.50, swatchRGB = {0.96, 0.55, 0.73} }
|
|
SFrames.Theme.Presets["c_hunter"] = { name = "猎人", hue = 85, satMul = 0.55, swatchRGB = {0.67, 0.83, 0.45} }
|
|
SFrames.Theme.Presets["c_rogue"] = { name = "潜行者", hue = 56, satMul = 0.70, swatchRGB = {1.00, 0.96, 0.41} }
|
|
SFrames.Theme.Presets["c_priest"] = { name = "牧师", hue = 40, satMul = 0.06, swatchRGB = {1.00, 1.00, 1.00} }
|
|
SFrames.Theme.Presets["c_shaman"] = { name = "萨满", hue = 225, satMul = 0.95, swatchRGB = {0.14, 0.35, 1.00} }
|
|
SFrames.Theme.Presets["c_mage"] = { name = "法师", hue = 196, satMul = 0.65, swatchRGB = {0.41, 0.80, 0.94} }
|
|
SFrames.Theme.Presets["c_warlock"] = { name = "术士", hue = 255, satMul = 0.45, swatchRGB = {0.58, 0.51, 0.79} }
|
|
SFrames.Theme.Presets["c_druid"] = { name = "德鲁伊", hue = 28, satMul = 1.00, swatchRGB = {1.00, 0.49, 0.04} }
|
|
|
|
SFrames.Theme.ClassPresetOrder = { "c_warrior", "c_paladin", "c_hunter", "c_rogue", "c_priest", "c_shaman", "c_mage", "c_warlock", "c_druid" }
|
|
|
|
SFrames.Theme.ClassMap = {}
|
|
SFrames.Theme.ClassMap["WARRIOR"] = "c_warrior"
|
|
SFrames.Theme.ClassMap["PALADIN"] = "c_paladin"
|
|
SFrames.Theme.ClassMap["HUNTER"] = "c_hunter"
|
|
SFrames.Theme.ClassMap["ROGUE"] = "c_rogue"
|
|
SFrames.Theme.ClassMap["PRIEST"] = "c_priest"
|
|
SFrames.Theme.ClassMap["SHAMAN"] = "c_shaman"
|
|
SFrames.Theme.ClassMap["MAGE"] = "c_mage"
|
|
SFrames.Theme.ClassMap["WARLOCK"] = "c_warlock"
|
|
SFrames.Theme.ClassMap["DRUID"] = "c_druid"
|
|
|
|
local function GenerateTheme(H, satMul)
|
|
satMul = satMul or 1.0
|
|
local function S(s)
|
|
local v = s * satMul
|
|
if v > 1 then v = 1 end
|
|
return v
|
|
end
|
|
local function C3(s, v)
|
|
local r, g, b = HSVtoRGB(H, S(s), v)
|
|
return { r, g, b }
|
|
end
|
|
local function C4(s, v, a)
|
|
local r, g, b = HSVtoRGB(H, S(s), v)
|
|
return { r, g, b, a }
|
|
end
|
|
local t = {}
|
|
t.accent = C4(0.40, 0.80, 0.98)
|
|
t.accentDark = C3(0.45, 0.55)
|
|
t.accentLight = C3(0.30, 1.00)
|
|
t.accentHex = RGBtoHex(t.accentLight[1], t.accentLight[2], t.accentLight[3])
|
|
t.panelBg = C4(0.50, 0.12, 0.95)
|
|
t.panelBorder = C4(0.45, 0.55, 0.90)
|
|
t.headerBg = C4(0.60, 0.10, 0.98)
|
|
t.sectionBg = C4(0.43, 0.14, 0.82)
|
|
t.sectionBorder = C4(0.38, 0.45, 0.86)
|
|
t.bg = t.panelBg
|
|
t.border = t.panelBorder
|
|
t.slotBg = C4(0.20, 0.07, 0.90)
|
|
t.slotBorder = C4(0.10, 0.28, 0.80)
|
|
t.slotHover = C4(0.38, 0.40, 0.90)
|
|
t.slotSelected = C4(0.43, 0.70, 1.00)
|
|
t.buttonBg = C4(0.44, 0.18, 0.94)
|
|
t.buttonBorder = C4(0.40, 0.50, 0.90)
|
|
t.buttonHoverBg = C4(0.47, 0.30, 0.96)
|
|
t.buttonDownBg = C4(0.50, 0.14, 0.96)
|
|
t.buttonDisabledBg = C4(0.43, 0.14, 0.65)
|
|
t.buttonActiveBg = C4(0.52, 0.42, 0.98)
|
|
t.buttonActiveBorder = C4(0.42, 0.90, 1.00)
|
|
t.buttonText = C3(0.16, 0.90)
|
|
t.buttonActiveText = C3(0.08, 1.00)
|
|
t.buttonDisabledText = C4(0.14, 0.55, 0.68)
|
|
t.btnBg = t.buttonBg
|
|
t.btnBorder = t.buttonBorder
|
|
t.btnHoverBg = t.buttonHoverBg
|
|
t.btnHoverBd = C4(0.40, 0.80, 0.98)
|
|
t.btnDownBg = t.buttonDownBg
|
|
t.btnText = t.buttonText
|
|
t.btnActiveText = t.buttonActiveText
|
|
t.btnDisabledText = C3(0.14, 0.40)
|
|
t.btnHover = C4(0.47, 0.30, 0.95)
|
|
t.btnHoverBorder = t.btnHoverBd
|
|
t.tabBg = t.buttonBg
|
|
t.tabBorder = t.buttonBorder
|
|
t.tabActiveBg = C4(0.50, 0.32, 0.96)
|
|
t.tabActiveBorder = C4(0.40, 0.80, 0.98)
|
|
t.tabText = C3(0.21, 0.70)
|
|
t.tabActiveText = t.buttonActiveText
|
|
t.checkBg = t.buttonBg
|
|
t.checkBorder = t.buttonBorder
|
|
t.checkHoverBorder = C4(0.40, 0.80, 0.95)
|
|
t.checkFill = C4(0.43, 0.88, 0.98)
|
|
t.checkOn = C3(0.40, 0.80)
|
|
t.checkOff = C4(0.40, 0.25, 0.60)
|
|
t.sliderTrack = C4(0.45, 0.22, 0.90)
|
|
t.sliderFill = C4(0.35, 0.85, 0.92)
|
|
t.sliderThumb = C4(0.25, 1.00, 0.95)
|
|
t.text = C3(0.11, 0.92)
|
|
t.title = C3(0.30, 1.00)
|
|
t.gold = t.title
|
|
t.nameText = C3(0.06, 0.92)
|
|
t.dimText = C3(0.25, 0.60)
|
|
t.bodyText = C3(0.05, 0.82)
|
|
t.sectionTitle = C3(0.24, 0.90)
|
|
t.catHeader = C3(0.31, 0.80)
|
|
t.colHeader = C3(0.25, 0.80)
|
|
t.labelText = C3(0.23, 0.65)
|
|
t.valueText = t.text
|
|
t.subText = t.labelText
|
|
t.pageText = C3(0.19, 0.80)
|
|
t.objectiveText = C3(0.10, 0.90)
|
|
t.optionText = t.tabText
|
|
t.countText = t.tabText
|
|
t.trackText = C3(0.25, 0.80)
|
|
t.divider = C4(0.45, 0.55, 0.40)
|
|
t.sepColor = C4(0.44, 0.45, 0.50)
|
|
t.scrollThumb = C4(0.45, 0.55, 0.70)
|
|
t.scrollTrack = C4(0.50, 0.08, 0.50)
|
|
t.inputBg = C4(0.50, 0.08, 0.95)
|
|
t.inputBorder = C4(0.38, 0.40, 0.80)
|
|
t.searchBg = C4(0.50, 0.08, 0.80)
|
|
t.searchBorder = C4(0.38, 0.40, 0.60)
|
|
t.progressBg = C4(0.50, 0.08, 0.90)
|
|
t.progressFill = C4(0.50, 0.70, 1.00)
|
|
t.modelBg = C4(0.60, 0.08, 0.85)
|
|
t.modelBorder = C4(0.43, 0.35, 0.70)
|
|
t.emptySlot = C4(0.40, 0.25, 0.40)
|
|
t.emptySlotBg = C4(0.50, 0.08, 0.40)
|
|
t.emptySlotBd = C4(0.40, 0.25, 0.30)
|
|
t.barBg = C4(0.60, 0.10, 1.00)
|
|
t.rowNormal = C4(0.50, 0.06, 0.30)
|
|
t.rowNormalBd = C4(0.22, 0.20, 0.30)
|
|
t.raidGroup = t.sectionBg
|
|
t.raidGroupBorder = C4(0.38, 0.40, 0.70)
|
|
t.raidSlotEmpty = C4(0.50, 0.08, 0.60)
|
|
t.questSelected = C4(0.70, 0.60, 0.85)
|
|
t.questSelBorder = C4(0.47, 0.95, 1.00)
|
|
t.questSelBar = C4(0.45, 1.00, 1.00)
|
|
t.questHover = C4(0.52, 0.25, 0.50)
|
|
t.zoneHeader = t.catHeader
|
|
t.zoneBg = C4(0.50, 0.14, 0.50)
|
|
t.collapseIcon = C3(0.31, 0.70)
|
|
t.trackBar = C4(0.53, 0.95, 1.00)
|
|
t.trackGlow = C4(0.53, 0.95, 0.22)
|
|
t.rewardBg = C4(0.50, 0.10, 0.85)
|
|
t.rewardBorder = C4(0.45, 0.40, 0.70)
|
|
t.listBg = C4(0.50, 0.08, 0.80)
|
|
t.listBorder = C4(0.43, 0.35, 0.60)
|
|
t.detailBg = C4(0.50, 0.09, 0.92)
|
|
t.detailBorder = t.listBorder
|
|
t.selectedRowBg = C4(0.65, 0.35, 0.60)
|
|
t.selectedRowBorder = C4(0.50, 0.90, 0.70)
|
|
t.selectedNameText = { 1, 0.95, 1 }
|
|
t.overlayBg = C4(0.75, 0.04, 0.55)
|
|
t.accentLine = C4(0.50, 1.00, 0.90)
|
|
t.titleColor = t.title
|
|
t.nameColor = { 1, 1, 1 }
|
|
t.valueColor = t.text
|
|
t.labelColor = C3(0.28, 0.58)
|
|
t.dimColor = C3(0.29, 0.48)
|
|
t.clockColor = C3(0.18, 1.00)
|
|
t.timerColor = C3(0.27, 0.75)
|
|
t.brandColor = C4(0.37, 0.60, 0.70)
|
|
t.particleColor = C3(0.40, 1.00)
|
|
t.wbGold = { 1, 0.88, 0.55 }
|
|
t.wbBorder = { 0.95, 0.75, 0.25 }
|
|
t.passive = { 0.60, 0.60, 0.65 }
|
|
return t
|
|
end
|
|
|
|
function SFrames.Theme:Extend(extras)
|
|
local override = extras or {}
|
|
local proxy = {}
|
|
setmetatable(proxy, {
|
|
__index = function(self, k)
|
|
local v = override[k]
|
|
if v ~= nil then return v end
|
|
return SFrames.ActiveTheme[k]
|
|
end
|
|
})
|
|
return proxy
|
|
end
|
|
|
|
function SFrames.Theme:Apply(presetKey)
|
|
local key = presetKey or "pink"
|
|
local preset = self.Presets[key]
|
|
if not preset then key = "pink"; preset = self.Presets["pink"] end
|
|
local newTheme = GenerateTheme(preset.hue, preset.satMul)
|
|
local oldKeys = {}
|
|
for k, v in pairs(SFrames.ActiveTheme) do
|
|
table.insert(oldKeys, k)
|
|
end
|
|
for i = 1, table.getn(oldKeys) do
|
|
SFrames.ActiveTheme[oldKeys[i]] = nil
|
|
end
|
|
for k, v in pairs(newTheme) do
|
|
SFrames.ActiveTheme[k] = v
|
|
end
|
|
if SFrames.Config and SFrames.Config.colors then
|
|
local a = SFrames.ActiveTheme
|
|
SFrames.Config.colors.border = { r = a.accent[1], g = a.accent[2], b = a.accent[3], a = 1 }
|
|
SFrames.Config.colors.backdrop = { r = a.panelBg[1], g = a.panelBg[2], b = a.panelBg[3], a = a.panelBg[4] or 0.8 }
|
|
end
|
|
if SFrames.MinimapButton and SFrames.MinimapButton.Refresh then
|
|
SFrames.MinimapButton:Refresh()
|
|
end
|
|
end
|
|
|
|
function SFrames.Theme:GetCurrentPreset()
|
|
local dbExists = SFramesDB and true or false
|
|
local themeExists = SFramesDB and type(SFramesDB.Theme) == "table" and true or false
|
|
local savedPreset = themeExists and SFramesDB.Theme.preset or "nil"
|
|
if SFramesDB and type(SFramesDB.Theme) == "table" then
|
|
if SFramesDB.Theme.useClassTheme then
|
|
local _, class = UnitClass("player")
|
|
if class and self.ClassMap[class] then
|
|
return self.ClassMap[class]
|
|
end
|
|
end
|
|
if SFramesDB.Theme.preset and self.Presets[SFramesDB.Theme.preset] then
|
|
return SFramesDB.Theme.preset
|
|
end
|
|
end
|
|
return "pink"
|
|
end
|
|
|
|
function SFrames.Theme:GetAccentHex()
|
|
return SFrames.ActiveTheme.accentHex or "ffffb3d9"
|
|
end
|
|
|
|
SFrames.Theme.HSVtoRGB = HSVtoRGB
|
|
SFrames.Theme.RGBtoHex = RGBtoHex
|
|
|
|
SFrames.Theme:Apply(SFrames.Theme:GetCurrentPreset())
|
|
|
|
local themeInitFrame = CreateFrame("Frame")
|
|
themeInitFrame:RegisterEvent("VARIABLES_LOADED")
|
|
themeInitFrame:RegisterEvent("PLAYER_LOGIN")
|
|
themeInitFrame:SetScript("OnEvent", function()
|
|
SFrames.Theme:Apply(SFrames.Theme:GetCurrentPreset())
|
|
end)
|