680 lines
24 KiB
Lua
680 lines
24 KiB
Lua
local NanamiDPS = NanamiDPS
|
|
local L = NanamiDPS.L
|
|
local DataStore = NanamiDPS.DataStore
|
|
local Window = NanamiDPS.Window
|
|
|
|
local Options = {}
|
|
NanamiDPS.Options = Options
|
|
|
|
local optionsFrame = nil
|
|
local activeTabPage = nil
|
|
|
|
-----------------------------------------------------------------------
|
|
-- UI builder helpers
|
|
-----------------------------------------------------------------------
|
|
local function ApplyThemeColors(frame, category)
|
|
local A = SFrames.ActiveTheme
|
|
if not A then return end
|
|
if category == "header" and A.headerBg then
|
|
frame:SetBackdropColor(A.headerBg[1], A.headerBg[2], A.headerBg[3], A.headerBg[4] or 0.98)
|
|
elseif category == "panel" and A.panelBg then
|
|
frame:SetBackdropColor(A.panelBg[1], A.panelBg[2], A.panelBg[3], A.panelBg[4] or 0.9)
|
|
elseif category == "button" and A.buttonBg then
|
|
frame:SetBackdropColor(A.buttonBg[1], A.buttonBg[2], A.buttonBg[3], A.buttonBg[4] or 0.9)
|
|
if A.buttonBorder then
|
|
frame:SetBackdropBorderColor(A.buttonBorder[1], A.buttonBorder[2], A.buttonBorder[3], A.buttonBorder[4] or 0.8)
|
|
end
|
|
elseif category == "section" and A.sectionBg then
|
|
frame:SetBackdropColor(A.sectionBg[1], A.sectionBg[2], A.sectionBg[3], 0.5)
|
|
end
|
|
end
|
|
|
|
local function CreateSectionHeader(parent, text, yOffset)
|
|
local A = SFrames.ActiveTheme
|
|
local header = CreateFrame("Frame", nil, parent)
|
|
header:SetHeight(20)
|
|
header:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, yOffset)
|
|
header:SetPoint("TOPRIGHT", parent, "TOPRIGHT", 0, yOffset)
|
|
header:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 0,
|
|
})
|
|
if A and A.accent then
|
|
header:SetBackdropColor(A.accent[1], A.accent[2], A.accent[3], 0.12)
|
|
else
|
|
header:SetBackdropColor(0.3, 0.3, 0.3, 0.12)
|
|
end
|
|
|
|
local accent = header:CreateTexture(nil, "ARTWORK")
|
|
accent:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
accent:SetWidth(3)
|
|
accent:SetHeight(14)
|
|
accent:SetPoint("LEFT", header, "LEFT", 2, 0)
|
|
if A and A.accent then
|
|
accent:SetVertexColor(A.accent[1], A.accent[2], A.accent[3], 0.9)
|
|
else
|
|
accent:SetVertexColor(0.7, 0.7, 0.7, 0.9)
|
|
end
|
|
|
|
local label = SFrames:CreateFontString(header, 10, "LEFT")
|
|
label:SetPoint("LEFT", accent, "RIGHT", 6, 0)
|
|
if A and A.sectionTitle then
|
|
label:SetTextColor(A.sectionTitle[1], A.sectionTitle[2], A.sectionTitle[3])
|
|
end
|
|
label:SetText(text)
|
|
|
|
return header
|
|
end
|
|
|
|
local function CreateStyledCheckbox(parent, label, x, y, getValue, setValue)
|
|
local A = SFrames.ActiveTheme
|
|
|
|
local container = CreateFrame("Frame", nil, parent)
|
|
container:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
container:SetWidth(240)
|
|
container:SetHeight(20)
|
|
container:EnableMouse(true)
|
|
|
|
local check = CreateFrame("CheckButton", nil, container)
|
|
check:SetWidth(14)
|
|
check:SetHeight(14)
|
|
check:SetPoint("LEFT", container, "LEFT", 0, 0)
|
|
|
|
check:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 1,
|
|
insets = { left = 1, right = 1, top = 1, bottom = 1 },
|
|
})
|
|
if A and A.checkBg then
|
|
check:SetBackdropColor(A.checkBg[1], A.checkBg[2], A.checkBg[3], A.checkBg[4] or 0.9)
|
|
else
|
|
check:SetBackdropColor(0.12, 0.06, 0.09, 0.9)
|
|
end
|
|
if A and A.checkBorder then
|
|
check:SetBackdropBorderColor(A.checkBorder[1], A.checkBorder[2], A.checkBorder[3], A.checkBorder[4] or 0.8)
|
|
else
|
|
check:SetBackdropBorderColor(0.45, 0.3, 0.38, 0.8)
|
|
end
|
|
|
|
local checkMark = check:CreateTexture(nil, "OVERLAY")
|
|
checkMark:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
checkMark:SetWidth(8)
|
|
checkMark:SetHeight(8)
|
|
checkMark:SetPoint("CENTER", 0, 0)
|
|
if A and A.checkFill then
|
|
checkMark:SetVertexColor(A.checkFill[1], A.checkFill[2], A.checkFill[3], A.checkFill[4] or 1)
|
|
else
|
|
checkMark:SetVertexColor(0.7, 0.7, 0.7, 1)
|
|
end
|
|
|
|
local checked = getValue() and true or false
|
|
check:SetChecked(checked)
|
|
checkMark:SetAlpha(checked and 1 or 0)
|
|
|
|
local text = SFrames:CreateFontString(container, 10, "LEFT")
|
|
text:SetPoint("LEFT", check, "RIGHT", 6, 0)
|
|
text:SetText(label)
|
|
if A and A.text then
|
|
text:SetTextColor(A.text[1], A.text[2], A.text[3])
|
|
end
|
|
|
|
local function ToggleCheck()
|
|
local val = not check.isChecked
|
|
check.isChecked = val
|
|
check:SetChecked(val)
|
|
checkMark:SetAlpha(val and 1 or 0)
|
|
setValue(val)
|
|
Window:RefreshAll(true)
|
|
end
|
|
|
|
check.isChecked = checked
|
|
check:SetScript("OnClick", ToggleCheck)
|
|
container:SetScript("OnMouseUp", ToggleCheck)
|
|
|
|
container:SetScript("OnEnter", function()
|
|
if A and A.checkHoverBorder then
|
|
check:SetBackdropBorderColor(A.checkHoverBorder[1], A.checkHoverBorder[2], A.checkHoverBorder[3], A.checkHoverBorder[4] or 0.9)
|
|
else
|
|
check:SetBackdropBorderColor(0.7, 0.7, 0.7, 0.9)
|
|
end
|
|
end)
|
|
container:SetScript("OnLeave", function()
|
|
if A and A.checkBorder then
|
|
check:SetBackdropBorderColor(A.checkBorder[1], A.checkBorder[2], A.checkBorder[3], A.checkBorder[4] or 0.8)
|
|
else
|
|
check:SetBackdropBorderColor(0.45, 0.3, 0.38, 0.8)
|
|
end
|
|
end)
|
|
|
|
return container
|
|
end
|
|
|
|
local function CreateStyledSlider(parent, label, x, y, minVal, maxVal, step, getValue, setValue, formatFn)
|
|
local A = SFrames.ActiveTheme
|
|
|
|
local container = CreateFrame("Frame", nil, parent)
|
|
container:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
container:SetWidth(260)
|
|
container:SetHeight(36)
|
|
|
|
local titleText = SFrames:CreateFontString(container, 9, "LEFT")
|
|
titleText:SetPoint("TOPLEFT", container, "TOPLEFT", 0, 0)
|
|
titleText:SetText(label)
|
|
if A and A.text then
|
|
titleText:SetTextColor(A.text[1], A.text[2], A.text[3])
|
|
end
|
|
|
|
local slider = CreateFrame("Slider", nil, container)
|
|
slider:SetPoint("TOPLEFT", container, "TOPLEFT", 0, -14)
|
|
slider:SetWidth(200)
|
|
slider:SetHeight(12)
|
|
slider:SetOrientation("HORIZONTAL")
|
|
slider:SetMinMaxValues(minVal, maxVal)
|
|
slider:SetValueStep(step)
|
|
slider:SetValue(getValue())
|
|
slider:EnableMouseWheel(1)
|
|
|
|
slider:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 1,
|
|
insets = { left = 1, right = 1, top = 1, bottom = 1 },
|
|
})
|
|
if A and A.sliderTrack then
|
|
slider:SetBackdropColor(A.sliderTrack[1], A.sliderTrack[2], A.sliderTrack[3], A.sliderTrack[4] or 0.9)
|
|
else
|
|
slider:SetBackdropColor(0.12, 0.06, 0.09, 0.9)
|
|
end
|
|
if A and A.buttonBorder then
|
|
slider:SetBackdropBorderColor(A.buttonBorder[1], A.buttonBorder[2], A.buttonBorder[3], A.buttonBorder[4] or 0.8)
|
|
else
|
|
slider:SetBackdropBorderColor(0.35, 0.25, 0.3, 0.8)
|
|
end
|
|
|
|
slider:SetThumbTexture("Interface\\Buttons\\WHITE8X8")
|
|
local thumb = slider:GetThumbTexture()
|
|
thumb:SetWidth(8)
|
|
thumb:SetHeight(12)
|
|
if A and A.sliderThumb then
|
|
thumb:SetVertexColor(A.sliderThumb[1], A.sliderThumb[2], A.sliderThumb[3], A.sliderThumb[4] or 0.95)
|
|
else
|
|
thumb:SetVertexColor(0.7, 0.7, 0.7, 0.95)
|
|
end
|
|
|
|
local valText = SFrames:CreateFontString(container, 10, "LEFT")
|
|
valText:SetPoint("LEFT", slider, "RIGHT", 10, 0)
|
|
valText:SetWidth(40)
|
|
|
|
local function UpdateDisplay(val)
|
|
if formatFn then
|
|
valText:SetText(formatFn(val))
|
|
else
|
|
valText:SetText(tostring(math.floor(val + 0.5)))
|
|
end
|
|
end
|
|
UpdateDisplay(getValue())
|
|
if A and A.accent then
|
|
valText:SetTextColor(A.accent[1], A.accent[2], A.accent[3], 1)
|
|
end
|
|
|
|
slider:SetScript("OnValueChanged", function()
|
|
local val = this:GetValue()
|
|
UpdateDisplay(val)
|
|
setValue(val)
|
|
end)
|
|
|
|
slider:SetScript("OnMouseUp", function()
|
|
Window:RefreshAll(true)
|
|
end)
|
|
|
|
slider:SetScript("OnMouseWheel", function()
|
|
local val = slider:GetValue()
|
|
if arg1 > 0 then
|
|
slider:SetValue(math.min(val + step, maxVal))
|
|
else
|
|
slider:SetValue(math.max(val - step, minVal))
|
|
end
|
|
end)
|
|
|
|
return container
|
|
end
|
|
|
|
local function CreateActionButton(parent, text, x, y, width, onClick)
|
|
local A = SFrames.ActiveTheme
|
|
|
|
local btn = CreateFrame("Button", nil, parent)
|
|
btn:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
btn:SetWidth(width or 120)
|
|
btn:SetHeight(22)
|
|
|
|
btn:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
edgeFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 1,
|
|
insets = { left = 1, right = 1, top = 1, bottom = 1 },
|
|
})
|
|
if A and A.buttonBg then
|
|
btn:SetBackdropColor(A.buttonBg[1], A.buttonBg[2], A.buttonBg[3], A.buttonBg[4] or 0.9)
|
|
else
|
|
btn:SetBackdropColor(0.2, 0.1, 0.15, 0.9)
|
|
end
|
|
if A and A.buttonBorder then
|
|
btn:SetBackdropBorderColor(A.buttonBorder[1], A.buttonBorder[2], A.buttonBorder[3], A.buttonBorder[4] or 0.8)
|
|
else
|
|
btn:SetBackdropBorderColor(0.5, 0.35, 0.42, 0.8)
|
|
end
|
|
|
|
local label = SFrames:CreateFontString(btn, 10, "CENTER")
|
|
label:SetAllPoints()
|
|
label:SetText(text)
|
|
|
|
btn:SetScript("OnClick", onClick)
|
|
btn:SetScript("OnEnter", function()
|
|
if A and A.buttonHoverBg then
|
|
this:SetBackdropColor(A.buttonHoverBg[1], A.buttonHoverBg[2], A.buttonHoverBg[3], A.buttonHoverBg[4] or 0.3)
|
|
else
|
|
this:SetBackdropColor(0.3, 0.3, 0.3, 0.2)
|
|
end
|
|
if A and A.accent then
|
|
this:SetBackdropBorderColor(A.accent[1], A.accent[2], A.accent[3], 0.9)
|
|
else
|
|
this:SetBackdropBorderColor(0.7, 0.7, 0.7, 0.9)
|
|
end
|
|
end)
|
|
btn:SetScript("OnLeave", function()
|
|
if A and A.buttonBg then
|
|
this:SetBackdropColor(A.buttonBg[1], A.buttonBg[2], A.buttonBg[3], A.buttonBg[4] or 0.9)
|
|
else
|
|
this:SetBackdropColor(0.2, 0.1, 0.15, 0.9)
|
|
end
|
|
if A and A.buttonBorder then
|
|
this:SetBackdropBorderColor(A.buttonBorder[1], A.buttonBorder[2], A.buttonBorder[3], A.buttonBorder[4] or 0.8)
|
|
else
|
|
this:SetBackdropBorderColor(0.5, 0.35, 0.42, 0.8)
|
|
end
|
|
end)
|
|
|
|
return btn
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- Tab system
|
|
-----------------------------------------------------------------------
|
|
local function CreateTab(parent, tabIndex, text, tabBar, contentParent, totalTabs)
|
|
local A = SFrames.ActiveTheme
|
|
local tabWidth = math.floor((parent:GetWidth() - 2) / totalTabs)
|
|
|
|
local tab = CreateFrame("Button", nil, tabBar)
|
|
tab:SetWidth(tabWidth)
|
|
tab:SetHeight(20)
|
|
|
|
if tabIndex == 1 then
|
|
tab:SetPoint("TOPLEFT", tabBar, "TOPLEFT", 1, 0)
|
|
else
|
|
tab:SetPoint("LEFT", tabBar.tabs[tabIndex - 1], "RIGHT", 0, 0)
|
|
end
|
|
|
|
tab:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 0,
|
|
})
|
|
if A and A.tabBg then
|
|
tab:SetBackdropColor(A.tabBg[1], A.tabBg[2], A.tabBg[3], A.tabBg[4] or 0.6)
|
|
else
|
|
tab:SetBackdropColor(0.12, 0.06, 0.09, 0.6)
|
|
end
|
|
|
|
local label = SFrames:CreateFontString(tab, 9, "CENTER")
|
|
label:SetAllPoints()
|
|
label:SetText(text)
|
|
if A and A.tabText then
|
|
label:SetTextColor(A.tabText[1], A.tabText[2], A.tabText[3])
|
|
end
|
|
tab.label = label
|
|
|
|
tab.tabIndex = tabIndex
|
|
tab.page = CreateFrame("Frame", nil, contentParent)
|
|
tab.page:SetAllPoints(contentParent)
|
|
tab.page:Hide()
|
|
|
|
tab:SetScript("OnClick", function()
|
|
Options:SwitchTab(parent, tabIndex)
|
|
end)
|
|
|
|
tab:SetScript("OnEnter", function()
|
|
if activeTabPage ~= this.page then
|
|
if A and A.buttonHoverBg then
|
|
this:SetBackdropColor(A.buttonHoverBg[1], A.buttonHoverBg[2], A.buttonHoverBg[3], 0.3)
|
|
else
|
|
this:SetBackdropColor(0.3, 0.3, 0.3, 0.15)
|
|
end
|
|
end
|
|
end)
|
|
tab:SetScript("OnLeave", function()
|
|
if activeTabPage ~= this.page then
|
|
if A and A.tabBg then
|
|
this:SetBackdropColor(A.tabBg[1], A.tabBg[2], A.tabBg[3], A.tabBg[4] or 0.6)
|
|
else
|
|
this:SetBackdropColor(0.12, 0.06, 0.09, 0.6)
|
|
end
|
|
end
|
|
end)
|
|
|
|
return tab
|
|
end
|
|
|
|
function Options:SwitchTab(frame, tabIndex)
|
|
local A = SFrames.ActiveTheme
|
|
local tabBar = frame.tabBar
|
|
if not tabBar or not tabBar.tabs then return end
|
|
|
|
for _, tab in ipairs(tabBar.tabs) do
|
|
if A and A.tabBg then
|
|
tab:SetBackdropColor(A.tabBg[1], A.tabBg[2], A.tabBg[3], A.tabBg[4] or 0.6)
|
|
else
|
|
tab:SetBackdropColor(0.12, 0.06, 0.09, 0.6)
|
|
end
|
|
if A and A.tabText then
|
|
tab.label:SetTextColor(A.tabText[1], A.tabText[2], A.tabText[3])
|
|
else
|
|
tab.label:SetTextColor(0.7, 0.7, 0.7)
|
|
end
|
|
tab.page:Hide()
|
|
end
|
|
|
|
local active = tabBar.tabs[tabIndex]
|
|
if active then
|
|
if A and A.tabActiveBg then
|
|
active:SetBackdropColor(A.tabActiveBg[1], A.tabActiveBg[2], A.tabActiveBg[3], A.tabActiveBg[4] or 0.3)
|
|
else
|
|
active:SetBackdropColor(0.3, 0.3, 0.3, 0.2)
|
|
end
|
|
if A and A.tabActiveText then
|
|
active.label:SetTextColor(A.tabActiveText[1], A.tabActiveText[2], A.tabActiveText[3])
|
|
else
|
|
active.label:SetTextColor(1, 0.85, 0.9)
|
|
end
|
|
active.page:Show()
|
|
activeTabPage = active.page
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- Build the options panel
|
|
-----------------------------------------------------------------------
|
|
function Options:CreatePanel()
|
|
if optionsFrame then return optionsFrame end
|
|
|
|
local A = SFrames.ActiveTheme
|
|
|
|
optionsFrame = CreateFrame("Frame", "NanamiDPSOptions", UIParent)
|
|
optionsFrame:SetWidth(340)
|
|
optionsFrame:SetHeight(460)
|
|
optionsFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
|
|
optionsFrame:SetMovable(true)
|
|
optionsFrame:EnableMouse(true)
|
|
optionsFrame:SetClampedToScreen(true)
|
|
optionsFrame:SetFrameStrata("DIALOG")
|
|
|
|
SFrames:CreateRoundBackdrop(optionsFrame)
|
|
|
|
-- Title bar
|
|
local titleBar = CreateFrame("Frame", nil, optionsFrame)
|
|
titleBar:SetHeight(24)
|
|
titleBar:SetPoint("TOPLEFT", optionsFrame, "TOPLEFT", 4, -4)
|
|
titleBar:SetPoint("TOPRIGHT", optionsFrame, "TOPRIGHT", -4, -4)
|
|
titleBar:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 0,
|
|
})
|
|
ApplyThemeColors(titleBar, "header")
|
|
if not (A and A.headerBg) then
|
|
titleBar:SetBackdropColor(0.06, 0.06, 0.08, 0.98)
|
|
end
|
|
titleBar:EnableMouse(true)
|
|
titleBar:RegisterForDrag("LeftButton")
|
|
titleBar:SetScript("OnDragStart", function() optionsFrame:StartMoving() end)
|
|
titleBar:SetScript("OnDragStop", function() optionsFrame:StopMovingOrSizing() end)
|
|
|
|
local titleText = SFrames:CreateFontString(titleBar, 11, "CENTER")
|
|
titleText:SetPoint("LEFT", titleBar, "LEFT", 8, 0)
|
|
titleText:SetPoint("RIGHT", titleBar, "RIGHT", -28, 0)
|
|
local accentHex = (A and A.accentHex) or "ffFF88AA"
|
|
titleText:SetText("|c" .. accentHex .. "Nanami|r DPS - " .. L["Settings"])
|
|
|
|
local verText = SFrames:CreateFontString(titleBar, 8, "RIGHT")
|
|
verText:SetPoint("RIGHT", titleBar, "RIGHT", -24, -4)
|
|
verText:SetText("|cff888888v" .. NanamiDPS.version)
|
|
|
|
local closeBtn = CreateFrame("Button", nil, titleBar)
|
|
closeBtn:SetWidth(18)
|
|
closeBtn:SetHeight(18)
|
|
closeBtn:SetPoint("RIGHT", titleBar, "RIGHT", -3, 0)
|
|
local closeIcon = SFrames:CreateIcon(closeBtn, "close", 12)
|
|
closeIcon:SetPoint("CENTER", 0, 0)
|
|
closeBtn:SetScript("OnClick", function() optionsFrame:Hide() end)
|
|
closeBtn:SetScript("OnEnter", function()
|
|
closeIcon:SetVertexColor(1, 0.3, 0.3)
|
|
end)
|
|
closeBtn:SetScript("OnLeave", function()
|
|
closeIcon:SetVertexColor(1, 1, 1)
|
|
end)
|
|
|
|
-- Tab bar
|
|
local tabBar = CreateFrame("Frame", nil, optionsFrame)
|
|
tabBar:SetHeight(20)
|
|
tabBar:SetPoint("TOPLEFT", titleBar, "BOTTOMLEFT", 0, 0)
|
|
tabBar:SetPoint("TOPRIGHT", titleBar, "BOTTOMRIGHT", 0, 0)
|
|
tabBar:SetBackdrop({
|
|
bgFile = "Interface\\Buttons\\WHITE8X8",
|
|
tile = false, edgeSize = 0,
|
|
})
|
|
if A and A.sectionBg then
|
|
tabBar:SetBackdropColor(A.sectionBg[1], A.sectionBg[2], A.sectionBg[3], A.sectionBg[4] or 0.95)
|
|
else
|
|
tabBar:SetBackdropColor(0.05, 0.03, 0.04, 0.95)
|
|
end
|
|
tabBar.tabs = {}
|
|
optionsFrame.tabBar = tabBar
|
|
|
|
local contentArea = CreateFrame("Frame", nil, optionsFrame)
|
|
contentArea:SetPoint("TOPLEFT", tabBar, "BOTTOMLEFT", 12, -8)
|
|
contentArea:SetPoint("BOTTOMRIGHT", optionsFrame, "BOTTOMRIGHT", -12, 14)
|
|
|
|
local tabLabels = { L["Display Settings"], L["Data Settings"], L["Window Settings"] }
|
|
for i, name in ipairs(tabLabels) do
|
|
local tab = CreateTab(optionsFrame, i, name, tabBar, contentArea, table.getn(tabLabels))
|
|
tabBar.tabs[i] = tab
|
|
end
|
|
|
|
local cfg = NanamiDPS.config or {}
|
|
|
|
---------------------------------------------------------------
|
|
-- Tab 1: Display Settings
|
|
---------------------------------------------------------------
|
|
local page1 = tabBar.tabs[1].page
|
|
local y = 0
|
|
|
|
CreateSectionHeader(page1, L["Bar Height"], y)
|
|
y = y - 24
|
|
CreateStyledSlider(page1, "", 8, y, 10, 30, 1,
|
|
function() return cfg.barHeight or 16 end,
|
|
function(v) cfg.barHeight = math.floor(v + 0.5) end)
|
|
y = y - 34
|
|
|
|
CreateSectionHeader(page1, L["Bar Spacing"], y)
|
|
y = y - 24
|
|
CreateStyledSlider(page1, "", 8, y, 0, 5, 1,
|
|
function() return cfg.barSpacing or 1 end,
|
|
function(v) cfg.barSpacing = math.floor(v + 0.5) end)
|
|
y = y - 34
|
|
|
|
CreateSectionHeader(page1, L["Font Size"], y)
|
|
y = y - 24
|
|
CreateStyledSlider(page1, "", 8, y, 7, 16, 1,
|
|
function() return cfg.fontSize or 10 end,
|
|
function(v) cfg.fontSize = math.floor(v + 0.5) end)
|
|
y = y - 34
|
|
|
|
CreateSectionHeader(page1, L["Backdrop Alpha"], y)
|
|
y = y - 24
|
|
CreateStyledSlider(page1, "", 8, y, 0, 100, 5,
|
|
function() return (cfg.backdropAlpha or 0.92) * 100 end,
|
|
function(v) cfg.backdropAlpha = v / 100 end,
|
|
function(v) return math.floor(v + 0.5) .. "%" end)
|
|
y = y - 40
|
|
|
|
CreateStyledCheckbox(page1, L["Show Class Icons"], 8, y,
|
|
function() return cfg.showClassIcons end,
|
|
function(v) cfg.showClassIcons = v end)
|
|
|
|
---------------------------------------------------------------
|
|
-- Tab 2: Data Settings
|
|
---------------------------------------------------------------
|
|
local page2 = tabBar.tabs[2].page
|
|
y = 0
|
|
|
|
CreateSectionHeader(page2, L["Data Settings"], y)
|
|
y = y - 28
|
|
|
|
CreateStyledCheckbox(page2, L["Track All Units"], 8, y,
|
|
function() return cfg.trackAllUnits end,
|
|
function(v) cfg.trackAllUnits = v end)
|
|
y = y - 26
|
|
|
|
CreateStyledCheckbox(page2, L["Merge Pets"], 8, y,
|
|
function() return cfg.mergePets end,
|
|
function(v) cfg.mergePets = v end)
|
|
y = y - 36
|
|
|
|
CreateSectionHeader(page2, L["Max Segments"], y)
|
|
y = y - 24
|
|
CreateStyledSlider(page2, "", 8, y, 3, 30, 1,
|
|
function() return cfg.maxSegments or 10 end,
|
|
function(v) cfg.maxSegments = math.floor(v + 0.5) end)
|
|
y = y - 50
|
|
|
|
CreateSectionHeader(page2, L["Reset"], y)
|
|
y = y - 28
|
|
|
|
CreateActionButton(page2, "|cffff4444" .. L["Reset All Data"], 8, y, 150, function()
|
|
local dialog = StaticPopupDialogs["NANAMI_DPS_CONFIRM"]
|
|
dialog.text = L["Reset Data?"]
|
|
dialog.OnAccept = function() DataStore:ResetAll() end
|
|
StaticPopup_Show("NANAMI_DPS_CONFIRM")
|
|
end)
|
|
|
|
---------------------------------------------------------------
|
|
-- Tab 3: Window Settings
|
|
---------------------------------------------------------------
|
|
local page3 = tabBar.tabs[3].page
|
|
y = 0
|
|
|
|
CreateSectionHeader(page3, L["Window Settings"], y)
|
|
y = y - 28
|
|
|
|
CreateStyledCheckbox(page3, L["Lock Windows"], 8, y,
|
|
function() return cfg.locked end,
|
|
function(v) cfg.locked = v end)
|
|
y = y - 36
|
|
|
|
CreateSectionHeader(page3, L["Create New Window"], y)
|
|
y = y - 28
|
|
|
|
CreateActionButton(page3, L["Create New Window"], 8, y, 150, function()
|
|
Window:CreateNewWindow()
|
|
end)
|
|
|
|
-- Activate first tab
|
|
self:SwitchTab(optionsFrame, 1)
|
|
|
|
optionsFrame:Hide()
|
|
return optionsFrame
|
|
end
|
|
|
|
function Options:Toggle()
|
|
local panel = self:CreatePanel()
|
|
if panel:IsShown() then
|
|
panel:Hide()
|
|
else
|
|
panel:Show()
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------------------
|
|
-- Slash commands
|
|
-----------------------------------------------------------------------
|
|
SLASH_NANAMIDPS1 = "/nanami"
|
|
SLASH_NANAMIDPS2 = "/ndps"
|
|
|
|
SlashCmdList["NANAMIDPS"] = function(msg)
|
|
msg = string.lower(msg or "")
|
|
msg = NanamiDPS.trim(msg)
|
|
|
|
if msg == "" or msg == "toggle" then
|
|
Window:ToggleVisibility()
|
|
elseif msg == "reset" then
|
|
DataStore:ResetAll()
|
|
local chatHex = (SFrames.ActiveTheme and SFrames.ActiveTheme.accentHex) or "ffFF88AA"
|
|
DEFAULT_CHAT_FRAME:AddMessage("|c" .. chatHex .. "Nanami DPS|r: " .. L["Data Reset"])
|
|
elseif msg == "config" or msg == "options" or msg == "settings" then
|
|
Options:Toggle()
|
|
elseif msg == "lock" then
|
|
local cfg = NanamiDPS.config or {}
|
|
cfg.locked = not cfg.locked
|
|
local chatHex = (SFrames.ActiveTheme and SFrames.ActiveTheme.accentHex) or "ffFF88AA"
|
|
DEFAULT_CHAT_FRAME:AddMessage("|c" .. chatHex .. "Nanami DPS|r: " .. (cfg.locked and L["Windows Locked"] or L["Windows Unlocked"]))
|
|
elseif msg == "report" then
|
|
local win = NanamiDPS.windows and NanamiDPS.windows[1]
|
|
if win then
|
|
local mod = NanamiDPS.modules[win.activeModuleName]
|
|
local seg = DataStore:GetSegment(win.segmentIndex or 1)
|
|
if mod and mod.GetReportLines then
|
|
local lines = mod:GetReportLines(seg, 5)
|
|
local modName = mod:GetName()
|
|
local segName = (win.segmentIndex == 0) and L["Total"] or L["Current"]
|
|
local chatHex = (SFrames.ActiveTheme and SFrames.ActiveTheme.accentHex) or "ffFF88AA"
|
|
DEFAULT_CHAT_FRAME:AddMessage("|c" .. chatHex .. "Nanami DPS|r - " .. segName .. " " .. modName .. ":")
|
|
for _, line in ipairs(lines) do
|
|
DEFAULT_CHAT_FRAME:AddMessage(" " .. line)
|
|
end
|
|
end
|
|
end
|
|
elseif string.find(msg, "^report ") then
|
|
local _, _, channel, countStr = string.find(msg, "^report%s+(%a+)%s*(%d*)")
|
|
local count = tonumber(countStr) or 5
|
|
local win = NanamiDPS.windows and NanamiDPS.windows[1]
|
|
if win and channel then
|
|
local mod = NanamiDPS.modules[win.activeModuleName]
|
|
local seg = DataStore:GetSegment(win.segmentIndex or 1)
|
|
if mod and mod.GetReportLines then
|
|
local lines = mod:GetReportLines(seg, count)
|
|
local modName = mod:GetName()
|
|
local segName = (win.segmentIndex == 0) and L["Total"] or L["Current"]
|
|
channel = string.upper(channel)
|
|
SendChatMessage("Nanami DPS - " .. segName .. " " .. modName .. ":", channel)
|
|
for _, line in ipairs(lines) do
|
|
SendChatMessage(line, channel)
|
|
end
|
|
end
|
|
end
|
|
elseif msg == "new" or msg == "newwindow" then
|
|
Window:CreateNewWindow()
|
|
else
|
|
local chatHex = (SFrames.ActiveTheme and SFrames.ActiveTheme.accentHex) or "ffFF88AA"
|
|
DEFAULT_CHAT_FRAME:AddMessage("|c" .. chatHex .. "Nanami DPS|r " .. L["Commands"] .. ":")
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps toggle - " .. L["Show/Hide"])
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps reset - " .. L["Reset All Data"])
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps config - " .. L["Open Settings"])
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps lock - " .. L["Lock/Unlock"])
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps report - " .. L["Report to chat"])
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps report [channel] [count]")
|
|
DEFAULT_CHAT_FRAME:AddMessage(" /ndps new - " .. L["Create New Window"])
|
|
end
|
|
end
|
|
|
|
NanamiDPS:RegisterCallback("INIT", "Options", function()
|
|
Options:CreatePanel()
|
|
end)
|