initial commit
This commit is contained in:
287
Core/UI/MainUI/Settings/Core.lua
Normal file
287
Core/UI/MainUI/Settings/Core.lua
Normal file
@@ -0,0 +1,287 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Settings = TSM.MainUI:NewPackage("Settings")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Wow = TSM.Include("Util.Wow")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settingPages = {
|
||||
top = {},
|
||||
middle = {},
|
||||
bottom = {},
|
||||
},
|
||||
callback = {},
|
||||
childSettingsPages = {},
|
||||
sectionCollapsed = {},
|
||||
}
|
||||
local SECTIONS = { "top", "middle" }
|
||||
local SETTING_PATH_SEP = "`"
|
||||
local SETTING_LABEL_WIDTH = 400
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Settings.OnInitialize()
|
||||
TSM.MainUI.RegisterTopLevelPage(L["Settings"], private.GetSettingsFrame)
|
||||
end
|
||||
|
||||
function Settings.RegisterSettingPage(name, section, callback)
|
||||
assert(tContains(SECTIONS, section))
|
||||
tinsert(private.settingPages[section], name)
|
||||
private.callback[name] = callback
|
||||
end
|
||||
|
||||
function Settings.RegisterChildSettingPage(parentName, childName, callback)
|
||||
local path = parentName..SETTING_PATH_SEP..childName
|
||||
private.childSettingsPages[parentName] = private.childSettingsPages[parentName] or {}
|
||||
tinsert(private.childSettingsPages[parentName], childName)
|
||||
private.callback[path] = callback
|
||||
end
|
||||
|
||||
function Settings.CreateSettingLine(id, labelText, width)
|
||||
width = width or SETTING_LABEL_WIDTH
|
||||
|
||||
return UIElements.New("Frame", id)
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(26)
|
||||
:SetMargin(0, 0, 0, 16)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth(width)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(labelText)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.CreateHeading(id, text)
|
||||
return UIElements.New("Text", id)
|
||||
:SetHeight(19)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(text)
|
||||
end
|
||||
|
||||
function Settings.CreateInputWithReset(id, label, context, validate)
|
||||
local scope, namespace, key = strsplit(".", context)
|
||||
local validateFunc, validateContext = nil, nil
|
||||
if type(validate) == "table" then
|
||||
validateFunc = "CUSTOM_PRICE"
|
||||
validateContext = validate
|
||||
elseif type(validate) == "function" then
|
||||
validateFunc = validate
|
||||
elseif validate == nil then
|
||||
validateFunc = "CUSTOM_PRICE"
|
||||
else
|
||||
error("Invalid validate: "..tostring(validate))
|
||||
end
|
||||
return UIElements.New("Frame", id)
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetHeight(18)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(label)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc(validateFunc, validateContext)
|
||||
:SetSettingInfo(TSM.db[scope][namespace], key)
|
||||
:SetScript("OnValueChanged", private.InputOnValueChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("ActionButton", "resetButton")
|
||||
:SetWidth(108)
|
||||
:SetText(L["Reset"])
|
||||
:SetDisabled(TSM.db[scope][namespace][key] == TSM.db:GetDefault(scope, namespace, key))
|
||||
:SetScript("OnClick", private.ResetBtnOnClick)
|
||||
:SetContext(context)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.CreateExpandableSection(pageName, id, text, description, descriptionHeight)
|
||||
return UIElements.New("CollapsibleContainer", id)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetMargin(0, 0, 0, 8)
|
||||
:SetContextTable(private.sectionCollapsed, pageName..text)
|
||||
:SetHeadingText(text)
|
||||
:AddChild(UIElements.New("Text", "description")
|
||||
:SetHeight(descriptionHeight or 20)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(description)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.PromptToReload()
|
||||
StaticPopupDialogs["TSMReloadPrompt"] = StaticPopupDialogs["TSMReloadPrompt"] or {
|
||||
text = L["You must reload your UI for these settings to take effect. Reload now?"],
|
||||
button1 = YES,
|
||||
button2 = NO,
|
||||
timeout = 0,
|
||||
OnAccept = ReloadUI,
|
||||
}
|
||||
Wow.ShowStaticPopupDialog("TSMReloadPrompt")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetSettingsFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "settings")
|
||||
local defaultPage = private.settingPages.top[1]
|
||||
|
||||
local frame = UIElements.New("Frame", "settings")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("Frame", "settingNavigation")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth(160)
|
||||
:SetPadding(12, 12, 1, 9)
|
||||
:AddChild(UIElements.New("Frame", "top")
|
||||
:SetLayout("VERTICAL")
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "vline")
|
||||
:SetHeight(1)
|
||||
:SetMargin(0, 0, 8, 8)
|
||||
:SetTexture("ACTIVE_BG_ALT")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "middle")
|
||||
:SetLayout("VERTICAL")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer")
|
||||
-- make all the navigation align to the top
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "divider")
|
||||
:SetWidth(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "contentFrame")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("ViewContainer", "content")
|
||||
:SetNavCallback(private.ContentNavCallback)
|
||||
)
|
||||
)
|
||||
|
||||
local content = frame:GetElement("contentFrame.content")
|
||||
local settingNav = frame:GetElement("settingNavigation")
|
||||
for _, location in ipairs(SECTIONS) do
|
||||
local navFrame = settingNav:GetElement(location)
|
||||
for _, settingName in ipairs(private.settingPages[location]) do
|
||||
navFrame:AddChild(UIElements.New("Button", settingName)
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(settingName)
|
||||
:SetText(settingName)
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(settingName, settingName == defaultPage)
|
||||
if private.childSettingsPages[settingName] then
|
||||
for _, childSettingName in ipairs(private.childSettingsPages[settingName]) do
|
||||
local path = settingName..SETTING_PATH_SEP..childSettingName
|
||||
navFrame:AddChild(UIElements.New("Button", path)
|
||||
:SetHeight(20)
|
||||
:SetMargin(9, 0, 8, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(path)
|
||||
:SetText(strupper(childSettingName))
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(path, path == defaultPage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
private.UpdateNavFrame(settingNav, defaultPage)
|
||||
return frame
|
||||
end
|
||||
|
||||
function private.ContentNavCallback(content, path)
|
||||
return private.callback[path]()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.NavButtonOnClick(button)
|
||||
local path = button:GetContext()
|
||||
if private.childSettingsPages[path] then
|
||||
-- select the first child
|
||||
path = path..SETTING_PATH_SEP..private.childSettingsPages[path][1]
|
||||
end
|
||||
|
||||
local contentFrame = button:GetElement("__parent.__parent.__parent.contentFrame")
|
||||
local navFrame = contentFrame:GetElement("__parent.settingNavigation")
|
||||
private.UpdateNavFrame(navFrame, path)
|
||||
navFrame:Draw()
|
||||
contentFrame:GetElement("content"):SetPath(path, true)
|
||||
end
|
||||
|
||||
function private.InputOnValueChanged(input)
|
||||
local button = input:GetElement("__parent.resetButton")
|
||||
local scope, namespace, key = strsplit(".", button:GetContext())
|
||||
button:SetDisabled(TSM.db[scope][namespace][key] == TSM.db:GetDefault(scope, namespace, key))
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function private.ResetBtnOnClick(button)
|
||||
local scope, namespace, key = strsplit(".", button:GetContext())
|
||||
local defaultValue = TSM.db:GetDefault(scope, namespace, key)
|
||||
TSM.db:Set(scope, nil, namespace, key, defaultValue)
|
||||
button:GetElement("__parent.input")
|
||||
:SetValue(defaultValue)
|
||||
:Draw()
|
||||
button:SetDisabled(true)
|
||||
:Draw()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateNavFrame(navFrame, selectedPath)
|
||||
local selectedSetting = strsplit(SETTING_PATH_SEP, selectedPath)
|
||||
for _, location in ipairs(SECTIONS) do
|
||||
for _, settingName in ipairs(private.settingPages[location]) do
|
||||
navFrame:GetElement(location ..".".. settingName)
|
||||
:SetTextColor(settingName == selectedSetting and "TEXT" or "ACTIVE_BG_ALT")
|
||||
if private.childSettingsPages[settingName] then
|
||||
for _, childSettingName in ipairs(private.childSettingsPages[settingName]) do
|
||||
local path = settingName..SETTING_PATH_SEP..childSettingName
|
||||
if settingName == selectedSetting then
|
||||
navFrame:GetElement(location ..".".. path)
|
||||
:SetTextColor(path == selectedPath and "INDICATOR" or "TEXT")
|
||||
:Show()
|
||||
else
|
||||
navFrame:GetElement(location ..".".. path):Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user