1075 lines
39 KiB
Lua
1075 lines
39 KiB
Lua
local NP = NanamiPlates
|
|
local Settings = NP.Settings
|
|
|
|
local optionsFrame = nil
|
|
local minimapButton = nil
|
|
|
|
-- ============================================
|
|
-- THEME HELPERS
|
|
-- ============================================
|
|
local function C(key, fr, fg, fb, fa)
|
|
return NP.GetThemeColor(key, fr, fg, fb, fa or 1)
|
|
end
|
|
|
|
local function MakeBackdrop(f, bgKey, brKey)
|
|
local bgR, bgG, bgB, bgA = C(bgKey or "panelBg", 0.10, 0.06, 0.10, 0.95)
|
|
local brR, brG, brB, brA = C(brKey or "panelBorder", 0.55, 0.30, 0.42, 0.9)
|
|
f:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 1, right = 1, top = 1, bottom = 1 }
|
|
})
|
|
f:SetBackdropColor(bgR, bgG, bgB, bgA)
|
|
f:SetBackdropBorderColor(brR, brG, brB, brA)
|
|
end
|
|
|
|
local function SectionLabel(parent, text, x, y)
|
|
local lbl = parent:CreateFontString(nil, "OVERLAY")
|
|
lbl:SetFont(NP.GetFont(), 11, NP.GetFontOutline())
|
|
lbl:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
local acR, acG, acB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
lbl:SetTextColor(acR, acG, acB, 0.85)
|
|
lbl:SetText(text)
|
|
return lbl
|
|
end
|
|
|
|
-- ============================================
|
|
-- CHECKBOX
|
|
-- ============================================
|
|
local checkIdx = 0
|
|
local function CreateCheckbox(parent, label, settingKey, x, y, tooltip)
|
|
checkIdx = checkIdx + 1
|
|
local size = 16
|
|
local frame = CreateFrame("Button", "NP_Chk" .. checkIdx, parent)
|
|
frame:SetWidth(size)
|
|
frame:SetHeight(size)
|
|
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
|
|
local cbBgR, cbBgG, cbBgB = C("checkBg", 0.08, 0.04, 0.08, 1)
|
|
local cbBrR, cbBrG, cbBrB = C("checkBorder", 0.45, 0.25, 0.38, 1)
|
|
frame:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
frame:SetBackdropColor(cbBgR, cbBgG, cbBgB, 1)
|
|
frame:SetBackdropBorderColor(cbBrR, cbBrG, cbBrB, 1)
|
|
|
|
local mark = frame:CreateTexture(nil, "OVERLAY")
|
|
mark:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
mark:SetPoint("TOPLEFT", frame, "TOPLEFT", 3, -3)
|
|
mark:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -3, 3)
|
|
local fillR, fillG, fillB = C("checkOn", 0.9, 0.45, 0.7, 1)
|
|
mark:SetVertexColor(fillR, fillG, fillB, 1)
|
|
|
|
local text = frame:CreateFontString(nil, "OVERLAY")
|
|
text:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
text:SetPoint("LEFT", frame, "RIGHT", 6, 0)
|
|
local txtR, txtG, txtB = C("text", 0.85, 0.85, 0.85, 1)
|
|
text:SetTextColor(txtR, txtG, txtB)
|
|
text:SetText(label)
|
|
|
|
local function Upd()
|
|
if Settings[settingKey] then
|
|
mark:Show()
|
|
local onR, onG, onB = C("checkOn", 0.9, 0.45, 0.7, 1)
|
|
frame:SetBackdropBorderColor(onR, onG, onB, 1)
|
|
else
|
|
mark:Hide()
|
|
frame:SetBackdropBorderColor(cbBrR, cbBrG, cbBrB, 1)
|
|
end
|
|
end
|
|
Upd()
|
|
|
|
frame:SetScript("OnClick", function()
|
|
Settings[settingKey] = not Settings[settingKey]
|
|
NP:SaveSettings()
|
|
Upd()
|
|
end)
|
|
local hvR, hvG, hvB = C("checkHoverBorder", 0.75, 0.40, 0.60, 1)
|
|
frame:SetScript("OnEnter", function()
|
|
if not Settings[settingKey] then frame:SetBackdropBorderColor(hvR, hvG, hvB, 1) end
|
|
if tooltip and GameTooltip then
|
|
GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
|
|
GameTooltip:SetText(tooltip, 1, 1, 1, 1, true)
|
|
GameTooltip:Show()
|
|
end
|
|
end)
|
|
frame:SetScript("OnLeave", function()
|
|
Upd()
|
|
if GameTooltip then GameTooltip:Hide() end
|
|
end)
|
|
return frame
|
|
end
|
|
|
|
-- ============================================
|
|
-- SLIDER (with inline editable value)
|
|
-- ============================================
|
|
local sliderIdx = 0
|
|
local function CreateSlider(parent, label, settingKey, minVal, maxVal, step, x, y, fmt, onChange)
|
|
sliderIdx = sliderIdx + 1
|
|
fmt = fmt or "%d"
|
|
|
|
local EDIT_W = 42
|
|
local ctr = CreateFrame("Frame", nil, parent)
|
|
ctr:SetWidth(220)
|
|
ctr:SetHeight(32)
|
|
ctr:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
|
|
local nameT = ctr:CreateFontString(nil, "OVERLAY")
|
|
nameT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
nameT:SetPoint("TOPLEFT", ctr, "TOPLEFT", 0, 0)
|
|
local lblR, lblG, lblB = C("labelText", 0.75, 0.75, 0.75, 1)
|
|
nameT:SetTextColor(lblR, lblG, lblB)
|
|
|
|
-- Value display (click to edit)
|
|
local valT = ctr:CreateFontString(nil, "OVERLAY")
|
|
valT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
valT:SetPoint("TOPRIGHT", ctr, "TOPRIGHT", 0, 0)
|
|
local valR, valG, valB = C("valueText", 0.9, 0.9, 0.9, 1)
|
|
valT:SetTextColor(valR, valG, valB)
|
|
|
|
-- EditBox for manual input (hidden by default)
|
|
local editBox = CreateFrame("EditBox", "NP_SliderEdit" .. sliderIdx, ctr)
|
|
editBox:SetWidth(EDIT_W)
|
|
editBox:SetHeight(14)
|
|
editBox:SetPoint("TOPRIGHT", ctr, "TOPRIGHT", 2, 2)
|
|
editBox:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
editBox:SetTextColor(1, 1, 1, 1)
|
|
editBox:SetJustifyH("RIGHT")
|
|
editBox:SetAutoFocus(false)
|
|
editBox:SetMaxLetters(8)
|
|
local eBgR, eBgG, eBgB = C("panelBg", 0.12, 0.08, 0.12, 1)
|
|
local eBrR, eBrG, eBrB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
editBox:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 2, right = 2, top = 0, bottom = 0 }
|
|
})
|
|
editBox:SetBackdropColor(eBgR, eBgG, eBgB, 1)
|
|
editBox:SetBackdropBorderColor(eBrR, eBrG, eBrB, 0.9)
|
|
editBox:Hide()
|
|
|
|
-- Click region over value text to open editbox
|
|
local valBtn = CreateFrame("Button", nil, ctr)
|
|
valBtn:SetWidth(EDIT_W + 4)
|
|
valBtn:SetHeight(14)
|
|
valBtn:SetPoint("TOPRIGHT", ctr, "TOPRIGHT", 2, 2)
|
|
valBtn:SetFrameLevel(ctr:GetFrameLevel() + 1)
|
|
|
|
local trkH = 6
|
|
local track = CreateFrame("Frame", nil, ctr)
|
|
track:SetHeight(trkH)
|
|
track:SetPoint("TOPLEFT", ctr, "TOPLEFT", 0, -14)
|
|
track:SetPoint("TOPRIGHT", ctr, "TOPRIGHT", 0, -14)
|
|
local trkR, trkG, trkB = C("sliderTrack", 0.12, 0.08, 0.12, 1)
|
|
track:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
track:SetBackdropColor(trkR, trkG, trkB, 1)
|
|
local tBrR, tBrG, tBrB = C("panelBorder", 0.35, 0.20, 0.30, 1)
|
|
track:SetBackdropBorderColor(tBrR, tBrG, tBrB, 0.5)
|
|
|
|
local fill = track:CreateTexture(nil, "ARTWORK")
|
|
fill:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
fill:SetPoint("TOPLEFT", track, "TOPLEFT", 1, -1)
|
|
fill:SetHeight(trkH - 2)
|
|
local fR, fG, fB = C("sliderFill", 0.7, 0.35, 0.55, 1)
|
|
fill:SetVertexColor(fR, fG, fB, 0.9)
|
|
|
|
local thumb = CreateFrame("Frame", nil, track)
|
|
thumb:SetWidth(12)
|
|
thumb:SetHeight(12)
|
|
thumb:SetFrameLevel(track:GetFrameLevel() + 2)
|
|
local thR, thG, thB = C("sliderThumb", 0.9, 0.55, 0.75, 1)
|
|
thumb:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
thumb:SetBackdropColor(thR, thG, thB, 1)
|
|
local thBR, thBG, thBB = C("panelBorder", 0.55, 0.30, 0.42, 1)
|
|
thumb:SetBackdropBorderColor(thBR, thBG, thBB, 1)
|
|
|
|
local function Norm(v) if maxVal == minVal then return 0 end return (v - minVal) / (maxVal - minVal) end
|
|
|
|
local function FormatValue(v)
|
|
if fmt == "pct" then
|
|
return math.floor(v * 100 + 0.5) .. "%"
|
|
else
|
|
return string.format(fmt, v)
|
|
end
|
|
end
|
|
|
|
local function Refresh(v)
|
|
v = math.floor(v / step + 0.5) * step
|
|
if v < minVal then v = minVal end
|
|
if v > maxVal then v = maxVal end
|
|
nameT:SetText(label)
|
|
valT:SetText(FormatValue(v))
|
|
local n = Norm(v)
|
|
local tw = track:GetWidth()
|
|
if tw <= 0 then tw = 220 end
|
|
fill:SetWidth(math.max(1, n * (tw - 2)))
|
|
thumb:ClearAllPoints()
|
|
thumb:SetPoint("CENTER", track, "LEFT", 1 + n * (tw - 2), 0)
|
|
end
|
|
|
|
local function ApplyValue(v)
|
|
v = math.floor(v / step + 0.5) * step
|
|
if v < minVal then v = minVal end
|
|
if v > maxVal then v = maxVal end
|
|
Settings[settingKey] = v
|
|
NP:SaveSettings()
|
|
Refresh(v)
|
|
if onChange then onChange(v) end
|
|
end
|
|
|
|
-- EditBox: show on click, commit on Enter/Tab, cancel on Escape
|
|
valBtn:SetScript("OnClick", function()
|
|
local cur = Settings[settingKey] or minVal
|
|
local rawVal
|
|
if fmt == "pct" then
|
|
rawVal = tostring(math.floor(cur * 100 + 0.5))
|
|
else
|
|
rawVal = string.format(fmt, cur)
|
|
end
|
|
editBox:SetText(rawVal)
|
|
valT:Hide()
|
|
valBtn:Hide()
|
|
editBox:Show()
|
|
editBox:SetFocus()
|
|
editBox:HighlightText()
|
|
end)
|
|
local hvUlR, hvUlG, hvUlB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
valBtn:SetScript("OnEnter", function() valT:SetTextColor(hvUlR, hvUlG, hvUlB) end)
|
|
valBtn:SetScript("OnLeave", function() valT:SetTextColor(valR, valG, valB) end)
|
|
|
|
local function CommitEdit()
|
|
local txt = editBox:GetText()
|
|
editBox:Hide()
|
|
valT:Show()
|
|
valBtn:Show()
|
|
local num = tonumber(txt)
|
|
if not num then
|
|
Refresh(Settings[settingKey] or minVal)
|
|
return
|
|
end
|
|
if fmt == "pct" then num = num / 100 end
|
|
ApplyValue(num)
|
|
end
|
|
|
|
editBox:SetScript("OnEnterPressed", function() CommitEdit() end)
|
|
editBox:SetScript("OnTabPressed", function() CommitEdit() end)
|
|
editBox:SetScript("OnEscapePressed", function()
|
|
editBox:Hide()
|
|
valT:Show()
|
|
valBtn:Show()
|
|
Refresh(Settings[settingKey] or minVal)
|
|
end)
|
|
|
|
track:EnableMouse(true)
|
|
local function HandleMouse()
|
|
local tw = track:GetWidth()
|
|
if tw <= 0 then return end
|
|
local mx = GetCursorPosition() / track:GetEffectiveScale()
|
|
local n = (mx - track:GetLeft()) / tw
|
|
if n < 0 then n = 0 end
|
|
if n > 1 then n = 1 end
|
|
local v = math.floor((minVal + n * (maxVal - minVal)) / step + 0.5) * step
|
|
ApplyValue(v)
|
|
end
|
|
track:SetScript("OnMouseDown", function() HandleMouse(); this.drag = true end)
|
|
track:SetScript("OnMouseUp", function() this.drag = false end)
|
|
track:SetScript("OnUpdate", function() if this.drag then HandleMouse() end end)
|
|
|
|
ctr:SetScript("OnShow", function() Refresh(Settings[settingKey] or minVal) end)
|
|
ctr.init = CreateFrame("Frame", nil, ctr)
|
|
ctr.init:SetScript("OnUpdate", function()
|
|
Refresh(Settings[settingKey] or minVal)
|
|
this:SetScript("OnUpdate", nil)
|
|
end)
|
|
return ctr
|
|
end
|
|
|
|
-- ============================================
|
|
-- CYCLE BUTTON
|
|
-- ============================================
|
|
local cycleIdx = 0
|
|
local function CreateCycleButton(parent, label, settingKey, options, x, y)
|
|
cycleIdx = cycleIdx + 1
|
|
local frame = CreateFrame("Button", "NP_Cyc" .. cycleIdx, parent)
|
|
frame:SetWidth(220)
|
|
frame:SetHeight(20)
|
|
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
|
|
local nameT = frame:CreateFontString(nil, "OVERLAY")
|
|
nameT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
nameT:SetPoint("LEFT", frame, "LEFT", 0, 0)
|
|
local lblR, lblG, lblB = C("labelText", 0.75, 0.75, 0.75, 1)
|
|
nameT:SetTextColor(lblR, lblG, lblB)
|
|
nameT:SetText(label)
|
|
|
|
local btn = CreateFrame("Button", nil, frame)
|
|
btn:SetWidth(110)
|
|
btn:SetHeight(18)
|
|
btn:SetPoint("RIGHT", frame, "RIGHT", 0, 0)
|
|
MakeBackdrop(btn, "buttonBg", "sepColor")
|
|
|
|
local btnT = btn:CreateFontString(nil, "OVERLAY")
|
|
btnT:SetFont(NP.GetFont(), 9, NP.GetFontOutline())
|
|
btnT:SetPoint("CENTER", btn, "CENTER", 0, 0)
|
|
local bTR, bTG, bTB = C("buttonText", 0.85, 0.85, 0.85, 1)
|
|
btnT:SetTextColor(bTR, bTG, bTB)
|
|
|
|
local function GetLbl(v)
|
|
for _, o in ipairs(options) do if o.value == v then return o.label end end
|
|
return tostring(v)
|
|
end
|
|
local function Upd() btnT:SetText(GetLbl(Settings[settingKey])) end
|
|
Upd()
|
|
|
|
btn:SetScript("OnClick", function()
|
|
local cur = Settings[settingKey]
|
|
local ni = 1
|
|
for i, o in ipairs(options) do
|
|
if o.value == cur then ni = i + 1; if ni > table.getn(options) then ni = 1 end; break end
|
|
end
|
|
Settings[settingKey] = options[ni].value
|
|
NP:SaveSettings()
|
|
Upd()
|
|
end)
|
|
local hBR, hBG, hBB = C("buttonHoverBg", 0.20, 0.12, 0.18, 1)
|
|
local hAR, hAG, hAB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
btn:SetScript("OnEnter", function()
|
|
btn:SetBackdropColor(hBR, hBG, hBB, 1)
|
|
btn:SetBackdropBorderColor(hAR, hAG, hAB, 0.8)
|
|
btnT:SetTextColor(1, 1, 1)
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
MakeBackdrop(btn, "buttonBg", "sepColor")
|
|
btnT:SetTextColor(bTR, bTG, bTB)
|
|
end)
|
|
return frame
|
|
end
|
|
|
|
-- ============================================
|
|
-- ROLE TOGGLE
|
|
-- ============================================
|
|
local function CreateRoleButton(parent, x, y)
|
|
local SW = 220
|
|
local SH = 26
|
|
local HALF = SW / 2
|
|
|
|
local frame = CreateFrame("Frame", "NP_Role", parent)
|
|
frame:SetWidth(SW)
|
|
frame:SetHeight(SH)
|
|
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
|
|
local bgR, bgG, bgB = C("panelBg", 0.08, 0.04, 0.08, 1)
|
|
local brR, brG, brB = C("panelBorder", 0.45, 0.25, 0.38, 1)
|
|
frame:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
frame:SetBackdropColor(bgR, bgG, bgB, 1)
|
|
frame:SetBackdropBorderColor(brR, brG, brB, 0.8)
|
|
|
|
local btnTank = CreateFrame("Button", nil, frame)
|
|
btnTank:SetWidth(HALF - 2)
|
|
btnTank:SetHeight(SH - 4)
|
|
btnTank:SetPoint("LEFT", frame, "LEFT", 2, 0)
|
|
btnTank:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
local tankT = btnTank:CreateFontString(nil, "OVERLAY")
|
|
tankT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
tankT:SetPoint("CENTER", btnTank, "CENTER", 0, 0)
|
|
tankT:SetText("坦克")
|
|
|
|
local btnDPS = CreateFrame("Button", nil, frame)
|
|
btnDPS:SetWidth(HALF - 2)
|
|
btnDPS:SetHeight(SH - 4)
|
|
btnDPS:SetPoint("RIGHT", frame, "RIGHT", -2, 0)
|
|
btnDPS:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
local dpsT = btnDPS:CreateFontString(nil, "OVERLAY")
|
|
dpsT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
dpsT:SetPoint("CENTER", btnDPS, "CENTER", 0, 0)
|
|
dpsT:SetText("输出")
|
|
|
|
local function Upd()
|
|
if (NP.playerRole or "DPS") == "TANK" then
|
|
btnTank:SetBackdropColor(0.15, 0.45, 0.15, 1)
|
|
btnTank:SetBackdropBorderColor(0.3, 0.8, 0.3, 0.9)
|
|
tankT:SetTextColor(0.4, 1.0, 0.4)
|
|
btnDPS:SetBackdropColor(bgR, bgG, bgB, 0.5)
|
|
btnDPS:SetBackdropBorderColor(brR, brG, brB, 0.3)
|
|
dpsT:SetTextColor(0.5, 0.5, 0.5)
|
|
else
|
|
btnTank:SetBackdropColor(bgR, bgG, bgB, 0.5)
|
|
btnTank:SetBackdropBorderColor(brR, brG, brB, 0.3)
|
|
tankT:SetTextColor(0.5, 0.5, 0.5)
|
|
btnDPS:SetBackdropColor(0.45, 0.12, 0.12, 1)
|
|
btnDPS:SetBackdropBorderColor(0.8, 0.3, 0.3, 0.9)
|
|
dpsT:SetTextColor(1.0, 0.4, 0.4)
|
|
end
|
|
end
|
|
Upd()
|
|
|
|
local function SetRole(role)
|
|
NP.playerRole = role
|
|
NP:SaveSettings()
|
|
Upd()
|
|
if NanamiPlates_Threat then NanamiPlates_Threat.BroadcastTankMode(true) end
|
|
NP.Print("角色: " .. role)
|
|
end
|
|
|
|
btnTank:SetScript("OnClick", function() SetRole("TANK") end)
|
|
btnDPS:SetScript("OnClick", function() SetRole("DPS") end)
|
|
|
|
return frame
|
|
end
|
|
|
|
-- ============================================
|
|
-- FORMAT OPTIONS
|
|
-- ============================================
|
|
local hpFmtOpts = {
|
|
{ value = 0, label = "隐藏" },
|
|
{ value = 1, label = "百分比" },
|
|
{ value = 2, label = "当前值" },
|
|
{ value = 3, label = "当前(百分比)" },
|
|
{ value = 4, label = "当前/最大" },
|
|
{ value = 5, label = "当前/最大 %" },
|
|
}
|
|
|
|
-- ============================================
|
|
-- TAB DEFINITIONS
|
|
-- ============================================
|
|
local TAB_DEFS = {
|
|
{ id = "hp", label = "血条" },
|
|
{ id = "cast", label = "施法条" },
|
|
{ id = "debuff", label = "减益" },
|
|
{ id = "target", label = "目标" },
|
|
{ id = "other", label = "其他" },
|
|
}
|
|
|
|
-- ============================================
|
|
-- TAB CONTENT BUILDERS
|
|
-- ============================================
|
|
local function BuildTab_HP(page)
|
|
local L = 20
|
|
local R = 260
|
|
local y = -10
|
|
|
|
SectionLabel(page, "-- 敌方 --", L, y)
|
|
y = y - 20
|
|
CreateSlider(page, "宽度", "healthbarWidth", 60, 220, 5, L, y)
|
|
CreateSlider(page, "高度", "healthbarHeight", 4, 30, 1, R, y)
|
|
y = y - 38
|
|
CreateSlider(page, "血量字号", "healthFontSize", 6, 18, 1, L, y)
|
|
CreateCycleButton(page, "血量格式", "healthTextFormat", hpFmtOpts, R, y + 6)
|
|
y = y - 38
|
|
CreateSlider(page, "名字字号", "nameFontSize", 6, 16, 1, L, y)
|
|
CreateSlider(page, "等级字号", "levelFontSize", 6, 16, 1, R, y)
|
|
y = y - 38
|
|
CreateSlider(page, "垂直偏移", "nameplateYOffset", -20, 40, 1, L, y)
|
|
|
|
y = y - 50
|
|
SectionLabel(page, "-- 友方 --", L, y)
|
|
y = y - 20
|
|
CreateSlider(page, "宽度", "friendHealthbarWidth", 40, 200, 5, L, y)
|
|
CreateSlider(page, "高度", "friendHealthbarHeight", 2, 20, 1, R, y)
|
|
y = y - 38
|
|
CreateSlider(page, "血量字号", "friendHealthFontSize", 6, 16, 1, L, y)
|
|
CreateCycleButton(page, "血量格式", "friendHealthTextFormat", hpFmtOpts, R, y + 6)
|
|
y = y - 38
|
|
CreateSlider(page, "名字字号", "friendNameFontSize", 6, 16, 1, L, y)
|
|
CreateSlider(page, "等级字号", "friendLevelFontSize", 6, 16, 1, R, y)
|
|
end
|
|
|
|
local function BuildTab_Cast(page)
|
|
local L = 20
|
|
local R = 260
|
|
local y = -10
|
|
|
|
SectionLabel(page, "-- 敌方施法条 --", L, y)
|
|
y = y - 20
|
|
CreateSlider(page, "宽度", "castbarWidth", 60, 220, 5, L, y)
|
|
CreateSlider(page, "高度", "castbarHeight", 4, 20, 1, R, y)
|
|
y = y - 36
|
|
CreateCheckbox(page, "显示法术图标", "showCastbarIcon", L, y)
|
|
|
|
y = y - 45
|
|
SectionLabel(page, "-- 友方施法条 --", L, y)
|
|
y = y - 20
|
|
CreateSlider(page, "宽度", "friendCastbarWidth", 40, 200, 5, L, y)
|
|
CreateSlider(page, "高度", "friendCastbarHeight", 2, 16, 1, R, y)
|
|
y = y - 36
|
|
CreateCheckbox(page, "显示法术图标", "friendShowCastbarIcon", L, y)
|
|
end
|
|
|
|
local function BuildTab_Debuff(page)
|
|
local L = 20
|
|
local R = 260
|
|
local y = -10
|
|
|
|
SectionLabel(page, "-- 减益效果 (Debuff) --", L, y)
|
|
y = y - 22
|
|
CreateCheckbox(page, "显示减益计时器", "showDebuffTimers", L, y, "在减益图标上显示倒计时")
|
|
y = y - 26
|
|
CreateCheckbox(page, "仅显示自己的减益", "showOnlyMyDebuffs", L, y, "只显示自己施放的减益效果")
|
|
y = y - 32
|
|
CreateSlider(page, "图标大小", "debuffIconSize", 12, 40, 1, L, y)
|
|
|
|
y = y - 50
|
|
SectionLabel(page, "-- 连击点 (星) --", L, y)
|
|
y = y - 22
|
|
CreateCheckbox(page, "显示连击点", "showComboPoints", L, y, "盗贼和德鲁伊(猫形态)的连击点显示")
|
|
y = y - 32
|
|
CreateSlider(page, "连击点大小", "comboPointsSize", 6, 20, 1, L, y)
|
|
end
|
|
|
|
local function CreateArrowStyleSelector(parent, x, y)
|
|
local ARROW_TEXTURE = "Interface\\AddOns\\Nanami-Plates\\img\\arrow"
|
|
local ARROW_TEXCOORDS = NP.ARROW_TEXCOORDS or {
|
|
{0, 0.5, 0, 0.5},
|
|
{0.5, 1, 0, 0.5},
|
|
{0, 0.5, 0.5, 1},
|
|
{0.5, 1, 0.5, 1},
|
|
}
|
|
|
|
local PREVIEW_SIZE = 40
|
|
local GAP = 8
|
|
local NUM_ARROWS = 4
|
|
|
|
local frame = CreateFrame("Frame", nil, parent)
|
|
frame:SetWidth(NUM_ARROWS * (PREVIEW_SIZE + GAP))
|
|
frame:SetHeight(PREVIEW_SIZE + 20)
|
|
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
|
|
local lbl = frame:CreateFontString(nil, "OVERLAY")
|
|
lbl:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
lbl:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
|
|
local lblR, lblG, lblB = C("labelText", 0.75, 0.75, 0.75, 1)
|
|
lbl:SetTextColor(lblR, lblG, lblB)
|
|
lbl:SetText("箭头样式")
|
|
|
|
local buttons = {}
|
|
local acR, acG, acB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
local brR, brG, brB = C("panelBorder", 0.35, 0.20, 0.30, 1)
|
|
|
|
local function UpdateSelection()
|
|
local cur = Settings.targetArrowStyle or 1
|
|
for i, btn in ipairs(buttons) do
|
|
if i == cur then
|
|
btn:SetBackdropBorderColor(acR, acG, acB, 1)
|
|
else
|
|
btn:SetBackdropBorderColor(brR, brG, brB, 0.5)
|
|
end
|
|
end
|
|
end
|
|
|
|
for i = 1, NUM_ARROWS do
|
|
local btn = CreateFrame("Button", nil, frame)
|
|
btn:SetWidth(PREVIEW_SIZE)
|
|
btn:SetHeight(PREVIEW_SIZE)
|
|
btn:SetPoint("TOPLEFT", frame, "TOPLEFT", (i - 1) * (PREVIEW_SIZE + GAP), -16)
|
|
btn:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
local bgR, bgG, bgB = C("panelBg", 0.08, 0.04, 0.08, 1)
|
|
btn:SetBackdropColor(bgR, bgG, bgB, 1)
|
|
|
|
local tex = btn:CreateTexture(nil, "ARTWORK")
|
|
tex:SetTexture(ARROW_TEXTURE)
|
|
tex:SetPoint("TOPLEFT", btn, "TOPLEFT", 3, -3)
|
|
tex:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -3, 3)
|
|
local coords = ARROW_TEXCOORDS[i]
|
|
tex:SetTexCoord(coords[1], coords[2], coords[3], coords[4])
|
|
tex:SetVertexColor(acR, acG, acB, 1)
|
|
|
|
btn.arrowIdx = i
|
|
btn:SetScript("OnClick", function()
|
|
Settings.targetArrowStyle = this.arrowIdx
|
|
NP:SaveSettings()
|
|
UpdateSelection()
|
|
if NP.UpdateAllArrows then NP.UpdateAllArrows() end
|
|
end)
|
|
local hvR, hvG, hvB = C("checkHoverBorder", 0.75, 0.40, 0.60, 1)
|
|
btn:SetScript("OnEnter", function()
|
|
if Settings.targetArrowStyle ~= this.arrowIdx then
|
|
this:SetBackdropBorderColor(hvR, hvG, hvB, 1)
|
|
end
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
UpdateSelection()
|
|
end)
|
|
|
|
table.insert(buttons, btn)
|
|
end
|
|
|
|
UpdateSelection()
|
|
return frame
|
|
end
|
|
|
|
local function BuildTab_Target(page)
|
|
local L = 20
|
|
local R = 260
|
|
local y = -10
|
|
|
|
SectionLabel(page, "-- 目标指示 --", L, y)
|
|
y = y - 22
|
|
CreateCheckbox(page, "显示目标箭头 >> <<", "showTargetGlow", L, y, "在当前目标姓名板两侧显示箭头")
|
|
y = y - 32
|
|
CreateArrowStyleSelector(page, L, y)
|
|
y = y - 68
|
|
CreateSlider(page, "箭头大小", "targetArrowSize", 12, 48, 2, L, y, nil, function()
|
|
if NP.UpdateAllArrows then NP.UpdateAllArrows() end
|
|
end)
|
|
CreateSlider(page, "箭头偏移", "targetArrowOffset", -20, 20, 1, R, y, nil, function()
|
|
if NP.UpdateAllArrows then NP.UpdateAllArrows() end
|
|
end)
|
|
y = y - 38
|
|
CreateSlider(page, "箭头染色", "targetArrowTint", 0, 1.0, 0.05, L, y, "pct")
|
|
CreateSlider(page, "非目标透明度", "nonTargetAlpha", 0.1, 1.0, 0.05, R, y, "pct")
|
|
|
|
y = y - 50
|
|
SectionLabel(page, "-- 仇恨与角色 --", L, y)
|
|
y = y - 26
|
|
CreateRoleButton(page, L, y)
|
|
end
|
|
|
|
local function BuildTab_Other(page)
|
|
local L = 20
|
|
local y = -10
|
|
|
|
SectionLabel(page, "-- 杂项 --", L, y)
|
|
y = y - 22
|
|
CreateCheckbox(page, "显示小动物姓名板", "showCritterNameplates", L, y, "显示兔子、松鼠等小动物的姓名板")
|
|
y = y - 26
|
|
CreateCheckbox(page, "显示法力条", "showManaBar", L, y)
|
|
y = y - 26
|
|
CreateCheckbox(page, "显示任务怪图标", "showQuestIcon", L, y, "在任务目标怪物的姓名板上显示\"!\"图标和进度 (配合pfQuest)")
|
|
y = y - 26
|
|
CreateCheckbox(page, "堆叠姓名板", "enableStacking", L, y, "当多个姓名板重叠时,自动将它们上下分开排列。\n关闭时姓名板会自由重叠在3D位置上。")
|
|
|
|
y = y - 50
|
|
|
|
local resetBtn = CreateFrame("Button", "NP_ResetBtn", page)
|
|
resetBtn:SetWidth(220)
|
|
resetBtn:SetHeight(26)
|
|
resetBtn:SetPoint("TOPLEFT", page, "TOPLEFT", L, y)
|
|
local rBgR, rBgG, rBgB = C("buttonBg", 0.18, 0.10, 0.15, 1)
|
|
local rBrR, rBrG, rBrB = C("sepColor", 0.45, 0.25, 0.38, 1)
|
|
resetBtn:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
resetBtn:SetBackdropColor(rBgR, rBgG, rBgB, 0.94)
|
|
resetBtn:SetBackdropBorderColor(rBrR, rBrG, rBrB, 1)
|
|
|
|
local rT = resetBtn:CreateFontString(nil, "OVERLAY")
|
|
rT:SetFont(NP.GetFont(), 10, NP.GetFontOutline())
|
|
rT:SetPoint("CENTER", resetBtn, "CENTER", 0, 0)
|
|
rT:SetText("重置所有设置 (重载UI)")
|
|
rT:SetTextColor(0.9, 0.4, 0.4)
|
|
|
|
resetBtn:SetScript("OnClick", function() NanamiPlatesDB = nil; ReloadUI() end)
|
|
resetBtn:SetScript("OnEnter", function()
|
|
resetBtn:SetBackdropBorderColor(1, 0.3, 0.3, 1)
|
|
rT:SetTextColor(1, 0.5, 0.5)
|
|
end)
|
|
resetBtn:SetScript("OnLeave", function()
|
|
resetBtn:SetBackdropBorderColor(rBrR, rBrG, rBrB, 1)
|
|
rT:SetTextColor(0.9, 0.4, 0.4)
|
|
end)
|
|
end
|
|
|
|
local TAB_BUILDERS = {
|
|
hp = BuildTab_HP,
|
|
cast = BuildTab_Cast,
|
|
debuff = BuildTab_Debuff,
|
|
target = BuildTab_Target,
|
|
other = BuildTab_Other,
|
|
}
|
|
|
|
-- ============================================
|
|
-- MAIN OPTIONS FRAME
|
|
-- ============================================
|
|
local function CreateOptionsFrame()
|
|
if optionsFrame then
|
|
if optionsFrame:IsShown() then optionsFrame:Hide() else optionsFrame:Show() end
|
|
return
|
|
end
|
|
|
|
local W = 540
|
|
local H = 440
|
|
local TAB_H = 28
|
|
local HEADER_H = 34
|
|
|
|
local f = CreateFrame("Frame", "NanamiPlatesOptions", UIParent)
|
|
f:SetWidth(W)
|
|
f:SetHeight(H)
|
|
f:SetPoint("CENTER", UIParent, "CENTER", 0, 50)
|
|
f:SetMovable(true)
|
|
f:EnableMouse(false)
|
|
f:SetFrameStrata("DIALOG")
|
|
f:SetToplevel(true)
|
|
f:SetClampedToScreen(true)
|
|
MakeBackdrop(f)
|
|
|
|
-- Title bar (only this area is draggable)
|
|
local header = CreateFrame("Frame", nil, f)
|
|
header:SetHeight(HEADER_H)
|
|
header:SetPoint("TOPLEFT", f, "TOPLEFT", 1, -1)
|
|
header:SetPoint("TOPRIGHT", f, "TOPRIGHT", -1, -1)
|
|
header:EnableMouse(true)
|
|
header:RegisterForDrag("LeftButton")
|
|
header:SetScript("OnDragStart", function() f:StartMoving() end)
|
|
header:SetScript("OnDragStop", function() f:StopMovingOrSizing() end)
|
|
local hR, hG, hB = C("headerBg", 0.14, 0.08, 0.12, 1)
|
|
header:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
|
|
header:SetBackdropColor(hR, hG, hB, 0.95)
|
|
|
|
local acR, acG, acB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
|
|
-- Logo icon
|
|
local logoIcon = header:CreateTexture(nil, "OVERLAY")
|
|
logoIcon:SetTexture("Interface\\AddOns\\Nanami-Plates\\img\\icon")
|
|
logoIcon:SetWidth(16)
|
|
logoIcon:SetHeight(16)
|
|
logoIcon:SetPoint("LEFT", header, "LEFT", 10, 0)
|
|
logoIcon:SetVertexColor(acR, acG, acB, 0.9)
|
|
|
|
local title = header:CreateFontString(nil, "OVERLAY")
|
|
title:SetFont(NP.GetFont(), 13, NP.GetFontOutline())
|
|
title:SetPoint("LEFT", logoIcon, "RIGHT", 6, 0)
|
|
title:SetTextColor(acR, acG, acB)
|
|
title:SetText("Nanami-Plates")
|
|
|
|
local verText = header:CreateFontString(nil, "OVERLAY")
|
|
verText:SetFont(NP.GetFont(), 9, NP.GetFontOutline())
|
|
verText:SetPoint("LEFT", title, "RIGHT", 8, 0)
|
|
verText:SetTextColor(0.5, 0.5, 0.5, 0.7)
|
|
verText:SetText("v1.0")
|
|
|
|
-- Close button with backdrop
|
|
local closeBtn = CreateFrame("Button", nil, header)
|
|
closeBtn:SetWidth(22)
|
|
closeBtn:SetHeight(22)
|
|
closeBtn:SetPoint("RIGHT", header, "RIGHT", -6, 0)
|
|
closeBtn:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
closeBtn:SetBackdropColor(0.15, 0.08, 0.12, 0.6)
|
|
closeBtn:SetBackdropBorderColor(0.35, 0.20, 0.30, 0.5)
|
|
local cT = closeBtn:CreateFontString(nil, "OVERLAY")
|
|
cT:SetFont(NP.GetFont(), 13, NP.GetFontOutline())
|
|
cT:SetPoint("CENTER", closeBtn, "CENTER", 0, 0)
|
|
cT:SetText("x")
|
|
cT:SetTextColor(0.7, 0.4, 0.5)
|
|
closeBtn:SetScript("OnClick", function() f:Hide() end)
|
|
closeBtn:SetScript("OnEnter", function()
|
|
cT:SetTextColor(1, 0.3, 0.4)
|
|
closeBtn:SetBackdropColor(0.3, 0.08, 0.08, 0.8)
|
|
closeBtn:SetBackdropBorderColor(0.8, 0.25, 0.25, 0.8)
|
|
end)
|
|
closeBtn:SetScript("OnLeave", function()
|
|
cT:SetTextColor(0.7, 0.4, 0.5)
|
|
closeBtn:SetBackdropColor(0.15, 0.08, 0.12, 0.6)
|
|
closeBtn:SetBackdropBorderColor(0.35, 0.20, 0.30, 0.5)
|
|
end)
|
|
|
|
-- Header divider
|
|
local headerDiv = f:CreateTexture(nil, "ARTWORK")
|
|
headerDiv:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
headerDiv:SetHeight(1)
|
|
headerDiv:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, 0)
|
|
headerDiv:SetPoint("TOPRIGHT", header, "BOTTOMRIGHT", 0, 0)
|
|
headerDiv:SetVertexColor(acR, acG, acB, 0.3)
|
|
|
|
-- Tab bar
|
|
local tabBar = CreateFrame("Frame", nil, f)
|
|
tabBar:SetHeight(TAB_H)
|
|
tabBar:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -1)
|
|
tabBar:SetPoint("TOPRIGHT", header, "BOTTOMRIGHT", 0, -1)
|
|
local tbBgR, tbBgG, tbBgB = C("sectionBg", 0.08, 0.05, 0.08, 1)
|
|
tabBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
|
|
tabBar:SetBackdropColor(tbBgR, tbBgG, tbBgB, 0.9)
|
|
|
|
-- Content area
|
|
local content = CreateFrame("Frame", nil, f)
|
|
content:SetPoint("TOPLEFT", tabBar, "BOTTOMLEFT", 0, -1)
|
|
content:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -1, 1)
|
|
|
|
-- Pages
|
|
local pages = {}
|
|
for _, def in ipairs(TAB_DEFS) do
|
|
local page = CreateFrame("Frame", nil, content)
|
|
page:SetAllPoints(content)
|
|
page:Hide()
|
|
if TAB_BUILDERS[def.id] then
|
|
TAB_BUILDERS[def.id](page)
|
|
end
|
|
pages[def.id] = page
|
|
end
|
|
|
|
-- Tab buttons
|
|
local tabs = {}
|
|
local tabW = (W - 2) / table.getn(TAB_DEFS)
|
|
|
|
local activeTabId = TAB_DEFS[1].id
|
|
|
|
local tabBgNR, tabBgNG, tabBgNB = C("tabBg", 0.10, 0.06, 0.10, 1)
|
|
local tabBrNR, tabBrNG, tabBrNB = C("tabBorder", 0.35, 0.20, 0.30, 1)
|
|
local tabBgAR, tabBgAG, tabBgAB = C("tabActiveBg", 0.20, 0.12, 0.18, 1)
|
|
local tabBrAR, tabBrAG, tabBrAB = C("tabActiveBorder", 0.9, 0.45, 0.7, 1)
|
|
local tabTxtNR, tabTxtNG, tabTxtNB = C("tabText", 0.6, 0.6, 0.6, 1)
|
|
local tabTxtAR, tabTxtAG, tabTxtAB = C("tabActiveText", 1.0, 0.9, 0.95, 1)
|
|
|
|
local function SetActiveTab(id)
|
|
activeTabId = id
|
|
for _, def in ipairs(TAB_DEFS) do
|
|
local tab = tabs[def.id]
|
|
local pg = pages[def.id]
|
|
if def.id == id then
|
|
pg:Show()
|
|
tab:SetBackdropColor(tabBgAR, tabBgAG, tabBgAB, 1)
|
|
tab:SetBackdropBorderColor(tabBrNR, tabBrNG, tabBrNB, 0.3)
|
|
tab.label:SetTextColor(tabTxtAR, tabTxtAG, tabTxtAB)
|
|
tab.indicator:Show()
|
|
else
|
|
pg:Hide()
|
|
tab:SetBackdropColor(tabBgNR, tabBgNG, tabBgNB, 1)
|
|
tab:SetBackdropBorderColor(tabBrNR, tabBrNG, tabBrNB, 0.3)
|
|
tab.label:SetTextColor(tabTxtNR, tabTxtNG, tabTxtNB)
|
|
tab.indicator:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
for i, def in ipairs(TAB_DEFS) do
|
|
local tabId = def.id
|
|
local tabLabel = def.label
|
|
|
|
local tab = CreateFrame("Button", nil, tabBar)
|
|
tab:SetWidth(tabW)
|
|
tab:SetHeight(TAB_H)
|
|
tab:SetPoint("TOPLEFT", tabBar, "TOPLEFT", (i - 1) * tabW, 0)
|
|
tab:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, tileSize = 0, edgeSize = 1,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
})
|
|
tab.tabId = tabId
|
|
|
|
local lbl = tab:CreateFontString(nil, "OVERLAY")
|
|
lbl:SetFont(NP.GetFont(), 11, NP.GetFontOutline())
|
|
lbl:SetPoint("CENTER", tab, "CENTER", 0, 0)
|
|
lbl:SetText(tabLabel)
|
|
tab.label = lbl
|
|
|
|
-- Active tab bottom indicator line
|
|
local ind = tab:CreateTexture(nil, "OVERLAY")
|
|
ind:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
ind:SetHeight(2)
|
|
ind:SetPoint("BOTTOMLEFT", tab, "BOTTOMLEFT", 4, 1)
|
|
ind:SetPoint("BOTTOMRIGHT", tab, "BOTTOMRIGHT", -4, 1)
|
|
ind:SetVertexColor(tabBrAR, tabBrAG, tabBrAB, 1)
|
|
ind:Hide()
|
|
tab.indicator = ind
|
|
|
|
tab:SetScript("OnClick", function() SetActiveTab(this.tabId) end)
|
|
tab:SetScript("OnEnter", function()
|
|
if activeTabId ~= this.tabId then
|
|
this:SetBackdropColor(tabBgAR * 0.7, tabBgAG * 0.7, tabBgAB * 0.7, 0.8)
|
|
this.label:SetTextColor(0.85, 0.85, 0.85)
|
|
end
|
|
end)
|
|
tab:SetScript("OnLeave", function()
|
|
if activeTabId ~= this.tabId then
|
|
this:SetBackdropColor(tabBgNR, tabBgNG, tabBgNB, 1)
|
|
this:SetBackdropBorderColor(tabBrNR, tabBrNG, tabBrNB, 0.3)
|
|
this.label:SetTextColor(tabTxtNR, tabTxtNG, tabTxtNB)
|
|
end
|
|
end)
|
|
|
|
tabs[tabId] = tab
|
|
end
|
|
|
|
SetActiveTab(TAB_DEFS[1].id)
|
|
|
|
optionsFrame = f
|
|
tinsert(UISpecialFrames, "NanamiPlatesOptions")
|
|
end
|
|
|
|
-- ============================================
|
|
-- MINIMAP BUTTON
|
|
-- ============================================
|
|
local function CreateMinimapButton()
|
|
if minimapButton then return end
|
|
|
|
local btnSize = 33
|
|
local btn = CreateFrame("Button", "NanamiPlatesMinimapBtn", Minimap)
|
|
btn:SetWidth(btnSize)
|
|
btn:SetHeight(btnSize)
|
|
btn:SetFrameStrata("MEDIUM")
|
|
btn:SetFrameLevel(Minimap:GetFrameLevel() + 5)
|
|
btn:SetMovable(true)
|
|
btn:EnableMouse(true)
|
|
btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
|
|
local savedAngle = NanamiPlatesDB and NanamiPlatesDB.minimapAngle or 220
|
|
|
|
local function UpdatePos(angle)
|
|
local rad = math.rad(angle)
|
|
btn:ClearAllPoints()
|
|
btn:SetPoint("CENTER", Minimap, "CENTER", math.cos(rad) * 80, math.sin(rad) * 80)
|
|
end
|
|
UpdatePos(savedAngle)
|
|
btn.angle = savedAngle
|
|
|
|
local icon = btn:CreateTexture(nil, "BACKGROUND")
|
|
icon:SetTexture("Interface\\AddOns\\Nanami-Plates\\img\\icon")
|
|
icon:SetWidth(20)
|
|
icon:SetHeight(20)
|
|
icon:SetPoint("CENTER", btn, "CENTER", 0, 0)
|
|
local iconR, iconG, iconB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
icon:SetVertexColor(iconR, iconG, iconB, 1)
|
|
|
|
local overlay = btn:CreateTexture(nil, "OVERLAY")
|
|
overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
|
|
overlay:SetWidth(52)
|
|
overlay:SetHeight(52)
|
|
overlay:SetPoint("CENTER", btn, "CENTER", 10, -10)
|
|
|
|
btn:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
|
|
|
|
local isDrag = false
|
|
btn:RegisterForDrag("LeftButton")
|
|
btn:SetScript("OnDragStart", function() isDrag = true end)
|
|
btn:SetScript("OnDragStop", function()
|
|
isDrag = false
|
|
if not NanamiPlatesDB then NanamiPlatesDB = {} end
|
|
NanamiPlatesDB.minimapAngle = btn.angle
|
|
end)
|
|
btn:SetScript("OnUpdate", function()
|
|
if not isDrag then return end
|
|
local cx, cy = GetCursorPosition()
|
|
local s = Minimap:GetEffectiveScale()
|
|
local mx, my = Minimap:GetCenter()
|
|
local angle = math.deg(math.atan2(cy / s - my, cx / s - mx))
|
|
btn.angle = angle
|
|
UpdatePos(angle)
|
|
end)
|
|
|
|
btn:SetScript("OnClick", function() CreateOptionsFrame() end)
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
icon:SetVertexColor(1, 1, 1, 1)
|
|
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
|
|
local aR, aG, aB = C("accent", 1.0, 0.5, 0.8, 1)
|
|
GameTooltip:SetText("Nanami-Plates 姓名板", aR, aG, aB)
|
|
GameTooltip:AddLine("左键点击打开设置", 0.8, 0.8, 0.8)
|
|
GameTooltip:AddLine("拖拽移动按钮位置", 0.6, 0.6, 0.6)
|
|
GameTooltip:Show()
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
icon:SetVertexColor(iconR, iconG, iconB, 1)
|
|
GameTooltip:Hide()
|
|
end)
|
|
|
|
minimapButton = btn
|
|
end
|
|
|
|
-- ============================================
|
|
-- INIT
|
|
-- ============================================
|
|
local initFrame = CreateFrame("Frame")
|
|
initFrame:RegisterEvent("PLAYER_LOGIN")
|
|
initFrame:SetScript("OnEvent", function() CreateMinimapButton() end)
|
|
|
|
-- ============================================
|
|
-- SLASH
|
|
-- ============================================
|
|
SLASH_NANAMIPLATES1 = "/np"
|
|
SLASH_NANAMIPLATES2 = "/nanamiplates"
|
|
SlashCmdList["NANAMIPLATES"] = function(msg)
|
|
msg = string.lower(msg or "")
|
|
-- trim leading/trailing spaces
|
|
msg = string.gsub(msg, "^%s+", "")
|
|
msg = string.gsub(msg, "%s+$", "")
|
|
if msg == "tank" then
|
|
NP.playerRole = (NP.playerRole == "TANK") and "DPS" or "TANK"
|
|
NP:SaveSettings()
|
|
NP.Print("角色: " .. NP.playerRole)
|
|
if NanamiPlates_Threat then NanamiPlates_Threat.BroadcastTankMode(true) end
|
|
elseif msg == "reset" then
|
|
NanamiPlatesDB = nil
|
|
ReloadUI()
|
|
elseif msg == "minimap" then
|
|
if minimapButton then
|
|
if minimapButton:IsShown() then minimapButton:Hide() else minimapButton:Show() end
|
|
end
|
|
elseif msg == "debug" then
|
|
local p = function(s) DEFAULT_CHAT_FRAME:AddMessage("|cffff88cc[NP]|r " .. s) end
|
|
if UnitExists("target") then
|
|
local SDB = NanamiPlates_SpellDB
|
|
p("|cff00ff00-- Debuff Debug --|r")
|
|
if not SDB then
|
|
p("|cffff0000SpellDB is nil!|r")
|
|
elseif not SDB.textureToSpell then
|
|
p("|cffff0000textureToSpell is nil!|r")
|
|
else
|
|
local count = 0
|
|
for _ in pairs(SDB.textureToSpell) do count = count + 1 end
|
|
p("textureToSpell entries: " .. count)
|
|
end
|
|
for i = 1, 16 do
|
|
local texture, stacks = UnitDebuff("target", i)
|
|
if not texture then break end
|
|
local texLookup = SDB and SDB.textureToSpell and SDB.textureToSpell[texture]
|
|
local prioLookup = SDB and SDB.debuffPriority and SDB.debuffPriority[texture]
|
|
local scanResult = SDB and SDB:ScanDebuff("target", i) or "nil"
|
|
local dur = 0
|
|
if SDB and scanResult and scanResult ~= "nil" and scanResult ~= "" then
|
|
dur = SDB:GetDuration(scanResult, 0) or 0
|
|
end
|
|
p(i .. ": |cffffcc00" .. tostring(texture) .. "|r")
|
|
p(" prio=|cffaaaaff" .. tostring(prioLookup) .. "|r tex=|cffaaffaa" .. tostring(texLookup) .. "|r scan=|cff00ffff" .. tostring(scanResult) .. "|r dur=" .. dur)
|
|
end
|
|
p("|cff00ff00-- End --|r")
|
|
else
|
|
p("No target")
|
|
end
|
|
else
|
|
CreateOptionsFrame()
|
|
end
|
|
end
|