initial commit

This commit is contained in:
Gitea
2020-11-13 14:13:12 -05:00
commit 05df49ff60
368 changed files with 128754 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Accounting = TSM.MainUI.Settings:NewPackage("Accounting")
local L = TSM.Include("Locale").GetTable()
local Log = TSM.Include("Util.Log")
local UIElements = TSM.Include("UI.UIElements")
local private = {}
local DAYS_OLD_OPTIONS = { 0, 15, 30, 45, 60, 75, 90, 180, 360 }
-- ============================================================================
-- Module Functions
-- ============================================================================
function Accounting.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Accounting"], "middle", private.GetAccountingSettingsFrame)
end
-- ============================================================================
-- Accounting Settings UI
-- ============================================================================
function private.GetAccountingSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "accounting")
return UIElements.New("ScrollFrame", "accountingSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Accounting", "accounting", L["General Options"], L["Some general Accounting options are below."])
:AddChild(UIElements.New("Frame", "check1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "tradeCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Track Sales / Purchases via trade"])
:SetSettingInfo(TSM.db.global.accountingOptions, "trackTrades")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "tradePromptCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Don't prompt to record trades"])
:SetSettingInfo(TSM.db.global.accountingOptions, "autoTrackTrades")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Accounting", "accounting", L["Clear Old Data"], L["You can clear old Accounting data below to keep things running smoothly."])
:AddChild(UIElements.New("Text", "daysOldLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Remove Data Older Than (Days)"])
)
:AddChild(UIElements.New("Frame", "daysOld")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
:SetMargin(0, 8, 0, 0)
:SetHintText(L["None Selected"])
:SetItems(DAYS_OLD_OPTIONS)
:SetScript("OnSelectionChanged", private.DaysOldDropdownOnSelectionChanged)
)
:AddChild(UIElements.New("ActionButton", "clearBtn")
:SetWidth(107)
:SetDisabled(true)
:SetText(L["Clear Data"])
:SetScript("OnClick", private.ClearBtnOnClick)
)
)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.DaysOldDropdownOnSelectionChanged(dropdown)
dropdown:GetElement("__parent.clearBtn")
:SetDisabled(false)
:Draw()
end
function private.ClearBtnOnClick(button)
local days = button:GetElement("__parent.dropdown"):GetSelectedItem()
button:GetBaseElement():ShowConfirmationDialog(L["Clear Old Data?"], L["Are you sure you want to clear old accounting data?"], private.ClearDataConfirmed, days)
end
function private.ClearDataConfirmed(days)
Log.PrintfUser(L["Removed a total of %s old records."], TSM.Accounting.Transactions.RemoveOldData(days) + TSM.Accounting.Money.RemoveOldData(days) + TSM.Accounting.Auctions.RemoveOldData(days))
end

View File

@@ -0,0 +1,182 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Appearance = TSM.MainUI.Settings:NewPackage("Appearance")
local L = TSM.Include("Locale").GetTable()
local Theme = TSM.Include("Util.Theme")
local LibDBIcon = LibStub("LibDBIcon-1.0")
local UIElements = TSM.Include("UI.UIElements")
local private = {
colorSetKeys = {},
colorSetNames = {},
}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Appearance.OnInitialize()
for _, key, name in TSM.UI.Util.ColorSetIterator() do
tinsert(private.colorSetKeys, key)
tinsert(private.colorSetNames, name)
end
TSM.MainUI.Settings.RegisterSettingPage(L["Appearance"], "middle", private.GetSettingsFrame)
end
-- ============================================================================
-- Appearance Settings UI
-- ============================================================================
function private.GetSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "appearance")
return UIElements.New("ScrollFrame", "generalSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Appearance", "appearance", L["General Options"], L["Some general appearance options are below."])
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "minimapCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Hide minimap icon"])
:SetSettingInfo(TSM.db.global.coreOptions.minimapIcon, "hide")
:SetScript("OnValueChanged", private.MinimapOnValueChanged)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "taskListLockCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Lock task list's background"])
:SetSettingInfo(TSM.db.global.appearanceOptions, "taskListBackgroundLock")
:SetScript("OnValueChanged", private.TaskListLockOnValueChanged)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "showTotalMoneyCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Show total gold in header"])
:SetSettingInfo(TSM.db.global.appearanceOptions, "showTotalMoney")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(UIElements.New("Text", "label")
:SetHeight(24)
:SetMargin(12, 0, 4, 12)
:SetFont("BODY_BODY1_BOLD")
:SetText(L["Themes"])
)
:AddChild(UIElements.New("Frame", "theme")
:SetLayout("FLOW")
:AddChildrenWithFunction(private.AddTheme)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.MinimapOnValueChanged(_, value)
if value then
LibDBIcon:Hide("TradeSkillMaster")
else
LibDBIcon:Show("TradeSkillMaster")
end
end
function private.TaskListLockOnValueChanged(_, value)
TSM.db.global.appearanceOptions.taskListBackgroundLock = value
if TSM.UI.TaskListUI.IsVisible() then
TSM.UI.TaskListUI.UpdateFrame()
end
end
function private.AddTheme(frame)
for _, key, name in TSM.UI.Util.ColorSetIterator() do
frame:AddChild(UIElements.New("Frame", name)
:SetLayout("VERTICAL")
:SetSize(198, 140)
:SetPadding(0, 0, 12, 8)
:SetMargin(0, 12, 0, 8)
:SetBackgroundColor(Theme.GetColor("FRAME_BG", key), true)
:SetBorderColor(Theme.GetColor("ACTIVE_BG_ALT", key))
:SetContext(key)
:AddChild(UIElements.New("Frame", "top")
:SetLayout("HORIZONTAL")
:SetHeight(36)
:SetMargin(8, 8, 0, 12)
:AddChild(UIElements.New("Frame", "left")
:SetSize(36, 36)
:SetMargin(0, 12, 0, 0)
:SetBackgroundColor(Theme.GetColor("ACTIVE_BG_ALT", key), true)
)
:AddChild(UIElements.New("Frame", "right")
:SetLayout("VERTICAL")
:AddChild(UIElements.New("Frame", "line1")
:SetHeight(12)
:SetMargin(0, 0, 0, 12)
:SetBackgroundColor(Theme.GetColor("ACTIVE_BG", key), true)
)
:AddChild(UIElements.New("Frame", "line2")
:SetHeight(12)
:SetBackgroundColor(Theme.GetColor("PRIMARY_BG_ALT", key), true)
)
)
)
:AddChild(UIElements.New("Frame", "line3")
:SetMargin(8, 8, 0, 12)
:SetBackgroundColor(Theme.GetColor("PRIMARY_BG", key), true)
)
:AddChild(UIElements.New("Texture", "divider")
:SetHeight(1)
:SetTexture(Theme.GetColor("ACTIVE_BG_ALT", key))
)
:AddChild(UIElements.New("Toggle", "toggle")
:SetHeight(20)
:SetMargin(8, 0, 8, 0)
:SetFont("BODY_BODY2_MEDIUM")
:AddOption(Theme.GetThemeName(key), TSM.db.global.appearanceOptions.colorSet == key)
:SetScript("OnValueChanged", private.ThemeButtonOnClick)
)
:AddChildNoLayout(UIElements.New("Button", "btn")
:AddAnchor("TOPLEFT")
:AddAnchor("BOTTOMRIGHT")
:SetScript("OnClick", private.ThemeButtonOnClick)
)
)
end
end
function private.ThemeButtonOnClick(buttonToggle)
local selectedKey = buttonToggle:GetParentElement():GetContext()
for _, key, name in TSM.UI.Util.ColorSetIterator() do
local toggle = buttonToggle:GetElement("__parent.__parent."..name..".toggle")
if key == selectedKey then
toggle:SetOption(name, true)
else
toggle:ClearOption(true)
end
end
TSM.db.global.appearanceOptions.colorSet = selectedKey
Theme.SetActiveColorSet(selectedKey)
end

View File

@@ -0,0 +1,225 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Auctioning = TSM.MainUI.Settings:NewPackage("Auctioning")
local L = TSM.Include("Locale").GetTable()
local Sound = TSM.Include("Util.Sound")
local String = TSM.Include("Util.String")
local Log = TSM.Include("Util.Log")
local UIElements = TSM.Include("UI.UIElements")
local private = {
sounds = {},
soundkeys = {},
}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Auctioning.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Auctioning"], "middle", private.GetAuctioningSettingsFrame)
for key, name in pairs(Sound.GetSounds()) do
tinsert(private.sounds, name)
tinsert(private.soundkeys, key)
end
end
-- ============================================================================
-- Auctioning Settings UI
-- ============================================================================
function private.GetAuctioningSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "auctioning")
return UIElements.New("ScrollFrame", "auctioningSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Auctioning", "auctioning", L["General Options"], L["Some general Auctioning options are below."])
:AddChild(UIElements.New("Frame", "check1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "cancelBids")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Cancel auctions with bids"])
:SetSettingInfo(TSM.db.global.auctioningOptions, "cancelWithBid")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "invalidPrice")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Disable invalid price warnings"])
:SetSettingInfo(TSM.db.global.auctioningOptions, "disableInvalidMsg")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Auctioning", "sounds", L["Auction House Sounds"], L["Setup various sounds that play when doing Auctioning scans."])
:AddChild(UIElements.New("Frame", "labelLine1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:AddChild(UIElements.New("Text", "scan")
:SetMargin(0, 12, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Scan complete sound"])
)
:AddChild(UIElements.New("Text", "confirm")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Confirm complete sound"])
)
)
:AddChild(UIElements.New("Frame", "dropdownLine1")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("SelectionDropdown", "scanComplete")
:SetMargin(0, 12, 0, 0)
:SetItems(private.sounds, private.soundkeys)
:SetSettingInfo(TSM.db.global.auctioningOptions, "scanCompleteSound")
:SetScript("OnSelectionChanged", private.SoundOnSelectionChanged)
)
:AddChild(UIElements.New("SelectionDropdown", "confirmComplete")
:SetItems(private.sounds, private.soundkeys)
:SetSettingInfo(TSM.db.global.auctioningOptions, "confirmCompleteSound")
:SetScript("OnSelectionChanged", private.SoundOnSelectionChanged)
)
)
:AddChild(UIElements.New("Text", "saleLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Auction sale sound"])
)
:AddChild(UIElements.New("SelectionDropdown", "saleDropdown")
:SetHeight(24)
:SetItems(private.sounds, private.soundkeys)
:SetSettingInfo(TSM.db.global.coreOptions, "auctionSaleSound")
:SetScript("OnSelectionChanged", private.SoundOnSelectionChanged)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Auctioning", "whitelist", L["Whitelist"], L["TSM will not undercut any players you add to your whitelist."])
:AddChild(UIElements.New("Text", "matchLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Match whitelisted players"])
)
:AddChild(UIElements.New("ToggleOnOff", "matchToggle")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:SetSettingInfo(TSM.db.global.auctioningOptions, "matchWhitelist")
)
:AddChild(UIElements.New("Text", "addLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Whitelisted characters"])
)
:AddChild(UIElements.New("Input", "newPlayerInput")
:SetHeight(24)
:SetMargin(0, 0, 0, 4)
:SetBackgroundColor("ACTIVE_BG")
:SetHintText(L["Enter player name"])
:SetScript("OnEnterPressed", private.NewPlayerOnEnterPressed)
)
:AddChild(UIElements.New("Frame", "whitelistFrame")
:SetLayout("FLOW")
:SetHeight(60)
:AddChildrenWithFunction(private.AddWhitelistRows)
)
)
end
function private.AddWhitelistRows(containerFrame)
for player in pairs(TSM.db.factionrealm.auctioningOptions.whitelist) do
private.AddWhitelistRow(containerFrame, player)
end
end
function private.AddWhitelistRow(frame, player)
frame:AddChild(UIElements.New("Frame", "whitelist_"..player)
:SetLayout("HORIZONTAL")
:SetSize(100, 20)
:SetMargin(0, 12, 0, 0)
:AddChild(UIElements.New("Text", "text")
:SetWidth("AUTO")
:SetMargin(0, 2, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(player)
)
:AddChild(UIElements.New("Button", "removeBtn")
:SetBackgroundAndSize("iconPack.14x14/Close/Circle")
:SetContext(player)
:SetScript("OnClick", private.RemoveWhitelistOnClick)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.SoundOnSelectionChanged(self)
Sound.PlaySound(self:GetSelectedItemKey())
end
function private.NewPlayerOnEnterPressed(input)
local newPlayer = strlower(input:GetValue())
input:SetValue("")
input:Draw()
if newPlayer == "" or strfind(newPlayer, ",") or newPlayer ~= String.Escape(newPlayer) then
Log.PrintfUser(L["Invalid player name."])
return
elseif TSM.db.factionrealm.auctioningOptions.whitelist[newPlayer] then
Log.PrintfUser(L["The player \"%s\" is already on your whitelist."], TSM.db.factionrealm.auctioningOptions.whitelist[newPlayer])
return
end
local isAlt = false
for factionrealm in TSM.db:GetConnectedRealmIterator("factionrealm") do
for _, character in TSM.db:FactionrealmCharacterIterator(factionrealm) do
if strlower(newPlayer) == strlower(character) then
Log.PrintfUser(L["You do not need to add \"%s\", alts are whitelisted automatically."], newPlayer)
isAlt = true
end
end
end
if isAlt then
return
end
TSM.db.factionrealm.auctioningOptions.whitelist[newPlayer] = newPlayer
-- add a new row to the UI
local frame = input:GetElement("__parent.whitelistFrame")
private.AddWhitelistRow(frame, newPlayer)
frame:Draw()
end
function private.RemoveWhitelistOnClick(self)
local player = self:GetContext()
TSM.db.factionrealm.auctioningOptions.whitelist[player] = nil
-- remove this row
local row = self:GetParentElement()
local frame = row:GetParentElement()
frame:RemoveChild(row)
row:Release()
frame:Draw()
end

View 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

View File

@@ -0,0 +1,142 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Crafting = TSM.MainUI.Settings:NewPackage("Crafting")
local L = TSM.Include("Locale").GetTable()
local PlayerInfo = TSM.Include("Service.PlayerInfo")
local UIElements = TSM.Include("UI.UIElements")
local private = {
altCharacters = {},
altGuilds = {},
}
local BAD_MAT_PRICE_SOURCES = {
matprice = true,
}
local BAD_CRAFT_VALUE_PRICE_SOURCES = {
crafting = true,
}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Crafting.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Crafting"], "middle", private.GetCraftingSettingsFrame)
end
-- ============================================================================
-- Crafting Settings UI
-- ============================================================================
function private.GetCraftingSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "crafting")
wipe(private.altCharacters)
wipe(private.altGuilds)
for _, character in PlayerInfo.CharacterIterator(true) do
tinsert(private.altCharacters, character)
end
for name in PlayerInfo.GuildIterator() do
tinsert(private.altGuilds, name)
end
return UIElements.New("ScrollFrame", "craftingSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Crafting", "inventory", L["Inventory Options"], "")
:AddChild(UIElements.New("Frame", "inventoryOptionsLabels")
:SetLayout("HORIZONTAL")
:SetMargin(0, 0, 0, 4)
:SetHeight(20)
:AddChild(UIElements.New("Text", "label")
:SetMargin(0, 12, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Ignore Characters"])
)
:AddChild(UIElements.New("Text", "label")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Ignore Guilds"])
)
)
:AddChild(UIElements.New("Frame", "inventoryOptionsDropdowns")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:AddChild(UIElements.New("MultiselectionDropdown", "charDropdown")
:SetMargin(0, 12, 0, 0)
:SetItems(private.altCharacters, private.altCharacters)
:SetSettingInfo(TSM.db.global.craftingOptions, "ignoreCharacters")
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
)
:AddChild(UIElements.New("MultiselectionDropdown", "guildDropdown")
:SetItems(private.altGuilds, private.altGuilds)
:SetSettingInfo(TSM.db.global.craftingOptions, "ignoreGuilds")
:SetSelectionText(L["No Guilds"], L["%d Guilds"], L["All Guilds"])
)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Crafting", "price", L["Default price configuration"], "")
:AddChild(UIElements.New("Text", "matCostLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetTextColor("TEXT_ALT")
:SetText(L["Default material cost method"])
)
:AddChild(UIElements.New("MultiLineInput", "matCostInput")
:SetHeight(70)
:SetMargin(0, 0, 0, 12)
:SetValidateFunc("CUSTOM_PRICE", BAD_MAT_PRICE_SOURCES)
:SetSettingInfo(TSM.db.global.craftingOptions, "defaultMatCostMethod")
)
:AddChild(UIElements.New("Text", "craftValueLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetTextColor("TEXT_ALT")
:SetText(L["Default craft value method"])
)
:AddChild(UIElements.New("MultiLineInput", "matCostInput")
:SetHeight(70)
:SetValidateFunc("CUSTOM_PRICE", BAD_CRAFT_VALUE_PRICE_SOURCES)
:SetSettingInfo(TSM.db.global.craftingOptions, "defaultCraftPriceMethod")
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Crafting", "cooldowns", L["Ignored Cooldowns"], L["Use this list to manage what cooldowns you'd like TSM to ignore from crafting."])
:AddChild(UIElements.New("QueryScrollingTable", "items")
:SetHeight(126)
:GetScrollingTableInfo()
:NewColumn("item")
:SetTitle(L["Cooldown"])
:SetFont("BODY_BODY3")
:SetJustifyH("LEFT")
:SetTextInfo(nil, private.CooldownGetText)
:DisableHiding()
:Commit()
:Commit()
:SetQuery(TSM.Crafting.CreateIgnoredCooldownQuery())
:SetAutoReleaseQuery(true)
:SetSelectionDisabled(true)
:SetScript("OnRowClick", private.IgnoredCooldownOnRowClick)
)
)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.CooldownGetText(row)
return row:GetField("characterKey").." - "..TSM.Crafting.GetName(row:GetField("spellId"))
end
function private.IgnoredCooldownOnRowClick(_, row)
TSM.Crafting.RemoveIgnoredCooldown(row:GetFields("characterKey", "spellId"))
end

View File

@@ -0,0 +1,297 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local CustomSources = TSM.MainUI.Settings:NewPackage("CustomSources")
local L = TSM.Include("Locale").GetTable()
local TempTable = TSM.Include("Util.TempTable")
local Theme = TSM.Include("Util.Theme")
local CustomPrice = TSM.Include("Service.CustomPrice")
local UIElements = TSM.Include("UI.UIElements")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function CustomSources.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Custom Sources"], "middle", private.GetCustomSourcesSettingsFrame)
end
-- ============================================================================
-- Custom Sources Settings UI
-- ============================================================================
function private.GetCustomSourcesSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "custom_sources")
return UIElements.New("ScrollFrame", "content")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Custom Price", "general", L["Custom Sources"], format(L["Custom sources allow you to create more advanced prices for use throughout the addon. You'll be able to use these new variables in the same way you can use the built-in price sources such as %s and %s."], Theme.GetColor("INDICATOR"):ColorText("vendorsell"), Theme.GetColor("INDICATOR"):ColorText("vendorbuy")), 60)
:AddChild(UIElements.New("Frame", "tableHeading")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Text", "col1")
:SetWidth(162)
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY3_MEDIUM")
:SetText(L["Name"])
)
:AddChild(UIElements.New("Text", "col2")
:SetFont("BODY_BODY3_MEDIUM")
:SetText(L["String"])
)
)
:AddChild(UIElements.New("Texture", "line1")
:SetHeight(1)
:SetTexture("ACTIVE_BG")
)
:AddChildrenWithFunction(private.AddCustomPriceRows)
:AddChild(UIElements.New("ActionButton", "addNewBtn")
:SetHeight(24)
:SetMargin(0, 0, 32, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Add a new custom source"])
:SetScript("OnClick", private.AddNewButtonOnClick)
)
)
end
function private.CreateCustomPriceRow(name)
local priceString = TSM.db.global.userData.customPriceSources[name]
local row = UIElements.New("Frame", "row_"..name)
:SetLayout("HORIZONTAL")
:SetHeight(28)
:SetMargin(-12, -12, 0, 0)
:SetPadding(12, 12, 0, 0)
:SetBackgroundColor("PRIMARY_BG_ALT")
:SetContext(name)
:SetScript("OnEnter", private.CustomPriceRowOnEnter)
:SetScript("OnLeave", private.CustomPriceRowOnLeave)
:AddChild(UIElements.New("Text", "nameText")
:SetWidth(162)
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY3_MEDIUM")
:SetText(name)
)
:AddChild(UIElements.New("Text", "valueText")
:SetFont("BODY_BODY3")
:SetText(priceString)
)
:AddChild(UIElements.New("Button", "editBtn")
:SetMargin(4, 0, 0, 0)
:SetBackgroundAndSize("iconPack.18x18/Edit")
:SetScript("OnClick", private.EditCustomPriceOnClick)
:PropagateScript("OnEnter")
:PropagateScript("OnLeave")
)
:AddChild(UIElements.New("Button", "deleteBtn")
:SetMargin(4, 0, 0, 0)
:SetBackgroundAndSize("iconPack.18x18/Delete")
:SetScript("OnClick", private.DeleteCustomPriceOnClick)
:PropagateScript("OnEnter")
:PropagateScript("OnLeave")
)
row:GetElement("editBtn"):Hide()
row:GetElement("deleteBtn"):Hide()
return row
end
function private.AddCustomPriceRows(frame)
local names = TempTable.Acquire()
for name in pairs(TSM.db.global.userData.customPriceSources) do
tinsert(names, name)
end
sort(names)
for _, name in ipairs(names) do
frame:AddChild(private.CreateCustomPriceRow(name))
end
TempTable.Release(names)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.CustomPriceRowOnEnter(frame)
frame:SetBackgroundColor("FRAME_BG")
frame:GetElement("editBtn"):Show()
frame:GetElement("deleteBtn"):Show()
frame:Draw()
end
function private.CustomPriceRowOnLeave(frame)
frame:SetBackgroundColor("PRIMARY_BG_ALT")
frame:GetElement("editBtn"):Hide()
frame:GetElement("deleteBtn"):Hide()
frame:Draw()
end
function private.EditCustomPriceOnClick(button)
private.ShowEditDialog(button)
end
function private.ShowEditDialog(editBtn)
local dialogFrame = UIElements.New("Frame", "frame")
:SetLayout("VERTICAL")
:SetSize(478, 314)
:SetPadding(12)
:AddAnchor("CENTER")
:SetMouseEnabled(true)
:SetBackgroundColor("FRAME_BG", true)
:SetContext(editBtn)
:AddChild(UIElements.New("Frame", "header")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, -4, 14)
:AddChild(UIElements.New("Spacer", "spacer")
:SetWidth(20)
)
:AddChild(UIElements.New("Text", "title")
:SetJustifyH("CENTER")
:SetFont("BODY_BODY1_BOLD")
:SetText(L["Edit Custom Source"])
)
:AddChild(UIElements.New("Button", "closeBtn")
:SetMargin(0, -4, 0, 0)
:SetBackgroundAndSize("iconPack.24x24/Close/Default")
:SetScript("OnClick", private.EditPriceCloseBtnOnClick)
)
)
:AddChild(UIElements.New("Text", "name")
:SetHeight(20)
:SetFont("BODY_BODY2_MEDIUM")
:SetJustifyH("LEFT")
:SetText(L["Name"])
)
:AddChild(UIElements.New("Input", "nameInput")
:SetHeight(24)
:SetBackgroundColor("PRIMARY_BG_ALT")
:SetValue(editBtn:GetElement("__parent.nameText"):GetText())
:SetTabPaths("__parent.valueInput", "__parent.valueInput")
:SetValidateFunc(private.NameValidateFunc)
:SetScript("OnValidationChanged", private.ConfirmOnValidationChanged)
)
:AddChild(UIElements.New("Text", "string")
:SetHeight(20)
:SetMargin(0, 0, 6, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetJustifyH("LEFT")
:SetText(L["String"])
)
:AddChild(UIElements.New("MultiLineInput", "valueInput")
:SetBackgroundColor("PRIMARY_BG_ALT")
:SetValue(editBtn:GetElement("__parent.valueText"):GetText())
:SetTabPaths("__parent.nameInput", "__parent.nameInput")
:SetValidateFunc(private.ValueValidateFunc)
:SetScript("OnValidationChanged", private.ConfirmOnValidationChanged)
)
:AddChild(UIElements.New("ActionButton", "confirm")
:SetHeight(24)
:SetMargin(0, 0, 12, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Confirm"])
:SetContext(editBtn:GetElement("__parent.__parent"))
:SetScript("OnClick", private.ConfirmOnClick)
)
editBtn:GetBaseElement():ShowDialogFrame(dialogFrame)
return dialogFrame
end
function private.EditPriceCloseBtnOnClick(button)
button:GetBaseElement():HideDialog()
end
function private.NameValidateFunc(input, value)
if value == "" then
return false
elseif gsub(value, "([a-z]+)", "") ~= "" then
return false, L["Custom price names can only contain lowercase letters."]
elseif value ~= input:GetParentElement():GetContext():GetParentElement():GetContext() then
return CustomPrice.ValidateName(value)
end
return true
end
function private.ConfirmOnValidationChanged(input)
input:GetElement("__parent.confirm")
:SetDisabled(not input:IsValid())
:Draw()
end
function private.ValueValidateFunc(input, value)
value = strlower(strtrim(value))
local isValid, errMsg = CustomPrice.Validate(value)
if not isValid and value ~= "" then
return false, errMsg
end
return true
end
function private.ConfirmOnClick(button)
local baseElement = button:GetBaseElement()
local oldName = button:GetParentElement():GetContext():GetParentElement():GetContext()
local newName = button:GetElement("__parent.nameInput"):GetValue()
if oldName ~= newName then
CustomPrice.RenameCustomPriceSource(oldName, newName)
CustomPrice.SetCustomPriceSource(newName, button:GetElement("__parent.valueInput"):GetValue())
local generalContainer = button:GetParentElement():GetContext():GetParentElement():GetParentElement()
local rowFrame = button:GetParentElement():GetContext():GetParentElement()
generalContainer:AddChildBeforeById("addNewBtn", private.CreateCustomPriceRow(newName))
generalContainer:RemoveChild(rowFrame)
rowFrame:Release()
generalContainer:GetElement("__parent.__parent")
:Draw()
else
CustomPrice.SetCustomPriceSource(newName, button:GetElement("__parent.valueInput"):GetValue())
button:GetParentElement():GetContext():GetElement("__parent.nameText")
:SetText(newName)
:Draw()
button:GetParentElement():GetContext():GetElement("__parent.valueText")
:SetText(button:GetElement("__parent.valueInput"):GetValue())
:Draw()
end
baseElement:HideDialog()
end
function private.DeleteCustomPriceOnClick(button)
CustomPrice.DeleteCustomPriceSource(button:GetParentElement():GetContext())
local rowFrame = button:GetParentElement()
local parentFrame = rowFrame:GetParentElement()
parentFrame:RemoveChild(rowFrame)
rowFrame:Release()
parentFrame:GetElement("__parent.__parent")
:Draw()
end
function private.AddNewButtonOnClick(button)
-- generate a placeholder name
local newName = nil
local suffix = ""
while not newName do
for i = strbyte("a"), strbyte("z") do
newName = "customprice"..suffix..strchar(i)
if not TSM.db.global.userData.customPriceSources[newName] then
break
end
newName = nil
end
suffix = suffix..strchar(random(strbyte("a"), strbyte("z")))
end
CustomPrice.CreateCustomPriceSource(newName, "")
button:GetParentElement()
:AddChildBeforeById("addNewBtn", private.CreateCustomPriceRow(newName))
button:GetElement("__parent.__parent.__parent")
:Draw()
local dialogFrame = private.ShowEditDialog(button:GetElement("__parent.row_"..newName..".editBtn"))
dialogFrame:GetElement("valueInput"):SetFocused(true)
end

View File

@@ -0,0 +1,122 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Destroying = TSM.MainUI.Settings:NewPackage("Destroying")
local L = TSM.Include("Locale").GetTable()
local UIElements = TSM.Include("UI.UIElements")
local private = {}
local ITEM_QUALITY_DESCS = { ITEM_QUALITY2_DESC, ITEM_QUALITY3_DESC, ITEM_QUALITY4_DESC }
local ITEM_QUALITY_KEYS = { 2, 3, 4 }
-- ============================================================================
-- Module Functions
-- ============================================================================
function Destroying.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage("Destroying", "middle", private.GetDestroyingSettingsFrame)
end
-- ============================================================================
-- Destroying Settings UI
-- ============================================================================
function private.GetDestroyingSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "destroying")
return UIElements.New("ScrollFrame", "destroyingSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Destroying", "general", L["General Options"], "")
:AddChild(UIElements.New("Frame", "check1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "autoStackCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Enable automatic stack combination"])
:SetSettingInfo(TSM.db.global.destroyingOptions, "autoStack")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "autoShowCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Show destroying frame automatically"])
:SetSettingInfo(TSM.db.global.destroyingOptions, "autoShow")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check3")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "includeSoulboundCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Include soulbound items"])
:SetSettingInfo(TSM.db.global.destroyingOptions, "includeSoulbound")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Destroying", "disenchanting", L["Disenchanting Options"], "")
:AddChild(UIElements.New("Text", "label")
:SetHeight(18)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Maximum disenchant quality"])
)
:AddChild(UIElements.New("SelectionDropdown", "maxQualityDropDown")
:SetHeight(26)
:SetMargin(0, 0, 0, 12)
:SetItems(ITEM_QUALITY_DESCS, ITEM_QUALITY_KEYS)
:SetSettingInfo(TSM.db.global.destroyingOptions, "deMaxQuality")
)
:AddChild(TSM.MainUI.Settings.CreateInputWithReset("deDisenchantPriceField", L["Only show items with disenchant values above this price"], "global.destroyingOptions.deAbovePrice"))
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Destroying", "ignore", L["Ignored Items"], L["Use this list to manage what items you'd like TSM to ignore from destroying."])
:AddChild(UIElements.New("QueryScrollingTable", "items")
:SetHeight(136)
:GetScrollingTableInfo()
:NewColumn("item")
:SetTitle(L["Item"])
:SetFont("ITEM_BODY3")
:SetJustifyH("LEFT")
:SetIconSize(12)
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
:SetIconInfo("texture")
:SetTooltipInfo("itemString")
:SetSortInfo("name")
:DisableHiding()
:Commit()
:Commit()
:SetQuery(TSM.Destroying.CreateIgnoreQuery())
:SetAutoReleaseQuery(true)
:SetSelectionDisabled(true)
:SetScript("OnRowClick", private.IgnoredItemsOnRowClick)
)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.IgnoredItemsOnRowClick(_, record, mouseButton)
if mouseButton ~= "LeftButton" then
return
end
TSM.Destroying.ForgetIgnoreItemPermanent(record:GetField("itemString"))
end

View File

@@ -0,0 +1,672 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local General = TSM.MainUI.Settings:NewPackage("General")
local L = TSM.Include("Locale").GetTable()
local Log = TSM.Include("Util.Log")
local TempTable = TSM.Include("Util.TempTable")
local Table = TSM.Include("Util.Table")
local Theme = TSM.Include("Util.Theme")
local Settings = TSM.Include("Service.Settings")
local Sync = TSM.Include("Service.Sync")
local PlayerInfo = TSM.Include("Service.PlayerInfo")
local Tooltip = TSM.Include("UI.Tooltip")
local UIElements = TSM.Include("UI.UIElements")
local private = {
frame = nil,
characterList = {},
guildList = {},
chatFrameList = {},
}
-- ============================================================================
-- Module Functions
-- ============================================================================
function General.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["General Settings"], "top", private.GetGeneralSettingsFrame)
Sync.RegisterConnectionChangedCallback(private.SyncConnectionChangedCallback)
end
-- ============================================================================
-- General Settings UI
-- ============================================================================
function private.GetGeneralSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "general")
wipe(private.chatFrameList)
local defaultChatFrame = nil
for i = 1, NUM_CHAT_WINDOWS do
local name = strlower(GetChatWindowInfo(i) or "")
if DEFAULT_CHAT_FRAME == _G["ChatFrame"..i] then
defaultChatFrame = name
end
if name ~= "" and _G["ChatFrame"..i.."Tab"]:IsVisible() then
tinsert(private.chatFrameList, name)
end
end
if not tContains(private.chatFrameList, TSM.db.global.coreOptions.chatFrame) then
if tContains(private.chatFrameList, defaultChatFrame) then
TSM.db.global.coreOptions.chatFrame = defaultChatFrame
Log.SetChatFrame(defaultChatFrame)
else
-- all chat frames are hidden, so just disable the setting
wipe(private.chatFrameList)
end
end
wipe(private.characterList)
for _, character in PlayerInfo.CharacterIterator(true) do
if character ~= UnitName("player") then
tinsert(private.characterList, character)
end
end
wipe(private.guildList)
for guild in PlayerInfo.GuildIterator(true) do
tinsert(private.guildList, guild)
end
return UIElements.New("ScrollFrame", "generalSettings")
:SetPadding(8, 8, 8, 0)
:SetScript("OnUpdate", private.FrameOnUpdate)
:SetScript("OnHide", private.FrameOnHide)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("General", "general", L["General Options"], L["Some general TSM options are below."])
:AddChild(UIElements.New("Frame", "check1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "globalOperations")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Store operations globally"])
:SetChecked(TSM.Operations.IsStoredGlobally())
:SetScript("OnValueChanged", private.GlobalOperationsOnValueChanged)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "protectAuctionHouse")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Prevent closing the Auction House with the esc key"])
:SetSettingInfo(TSM.db.global.coreOptions, "protectAuctionHouse")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(TSM.MainUI.Settings.CreateInputWithReset("generalGroupPriceField", L["Filter group item lists based on the following price source"], "global.coreOptions.groupPriceSource"))
:AddChild(UIElements.New("Frame", "dropdownLabelLine")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 12, 4)
:AddChild(UIElements.New("Text", "chatTabLabel")
:SetMargin(0, 12, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Chat Tab"])
)
:AddChild(UIElements.New("Text", "forgetLabel")
:SetMargin(0, 12, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Forget Character"])
)
:AddChild(UIElements.New("Text", "ignoreLabel")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Ignore Guilds"])
)
)
:AddChild(UIElements.New("Frame", "dropdownLabelLine")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:AddChild(UIElements.New("SelectionDropdown", "chatTabDropdown")
:SetMargin(0, 16, 0, 0)
:SetItems(private.chatFrameList, private.chatFrameList)
:SetSettingInfo(next(private.chatFrameList) and TSM.db.global.coreOptions or nil, "chatFrame")
:SetScript("OnSelectionChanged", private.ChatTabOnSelectionChanged)
)
:AddChild(UIElements.New("SelectionDropdown", "forgetDropdown")
:SetMargin(0, 16, 0, 0)
:SetItems(private.characterList, private.characterList)
:SetScript("OnSelectionChanged", private.ForgetCharacterOnSelectionChanged)
)
:AddChild(UIElements.New("MultiselectionDropdown", "ignoreDropdown")
:SetItems(private.guildList, private.guildList)
:SetSettingInfo(TSM.db.factionrealm.coreOptions, "ignoreGuilds")
:SetSelectionText(L["No Guilds"], L["%d Guilds"], L["All Guilds"])
)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("General", "profiles", L["Profiles"], L["Set your active profile or create a new one."])
:AddChildrenWithFunction(private.AddProfileRows)
:AddChild(UIElements.New("Text", "profileLabel")
:SetHeight(20)
:SetMargin(0, 0, 4, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Create new profile"])
)
:AddChild(UIElements.New("Input", "newProfileInput")
:SetHeight(24)
:SetBackgroundColor("ACTIVE_BG")
:SetHintText(L["Enter profile name"])
:SetScript("OnEnterPressed", private.NewProfileInputOnEnterPressed)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("General", "accountSync", L["Account Syncing"], L["TSM can automatically sync data between multiple WoW accounts."])
:AddChildrenWithFunction(private.AddAccountSyncRows)
:AddChild(UIElements.New("Text", "profileLabel")
:SetHeight(20)
:SetMargin(0, 0, 4, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Add account"])
)
:AddChild(UIElements.New("Input", "newProfileInput")
:SetHeight(24)
:SetBackgroundColor("ACTIVE_BG")
:SetHintText(L["Enter name of logged-in character on other account"])
:SetScript("OnEnterPressed", private.NewAccountSyncInputOnEnterPressed)
)
)
end
function private.AddProfileRows(frame)
for index, profileName in TSM.db:ProfileIterator() do
local isCurrentProfile = profileName == TSM.db:GetCurrentProfile()
local row = UIElements.New("Frame", "profileRow_"..index)
:SetLayout("HORIZONTAL")
:SetHeight(28)
:SetMargin(0, 0, 0, 8)
:SetPadding(8, 8, 4, 4)
:SetBackgroundColor(isCurrentProfile and "ACTIVE_BG" or "PRIMARY_BG_ALT", true)
:SetContext(profileName)
:SetScript("OnEnter", private.ProfileRowOnEnter)
:SetScript("OnLeave", private.ProfileRowOnLeave)
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "checkbox")
:SetWidth("AUTO")
:SetCheckboxPosition("LEFT")
:SetText(profileName)
:SetFont("BODY_BODY2")
:SetChecked(isCurrentProfile)
:SetScript("OnValueChanged", private.ProfileCheckboxOnValueChanged)
:PropagateScript("OnEnter")
:PropagateScript("OnLeave")
)
:PropagateScript("OnEnter")
:PropagateScript("OnLeave")
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Button", "resetBtn")
:SetBackgroundAndSize("iconPack.18x18/Reset")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.ResetProfileOnClick)
:SetScript("OnEnter", private.ResetProfileOnEnter)
:SetScript("OnLeave", private.ResetProfileOnLeave)
)
:AddChild(UIElements.New("Button", "renameBtn")
:SetBackgroundAndSize("iconPack.18x18/Edit")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.RenameProfileOnClick)
:SetScript("OnEnter", private.RenameProfileOnEnter)
:SetScript("OnLeave", private.RenameProfileOnLeave)
)
:AddChild(UIElements.New("Button", "duplicateBtn")
:SetBackgroundAndSize("iconPack.18x18/Duplicate")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.DuplicateProfileOnClick)
:SetScript("OnEnter", private.DuplicateProfileOnEnter)
:SetScript("OnLeave", private.DuplicateProfileOnLeave)
)
:AddChild(UIElements.New("Button", "deleteBtn")
:SetBackgroundAndSize("iconPack.18x18/Delete")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.DeleteProfileOnClick)
:SetScript("OnEnter", private.DeleteProfileOnEnter)
:SetScript("OnLeave", private.DeleteProfileOnLeave)
)
row:GetElement("deleteBtn"):Hide()
if not isCurrentProfile then
row:GetElement("resetBtn"):Hide()
row:GetElement("renameBtn"):Hide()
row:GetElement("duplicateBtn"):Hide()
end
frame:AddChild(row)
end
end
function private.AddAccountSyncRows(frame)
local newAccountStatusText = Sync.GetNewAccountStatus()
if newAccountStatusText then
local row = private.CreateAccountSyncRow("new", newAccountStatusText)
row:GetElement("sendProfileBtn"):Hide()
row:GetElement("removeBtn"):Hide()
frame:AddChild(row)
end
for _, account in TSM.db:SyncAccountIterator() do
local characters = TempTable.Acquire()
for _, character in Settings.CharacterByAccountFactionrealmIterator(account) do
tinsert(characters, character)
end
sort(characters)
local isConnected, connectedCharacter = Sync.GetConnectionStatus(account)
local statusText = nil
if isConnected then
statusText = Theme.GetFeedbackColor("GREEN"):ColorText(format(L["Connected to %s"], connectedCharacter))
else
statusText = Theme.GetFeedbackColor("RED"):ColorText(L["Offline"])
end
statusText = statusText.." | "..table.concat(characters, ", ")
TempTable.Release(characters)
local row = private.CreateAccountSyncRow("accountSyncRow_"..account, statusText)
row:SetContext(account)
row:GetElement("sendProfileBtn"):Hide()
row:GetElement("removeBtn"):Hide()
frame:AddChild(row)
end
end
function private.CreateAccountSyncRow(id, statusText)
local row = UIElements.New("Frame", id)
:SetLayout("HORIZONTAL")
:SetHeight(28)
:SetMargin(0, 0, 0, 8)
:SetPadding(8, 8, 4, 4)
:SetBackgroundColor("PRIMARY_BG_ALT", true)
:SetScript("OnEnter", private.AccountSyncRowOnEnter)
:SetScript("OnLeave", private.AccountSyncRowOnLeave)
:AddChild(UIElements.New("Text", "status")
:SetFont("BODY_BODY2")
:SetText(statusText)
:SetScript("OnEnter", private.AccountSyncTextOnEnter)
:SetScript("OnLeave", private.AccountSyncTextOnLeave)
)
:AddChild(UIElements.New("Button", "sendProfileBtn")
:SetBackgroundAndSize("iconPack.18x18/Operation")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.SendProfileOnClick)
:SetScript("OnEnter", private.SendProfileOnEnter)
:SetScript("OnLeave", private.SendProfileOnLeave)
)
:AddChild(UIElements.New("Button", "removeBtn")
:SetBackgroundAndSize("iconPack.18x18/Delete")
:SetMargin(4, 0, 0, 0)
:SetScript("OnClick", private.RemoveAccountSyncOnClick)
:SetScript("OnEnter", private.RemoveAccountOnEnter)
:SetScript("OnLeave", private.RemoveAccountOnLeave)
)
return row
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.SyncConnectionChangedCallback()
if private.frame then
private.frame:GetParentElement():ReloadContent()
end
end
function private.FrameOnUpdate(frame)
frame:SetScript("OnUpdate", nil)
private.frame = frame
end
function private.FrameOnHide(frame)
private.frame = nil
end
function private.GlobalOperationsOnValueChanged(checkbox, value)
-- restore the previous value until it's confirmed
checkbox:SetChecked(not value, true)
local desc = L["If you have multiple profiles set up with operations, enabling this will cause all but the current profile's operations to be irreversibly lost."]
checkbox:GetBaseElement():ShowConfirmationDialog(L["Make Operations Global?"], desc, private.GlobalOperationsConfirmed, checkbox, value)
end
function private.GlobalOperationsConfirmed(checkbox, newValue)
checkbox:SetChecked(newValue, true)
:Draw()
TSM.Operations.SetStoredGlobally(newValue)
end
function private.ChatTabOnSelectionChanged(dropdown)
Log.SetChatFrame(dropdown:GetSelectedItem())
end
function private.ForgetCharacterOnSelectionChanged(self)
local character = self:GetSelectedItem()
if not character then return end
TSM.db:RemoveSyncCharacter(character)
TSM.db.factionrealm.internalData.pendingMail[character] = nil
TSM.db.factionrealm.internalData.characterGuilds[character] = nil
Log.PrintfUser(L["%s removed."], character)
assert(Table.RemoveByValue(private.characterList, character) == 1)
self:SetSelectedItem(nil)
:SetItems(private.characterList)
:Draw()
end
function private.ProfileRowOnEnter(frame)
local isCurrentProfile = frame:GetContext() == TSM.db:GetCurrentProfile()
frame:SetBackgroundColor("ACTIVE_BG", true)
if not isCurrentProfile then
frame:GetElement("resetBtn"):Show()
frame:GetElement("renameBtn"):Show()
frame:GetElement("duplicateBtn"):Show()
frame:GetElement("deleteBtn"):Show()
end
frame:Draw()
end
function private.ProfileRowOnLeave(frame)
local isCurrentProfile = frame:GetContext() == TSM.db:GetCurrentProfile()
frame:SetBackgroundColor(isCurrentProfile and "ACTIVE_BG" or "PRIMARY_BG_ALT", true)
if not isCurrentProfile then
frame:GetElement("resetBtn"):Hide()
frame:GetElement("renameBtn"):Hide()
frame:GetElement("duplicateBtn"):Hide()
frame:GetElement("deleteBtn"):Hide()
end
frame:Draw()
end
function private.ProfileCheckboxOnValueChanged(checkbox, value)
if not value then
-- can't uncheck profile checkboxes
checkbox:SetChecked(true, true)
checkbox:Draw()
return
end
-- uncheck the current profile row
local currentProfileIndex = nil
for index, profileName in TSM.db:ProfileIterator() do
if profileName == TSM.db:GetCurrentProfile() then
assert(not currentProfileIndex)
currentProfileIndex = index
end
end
local prevRow = checkbox:GetElement("__parent.__parent.__parent.profileRow_"..currentProfileIndex)
prevRow:GetElement("content.checkbox")
:SetChecked(false, true)
prevRow:GetElement("resetBtn"):Hide()
prevRow:GetElement("renameBtn"):Hide()
prevRow:GetElement("duplicateBtn"):Hide()
prevRow:GetElement("deleteBtn"):Hide()
prevRow:SetBackgroundColor("PRIMARY_BG_ALT", true)
prevRow:Draw()
-- set the profile
TSM.db:SetProfile(checkbox:GetText())
-- set this row as the current one
local newRow = checkbox:GetElement("__parent.__parent")
newRow:SetBackgroundColor("ACTIVE_BG", true)
newRow:GetElement("resetBtn"):Show()
newRow:GetElement("renameBtn"):Show()
newRow:GetElement("duplicateBtn"):Show()
newRow:GetElement("deleteBtn"):Hide()
newRow:Draw()
end
function private.RenameProfileOnClick(button)
local profileName = button:GetParentElement():GetContext()
local dialogFrame = UIElements.New("Frame", "frame")
:SetLayout("VERTICAL")
:SetSize(600, 187)
:AddAnchor("CENTER")
:SetBackgroundColor("FRAME_BG")
:SetBorderColor("ACTIVE_BG")
:AddChild(UIElements.New("Text", "title")
:SetHeight(44)
:SetMargin(16, 16, 24, 16)
:SetFont("BODY_BODY2_BOLD")
:SetJustifyH("CENTER")
:SetText(L["Rename Profile"])
)
:AddChild(UIElements.New("Input", "nameInput")
:SetHeight(26)
:SetMargin(16, 16, 0, 25)
:SetBackgroundColor("PRIMARY_BG_ALT")
:SetContext(profileName)
:SetValue(profileName)
:SetScript("OnEnterPressed", private.RenameProfileInputOnEnterPressed)
)
:AddChild(UIElements.New("Frame", "buttons")
:SetLayout("HORIZONTAL")
:SetMargin(16, 16, 0, 16)
:AddChild(UIElements.New("Spacer", "spacer"))
:AddChild(UIElements.New("ActionButton", "closeBtn")
:SetSize(126, 26)
:SetText(CLOSE)
:SetScript("OnClick", private.DialogCloseBtnOnClick)
)
)
button:GetBaseElement():ShowDialogFrame(dialogFrame)
dialogFrame:GetElement("nameInput"):SetFocused(true)
end
function private.DialogCloseBtnOnClick(button)
private.RenameProfileInputOnEnterPressed(button:GetElement("__parent.__parent.nameInput"))
end
function private.RenameProfileInputOnEnterPressed(input)
local profileName = input:GetValue()
local prevProfileName = input:GetContext()
if not TSM.db:IsValidProfileName(profileName) then
Log.PrintUser(L["This is not a valid profile name. Profile names must be at least one character long and may not contain '@' characters."])
return
elseif TSM.db:ProfileExists(profileName) then
Log.PrintUser(L["A profile with this name already exists."])
return
end
-- create a new profile, copy over the settings, then delete the old one
local currentProfileName = TSM.db:GetCurrentProfile()
TSM.db:SetProfile(profileName)
TSM.db:CopyProfile(prevProfileName)
TSM.db:DeleteProfile(prevProfileName, profileName)
if currentProfileName ~= prevProfileName then
TSM.db:SetProfile(currentProfileName)
end
-- hide the dialog and refresh the settings content
local baseElement = input:GetBaseElement()
baseElement:HideDialog()
baseElement:GetElement("content.settings.contentFrame.content"):ReloadContent()
end
function private.RenameProfileOnEnter(button)
button:ShowTooltip(L["Rename the profile"])
private.ProfileRowOnEnter(button:GetParentElement())
end
function private.RenameProfileOnLeave(button)
Tooltip.Hide()
private.ProfileRowOnLeave(button:GetParentElement())
end
function private.DuplicateProfileOnClick(button)
local profileName = button:GetParentElement():GetContext()
local newName = profileName
while TSM.db:ProfileExists(newName) do
newName = newName.." Copy"
end
local activeProfile = TSM.db:GetCurrentProfile()
TSM.db:SetProfile(newName)
TSM.db:CopyProfile(profileName)
TSM.db:SetProfile(activeProfile)
button:GetBaseElement():GetElement("content.settings.contentFrame.content"):ReloadContent()
end
function private.DuplicateProfileOnEnter(button)
button:ShowTooltip(L["Duplicate the profile"])
private.ProfileRowOnEnter(button:GetParentElement())
end
function private.DuplicateProfileOnLeave(button)
Tooltip.Hide()
private.ProfileRowOnLeave(button:GetParentElement())
end
function private.ResetProfileOnClick(button)
local profileName = button:GetParentElement():GetContext()
local desc = format(L["This will reset all groups and operations (if not stored globally) to be wiped from '%s'."], profileName)
button:GetBaseElement():ShowConfirmationDialog(L["Reset Profile?"], desc, private.ResetProfileConfirmed, profileName)
end
function private.ResetProfileConfirmed(profileName)
local activeProfile = TSM.db:GetCurrentProfile()
TSM.db:SetProfile(profileName)
TSM.db:ResetProfile()
TSM.db:SetProfile(activeProfile)
end
function private.ResetProfileOnEnter(button)
button:ShowTooltip(L["Reset the current profile to default settings"])
private.ProfileRowOnEnter(button:GetParentElement())
end
function private.ResetProfileOnLeave(button)
Tooltip.Hide()
private.ProfileRowOnLeave(button:GetParentElement())
end
function private.DeleteProfileOnClick(button)
local profileName = button:GetParentElement():GetContext()
local desc = format(L["This will permanently delete the '%s' profile."], profileName)
button:GetBaseElement():ShowConfirmationDialog(L["Delete Profile?"], desc, private.DeleteProfileConfirmed, button, profileName)
end
function private.DeleteProfileConfirmed(button, profileName)
TSM.db:DeleteProfile(profileName)
button:GetBaseElement():GetElement("content.settings.contentFrame.content"):ReloadContent()
end
function private.DeleteProfileOnEnter(button)
button:ShowTooltip(L["Delete the profile"])
private.ProfileRowOnEnter(button:GetParentElement())
end
function private.DeleteProfileOnLeave(button)
Tooltip.Hide()
private.ProfileRowOnLeave(button:GetParentElement())
end
function private.NewProfileInputOnEnterPressed(input)
local profileName = input:GetValue()
if not TSM.db:IsValidProfileName(profileName) then
Log.PrintUser(L["This is not a valid profile name. Profile names must be at least one character long and may not contain '@' characters."])
return
elseif TSM.db:ProfileExists(profileName) then
Log.PrintUser(L["A profile with this name already exists."])
return
end
TSM.db:SetProfile(profileName)
input:GetBaseElement():GetElement("content.settings.contentFrame.content"):ReloadContent()
end
function private.AccountSyncRowOnEnter(frame)
local account = frame:GetContext()
if account then
frame:GetElement("sendProfileBtn"):Show()
frame:GetElement("removeBtn"):Show()
end
frame:SetBackgroundColor("ACTIVE_BG", true)
frame:Draw()
end
function private.AccountSyncRowOnLeave(frame)
frame:SetBackgroundColor("PRIMARY_BG_ALT", true)
frame:GetElement("sendProfileBtn"):Hide()
frame:GetElement("removeBtn"):Hide()
frame:Draw()
end
function private.AccountSyncTextOnEnter(text)
local account = text:GetParentElement():GetContext()
local tooltipLines = TempTable.Acquire()
if account then
tinsert(tooltipLines, Theme.GetColor("INDICATOR"):ColorText(L["Sync Status"]))
local mirrorConnected, mirrorSynced = Sync.GetMirrorStatus(account)
local mirrorStatus = nil
if not mirrorConnected then
mirrorStatus = Theme.GetFeedbackColor("RED"):ColorText(L["Not Connected"])
elseif not mirrorSynced then
mirrorStatus = Theme.GetFeedbackColor("YELLOW"):ColorText(L["Updating"])
else
mirrorStatus = Theme.GetFeedbackColor("GREEN"):ColorText(L["Up to date"])
end
tinsert(tooltipLines, L["Inventory / Gold Graph"]..TSM.CONST.TOOLTIP_SEP..mirrorStatus)
tinsert(tooltipLines, L["Profession Info"]..TSM.CONST.TOOLTIP_SEP..TSM.Crafting.Sync.GetStatus(account))
tinsert(tooltipLines, L["Purchase / Sale Info"]..TSM.CONST.TOOLTIP_SEP..TSM.Accounting.Sync.GetStatus(account))
else
tinsert(tooltipLines, L["Establishing connection..."])
end
text:ShowTooltip(table.concat(tooltipLines, "\n"), nil, 52)
TempTable.Release(tooltipLines)
private.AccountSyncRowOnEnter(text:GetParentElement())
end
function private.AccountSyncTextOnLeave(text)
Tooltip.Hide()
private.AccountSyncRowOnLeave(text:GetParentElement())
end
function private.SendProfileOnClick(button)
local player = Sync.GetConnectedCharacterByAccount(button:GetParentElement():GetContext())
if not player then
return
end
TSM.Groups.Sync.SendCurrentProfile(player)
end
function private.SendProfileOnEnter(button)
button:ShowTooltip(L["Send your active profile to this synced account"])
private.AccountSyncRowOnEnter(button:GetParentElement())
end
function private.SendProfileOnLeave(button)
Tooltip.Hide()
private.AccountSyncRowOnLeave(button:GetParentElement())
end
function private.RemoveAccountSyncOnClick(button)
Sync.RemoveAccount(button:GetParentElement():GetContext())
button:GetBaseElement():GetElement("content.settings.contentFrame.content"):ReloadContent()
Tooltip.Hide()
Log.PrintUser(L["Account sync removed. Please delete the account sync from the other account as well."])
end
function private.RemoveAccountOnEnter(button)
button:ShowTooltip(L["Remove this account sync and all synced data from this account"])
private.AccountSyncRowOnEnter(button:GetParentElement())
end
function private.RemoveAccountOnLeave(button)
Tooltip.Hide()
private.AccountSyncRowOnLeave(button:GetParentElement())
end
function private.NewAccountSyncInputOnEnterPressed(input)
local character = Ambiguate(input:GetValue(), "none")
if Sync.EstablishConnection(character) then
Log.PrintfUser(L["Establishing connection to %s. Make sure that you've entered this character's name on the other account."], character)
private.SyncConnectionChangedCallback()
else
input:SetValue("")
input:Draw()
end
end

View File

@@ -0,0 +1,270 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Macros = TSM.MainUI.Settings:NewPackage("Macros")
local L = TSM.Include("Locale").GetTable()
local TempTable = TSM.Include("Util.TempTable")
local Vararg = TSM.Include("Util.Vararg")
local Log = TSM.Include("Util.Log")
local Theme = TSM.Include("Util.Theme")
local UIElements = TSM.Include("UI.UIElements")
local private = {}
local MACRO_NAME = "TSMMacro"
local MACRO_ICON = TSM.IsWowClassic() and "INV_Misc_Flower_01" or "Achievement_Faction_GoldenLotus"
local BINDING_NAME = "MACRO "..MACRO_NAME
local BUTTON_MAPPING = {
["row1.myauctionsCheckbox"] = "TSMCancelAuctionBtn",
["row1.auctioningCheckbox"] = "TSMAuctioningBtn",
["row2.shoppingCheckbox"] = "TSMShoppingBuyoutBtn",
["row2.bidBuyConfirmBtn"] = "TSMBidBuyConfirmBtn",
["row3.sniperCheckbox"] = "TSMSniperBtn",
["row3.craftingCheckbox"] = "TSMCraftingBtn",
["row4.destroyingCheckbox"] = "TSMDestroyBtn",
["row4.vendoringCheckbox"] = "TSMVendoringSellAllButton",
}
local CHARACTER_BINDING_SET = 2
local MAX_MACRO_LENGTH = 255
-- ============================================================================
-- Module Functions
-- ============================================================================
function Macros.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Macros"], "middle", private.GetMacrosSettingsFrame)
end
-- ============================================================================
-- Macros Settings UI
-- ============================================================================
function private.GetMacrosSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "macros")
local body = GetMacroBody(MACRO_NAME) or ""
local upEnabled, downEnabled, altEnabled, ctrlEnabled, shiftEnabled = false, false, false, false, false
for _, binding in Vararg.Iterator(GetBindingKey(BINDING_NAME)) do
upEnabled = upEnabled or (strfind(binding, "MOUSEWHEELUP") and true)
downEnabled = upEnabled or (strfind(binding, "MOUSEWHEELDOWN") and true)
altEnabled = altEnabled or (strfind(binding, "ALT-") and true)
ctrlEnabled = ctrlEnabled or (strfind(binding, "CTRL-") and true)
shiftEnabled = shiftEnabled or (strfind(binding, "SHIFT-") and true)
end
local frame = UIElements.New("ScrollFrame", "macroSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Macro", "setup", L["Macro Setup"], L["Many commonly-used actions in TSM can be added to a macro and bound to your scroll wheel. Use the options below to setup this macro and scroll wheel binding."], 40)
:AddChild(UIElements.New("Text", "actionsSubHeading")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:SetFont("BODY_BODY2_BOLD")
:SetText(L["Bound Actions"])
)
:AddChild(UIElements.New("Frame", "row1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "myauctionsCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["My Auctions %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Cancel"])))
)
:AddChild(UIElements.New("Checkbox", "auctioningCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Auctioning %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Post / Cancel"])))
)
)
:AddChild(UIElements.New("Frame", "row2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "shoppingCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Shopping %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Buyout"])))
)
:AddChild(UIElements.New("Checkbox", "bidBuyConfirmBtn")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Confirmation %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Bid / Buyout"])))
)
)
:AddChild(UIElements.New("Frame", "row3")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "sniperCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Sniper %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Buyout"])))
)
:AddChild(UIElements.New("Checkbox", "craftingCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Crafting %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Craft Next"])))
)
)
:AddChild(UIElements.New("Frame", "row4")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 16)
:AddChild(UIElements.New("Checkbox", "destroyingCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Destroying %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Destroy Next"])))
)
:AddChild(UIElements.New("Checkbox", "vendoringCheckbox")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(format(L["Vendoring %s button"], Theme.GetColor("INDICATOR"):ColorText(L["Sell All"])))
)
)
:AddChild(UIElements.New("Text", "scrollWheelSubHeading")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:SetFont("BODY_BODY2_BOLD")
:SetText(L["Scroll Wheel Options"])
)
:AddChild(UIElements.New("Frame", "direction")
:SetLayout("VERTICAL")
:SetMargin(0, 0, 0, 14)
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 6)
:SetFont("BODY_BODY2")
:SetText(L["Scroll wheel direction"])
)
:AddChild(UIElements.New("Frame", "check")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "up")
:SetWidth("AUTO")
:SetMargin(0, 16, 0, 0)
:SetFont("BODY_BODY2")
:SetText(L["Up"])
:SetChecked(upEnabled)
)
:AddChild(UIElements.New("Checkbox", "down")
:SetWidth("AUTO")
:SetFont("BODY_BODY2")
:SetText(L["Down"])
:SetChecked(downEnabled)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(UIElements.New("Frame", "modifiers")
:SetLayout("VERTICAL")
:SetMargin(0, 0, 0, 18)
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 6)
:SetFont("BODY_BODY2")
:SetText(L["Modifiers"])
)
:AddChild(UIElements.New("Frame", "check")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "alt")
:SetWidth("AUTO")
:SetMargin(0, 16, 0, 0)
:SetFont("BODY_BODY2")
:SetText(L["ALT"])
:SetChecked(altEnabled)
)
:AddChild(UIElements.New("Checkbox", "ctrl")
:SetWidth("AUTO")
:SetMargin(0, 16, 0, 0)
:SetFont("BODY_BODY2")
:SetText(L["CTRL"])
:SetChecked(ctrlEnabled)
)
:AddChild(UIElements.New("Checkbox", "shift")
:SetWidth("AUTO")
:SetFont("BODY_BODY2")
:SetText(L["SHIFT"])
:SetChecked(shiftEnabled)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(UIElements.New("ActionButton", "createBtn")
:SetHeight(24)
:SetText(GetMacroInfo(MACRO_NAME) and L["Update existing macro"] or L["Create macro"])
:SetScript("OnClick", private.CreateButtonOnClick)
)
)
for path, buttonName in pairs(BUTTON_MAPPING) do
frame:GetElement("setup.content."..path)
:SetChecked(strfind(body, buttonName) and true or false)
end
return frame
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.CreateButtonOnClick(button)
-- remove the old bindings and macros
for _, binding in Vararg.Iterator(GetBindingKey(BINDING_NAME)) do
SetBinding(binding)
end
DeleteMacro(MACRO_NAME)
if GetNumMacros() >= MAX_ACCOUNT_MACROS then
Log.PrintUser(L["Could not create macro as you already have too many. Delete one of your existing macros and try again."])
return
end
-- create the new macro
local scrollFrame = button:GetParentElement():GetParentElement():GetParentElement()
local lines = TempTable.Acquire()
for elementPath, buttonName in pairs(BUTTON_MAPPING) do
if scrollFrame:GetElement("setup.content."..elementPath):IsChecked() then
tinsert(lines, "/click "..buttonName)
end
end
local macroText = table.concat(lines, "\n")
CreateMacro(MACRO_NAME, MACRO_ICON, macroText)
TempTable.Release(lines)
-- create the binding
local modifierStr = ""
if scrollFrame:GetElement("setup.content.modifiers.check.ctrl"):IsChecked() then
modifierStr = modifierStr.."CTRL-"
end
if scrollFrame:GetElement("setup.content.modifiers.check.alt"):IsChecked() then
modifierStr = modifierStr.."ALT-"
end
if scrollFrame:GetElement("setup.content.modifiers.check.shift"):IsChecked() then
modifierStr = modifierStr.."SHIFT-"
end
-- we want to save these bindings to be per-character, so the mode should be 1 / 2 if we're currently on
-- per-character bindings or not respectively
local bindingMode = (GetCurrentBindingSet() == CHARACTER_BINDING_SET) and 1 or 2
if scrollFrame:GetElement("setup.content.direction.check.up") then
SetBinding(modifierStr.."MOUSEWHEELUP", nil, bindingMode)
SetBinding(modifierStr.."MOUSEWHEELUP", BINDING_NAME, bindingMode)
end
if scrollFrame:GetElement("setup.content.direction.check.down") then
SetBinding(modifierStr.."MOUSEWHEELDOWN", nil, bindingMode)
SetBinding(modifierStr.."MOUSEWHEELDOWN", BINDING_NAME, bindingMode)
end
if TSM.IsWowClassic() then
AttemptToSaveBindings(CHARACTER_BINDING_SET)
else
SaveBindings(CHARACTER_BINDING_SET)
end
button:SetText(GetMacroInfo(MACRO_NAME) and L["Update existing macro"] or L["Create macro"])
:Draw()
Log.PrintUser(L["Macro created and scroll wheel bound!"])
if #macroText > MAX_MACRO_LENGTH then
Log.PrintUser(L["WARNING: The macro was too long, so was truncated to fit by WoW."])
end
end

View File

@@ -0,0 +1,167 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Mailing = TSM.MainUI.Settings:NewPackage("Mailing")
local L = TSM.Include("Locale").GetTable()
local Sound = TSM.Include("Util.Sound")
local Math = TSM.Include("Util.Math")
local UIElements = TSM.Include("UI.UIElements")
local private = {
sounds = {},
soundkeys = {},
}
local ITEM_QUALITY_DESCS = { ITEM_QUALITY2_DESC, ITEM_QUALITY3_DESC, ITEM_QUALITY4_DESC }
local ITEM_QUALITY_KEYS = { 2, 3, 4 }
-- ============================================================================
-- Module Functions
-- ============================================================================
function Mailing.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Mailing"], "middle", private.GetMailingSettingsFrame)
for key, name in pairs(Sound.GetSounds()) do
tinsert(private.sounds, name)
tinsert(private.soundkeys, key)
end
end
-- ============================================================================
-- Mailing Settings UI
-- ============================================================================
function private.GetMailingSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "mailing")
return UIElements.New("ScrollFrame", "mailingSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Mailing", "inbox", L["Inbox Settings"], "")
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "inboxMessagesCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Enable inbox chat messages"])
:SetSettingInfo(TSM.db.global.mailingOptions, "inboxMessages")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Text", "label")
:SetHeight(18)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Amount of bag space to keep free"])
)
:AddChild(UIElements.New("Frame", "freeSpaceFrame")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 0, 8)
:AddChild(UIElements.New("Input", "keepMailInput")
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("ACTIVE_BG")
:SetValidateFunc("NUMBER", "0:20")
:SetSettingInfo(TSM.db.global.mailingOptions, "keepMailSpace")
)
:AddChild(UIElements.New("Text", "label")
:SetSize("AUTO", 16)
:SetFont("BODY_BODY3")
:SetText(L["Min 0 - Max 20"])
)
)
:AddChild(UIElements.New("Text", "label")
:SetHeight(18)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Open mail complete sound"])
)
:AddChild(UIElements.New("SelectionDropdown", "soundDropdown")
:SetHeight(24)
:SetItems(private.sounds, private.soundkeys)
:SetSettingInfo(TSM.db.global.mailingOptions, "openMailSound")
:SetScript("OnSelectionChanged", private.SoundOnSelectionChanged)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Mailing", "send", L["Sending Settings"], "")
:AddChild(UIElements.New("Frame", "check1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "sendMessagesCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Enable sending chat messages"])
:SetSettingInfo(TSM.db.global.mailingOptions, "sendMessages")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "check2")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 22)
:AddChild(UIElements.New("Checkbox", "sendItemsCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Send grouped items individually"])
:SetSettingInfo(TSM.db.global.mailingOptions, "sendItemsIndividually")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Restart delay (minutes)"])
)
:AddChild(UIElements.New("Frame", "restartDelayFrame")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Input", "restartDelay")
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("ACTIVE_BG")
:SetValidateFunc("NUMBER", "0.5:10")
:SetValue(TSM.db.global.mailingOptions.resendDelay)
:SetScript("OnValueChanged", private.RestartDelayOnValueChanged)
)
:AddChild(UIElements.New("Text", "label")
:SetSize("AUTO", 16)
:SetFont("BODY_BODY3")
:SetText(L["Min 0.5 - Max 10"])
)
)
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Mail disenchantables max quality"])
)
:AddChild(UIElements.New("SelectionDropdown", "mailPageDropdown")
:SetHeight(26)
:SetItems(ITEM_QUALITY_DESCS, ITEM_QUALITY_KEYS)
:SetSettingInfo(TSM.db.global.mailingOptions, "deMaxQuality")
)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.SoundOnSelectionChanged(self, selection)
Sound.PlaySound(TSM.db.global.mailingOptions.openMailSound)
end
function private.RestartDelayOnValueChanged(input)
local value = Math.Round(tonumber(input:GetValue()), 0.5)
TSM.db.global.mailingOptions.resendDelay = value
end

View File

@@ -0,0 +1,168 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Shopping = TSM.MainUI.Settings:NewPackage("Shopping")
local L = TSM.Include("Locale").GetTable()
local Sound = TSM.Include("Util.Sound")
local UIElements = TSM.Include("UI.UIElements")
local private = {
sounds = {},
soundkeys = {},
}
local MAX_ITEM_LEVEL = 500
-- ============================================================================
-- Module Functions
-- ============================================================================
function Shopping.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Browse / Sniper"], "middle", private.GetShoppingSettingsFrame)
for key, name in pairs(Sound.GetSounds()) do
tinsert(private.sounds, name)
tinsert(private.soundkeys, key)
end
end
-- ============================================================================
-- Shopping Settings UI
-- ============================================================================
function private.GetShoppingSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "shopping")
return UIElements.New("ScrollFrame", "shoppingSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Shopping", "general", L["General Options"], L["Some general Browse/Sniper options are below."])
:AddChild(UIElements.New("Frame", "focusFrame")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "checkbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Auto-focus browse search input"])
:SetSettingInfo(TSM.db.global.shoppingOptions, "searchAutoFocus")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(TSM.MainUI.Settings.CreateInputWithReset("marketValueSourceField", L["Market value price source"], "global.shoppingOptions.pctSource")
:SetMargin(0, 0, 0, 12)
)
:AddChild(TSM.MainUI.Settings.CreateInputWithReset("buyoutConfirmationAlert", L["Buyout confirmation alert"], "global.shoppingOptions.buyoutAlertSource")
:SetMargin(0, 0, 0, 12)
)
:AddChild(UIElements.New("Frame", "showConfirmFrame")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Checkbox", "showConfirm")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetCheckboxPosition("LEFT")
:SetSettingInfo(TSM.db.global.shoppingOptions, "buyoutConfirm")
:SetText(L["Show confirmation alert if buyout is above the alert price"])
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Shopping", "disenchant", L["Disenchant Search Options"], L["Some options for the Disenchant Search are below."])
:AddChild(UIElements.New("Text", "minLevelLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Minimum disenchant level"])
)
:AddChild(UIElements.New("Frame", "minLevelInput")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Input", "input")
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("ACTIVE_BG")
:SetFont("BODY_BODY2_MEDIUM")
:SetValidateFunc("NUMBER", "0:"..MAX_ITEM_LEVEL)
:SetSettingInfo(TSM.db.global.shoppingOptions, "minDeSearchLvl")
)
:AddChild(UIElements.New("Text", "rangeText")
:SetWidth("AUTO")
:SetFont("BODY_BODY3")
:SetText(format(L["(minimum 0 - maximum %d)"], MAX_ITEM_LEVEL))
)
)
:AddChild(UIElements.New("Text", "maxLevelLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Maximum disenchant level"])
)
:AddChild(UIElements.New("Frame", "maxLevelInput")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Input", "input")
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("ACTIVE_BG")
:SetFont("BODY_BODY2_MEDIUM")
:SetValidateFunc("NUMBER", "0:"..MAX_ITEM_LEVEL)
:SetSettingInfo(TSM.db.global.shoppingOptions, "maxDeSearchLvl")
)
:AddChild(UIElements.New("Text", "rangeText")
:SetWidth("AUTO")
:SetFont("BODY_BODY3")
:SetText(format(L["(minimum 0 - maximum %d)"], MAX_ITEM_LEVEL))
)
)
:AddChild(UIElements.New("Text", "pctLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Maximum disenchant search percent"])
)
:AddChild(UIElements.New("Frame", "pctInput")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:AddChild(UIElements.New("Input", "input")
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("ACTIVE_BG")
:SetFont("BODY_BODY2_MEDIUM")
:SetValidateFunc("NUMBER", "0:100")
:SetSettingInfo(TSM.db.global.shoppingOptions, "maxDeSearchPercent")
)
:AddChild(UIElements.New("Text", "rangeText")
:SetWidth("AUTO")
:SetFont("BODY_BODY3")
:SetText(format(L["(minimum 0 - maximum %d)"], 100))
)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Shopping", "sniper", L["Sniper Options"], L["Options specific to Sniper are below."])
:AddChild(UIElements.New("Text", "soundLabel")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Found auction sound"])
)
:AddChild(UIElements.New("SelectionDropdown", "soundDrodown")
:SetHeight(24)
:SetItems(private.sounds, private.soundkeys)
:SetSettingInfo(TSM.db.global.sniperOptions, "sniperSound")
:SetScript("OnSelectionChanged", private.SoundOnSelectionChanged)
)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.SoundOnSelectionChanged(self)
Sound.PlaySound(self:GetSelectedItemKey())
end

View File

@@ -0,0 +1,395 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Tooltip = TSM.MainUI.Settings:NewPackage("Tooltip")
local L = TSM.Include("Locale").GetTable()
local Money = TSM.Include("Util.Money")
local Table = TSM.Include("Util.Table")
local TempTable = TSM.Include("Util.TempTable")
local CustomPrice = TSM.Include("Service.CustomPrice")
local UIElements = TSM.Include("UI.UIElements")
local private = {
operationModules = {},
operationModuleNames = {},
destroySources = {},
destroySourceKeys = {},
}
local INVALID_DESTROY_PRICE_SOURCES = {
crafting = true,
vendorbuy = true,
vendorsell = true,
destroy = true,
itemquality = true,
itemlevel = true,
requiredlevel = true,
numinventory = true,
numexpires = true,
salerate = true,
dbregionsalerate = true,
dbregionsoldperday = true,
auctioningopmin = true,
auctioningopmax = true,
auctioningopnormal = true,
shoppingopmax = true,
sniperopmax = true,
}
local GROUPS_OPS_SETTINGS_INFO = {
{ label = L["Group name"], settingKey = "groupNameTooltip" },
{ label = L["Auctioning operation"], settingTbl = "operationTooltips", settingKey = "Auctioning" },
{ label = L["Crafting operation"], settingTbl = "operationTooltips", settingKey = "Crafting" },
{ label = L["Mailing operation"], settingTbl = "operationTooltips", settingKey = "Mailing" },
{ label = L["Shopping operation"], settingTbl = "operationTooltips", settingKey = "Shopping" },
{ label = L["Sniper operation"], settingTbl = "operationTooltips", settingKey = "Sniper" },
{ label = L["Vendoring operation"], settingTbl = "operationTooltips", settingKey = "Vendoring" },
{ label = L["Warehousing operation"], settingTbl = "operationTooltips", settingKey = "Warehousing" },
}
local VALUES_SETTINGS_INFO = {
{ label = L["Disenchant value"], settingKey = "deTooltip" },
{ label = L["Mill value"], settingKey = "millTooltip" },
{ label = L["Prospect value"], settingKey = "prospectTooltip" },
{ label = L["Transform value"], settingKey = "transformTooltip" },
{ label = L["Detailed destroy information"], settingKey = "detailedDestroyTooltip" },
{ label = L["Vendor buy price"], settingKey = "vendorBuyTooltip" },
{ label = L["Vendor sell price"], settingKey = "vendorSellTooltip" },
}
local INVENTORY_SETTINGS_INFO = {
{ label = L["Full inventory"], settingKey = "inventoryTooltipFormat", setValue = "full", clearValue = "none" },
{ label = L["Simple inventory"], settingKey = "inventoryTooltipFormat", setValue = "simple", clearValue = "none" },
}
local ACCOUNTING_SETTINGS_INFO = {
{ label = L["Purchase information"], settingModule = "Accounting", settingKey = "purchase" },
{ label = L["Sale information"], settingModule = "Accounting", settingKey = "sale" },
{ label = L["Sale rate"], settingModule = "Accounting", settingKey = "saleRate" },
{ label = L["Expired information"], settingModule = "Accounting", settingKey = "expiredAuctions" },
{ label = L["Canceled information"], settingModule = "Accounting", settingKey = "cancelledAuctions" },
}
local AUCTIONDB_SETTINGS_INFO = {
{ label = L["Min buyout"], settingModule = "AuctionDB", settingKey = "minBuyout" },
{ label = L["Market value"], settingModule = "AuctionDB", settingKey = "marketValue" },
{ label = L["Historical price"], settingModule = "AuctionDB", settingKey = "historical" },
{ label = L["Region min buyout avg"], settingModule = "AuctionDB", settingKey = "regionMinBuyout" },
{ label = L["Region market value"], settingModule = "AuctionDB", settingKey = "regionMarketValue" },
{ label = L["Region historical price"], settingModule = "AuctionDB", settingKey = "regionHistorical" },
{ label = L["Region sale avg"], settingModule = "AuctionDB", settingKey = "regionSale" },
{ label = L["Region sale rate"], settingModule = "AuctionDB", settingKey = "regionSalePercent" },
{ label = L["Region avg daily sold"], settingModule = "AuctionDB", settingKey = "regionSoldPerDay" },
}
local AUCTIONING_SETTINGS_INFO = {
{ label = L["Post Quantity"], settingModule = "Auctioning", settingKey = "postQuantity" },
{ label = L["Min/Normal/Max price"], settingModule = "Auctioning", settingKey = "operationPrices" },
}
local CRAFTING_SETTINGS_INFO = {
{ label = L["Crafting cost"], settingModule = "Crafting", settingKey = "craftingCost" },
{ label = L["Detailed crafting cost"], settingModule = "Crafting", settingKey = "detailedMats" },
{ label = L["Mat cost"], settingModule = "Crafting", settingKey = "matPrice" },
}
local SHOPPING_SETTINGS_INFO = {
{ label = L["Max shopping price"], settingModule = "Shopping", settingKey = "maxPrice" },
}
local SNIPER_SETTINGS_INFO = {
{ label = L["Max sniper price"], settingModule = "Sniper", settingKey = "belowPrice" },
}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Tooltip.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Tooltip Settings"], "top", private.GetTooltipSettingsFrame)
end
-- ============================================================================
-- Tooltip Settings UI
-- ============================================================================
function private.GetTooltipSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "tooltips", "main")
wipe(private.operationModules)
wipe(private.operationModuleNames)
for _, moduleName in TSM.Operations.ModuleIterator() do
tinsert(private.operationModules, moduleName)
tinsert(private.operationModuleNames, TSM.Operations.GetLocalizedName(moduleName))
end
wipe(private.destroySources)
wipe(private.destroySourceKeys)
local foundCurrentSetting = false
for key, _, label in CustomPrice.Iterator() do
key = strlower(key)
if not INVALID_DESTROY_PRICE_SOURCES[key] then
tinsert(private.destroySources, label)
tinsert(private.destroySourceKeys, key)
if TSM.db.global.coreOptions.destroyValueSource == key then
foundCurrentSetting = true
end
end
end
if not foundCurrentSetting then
-- the current setting isn't in the list, so reset it to the default
TSM.db.global.coreOptions.destroyValueSource = strlower(TSM.db:GetDefaultReadOnly("global", "coreOptions", "destroyValueSource"))
end
return UIElements.New("ScrollFrame", "tooltipSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Tooltip", "general", L["General Options"], L["Some general options for the TSM tooltip information are below."])
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Enable TSM tooltips"])
)
:AddChild(UIElements.New("ToggleOnOff", "enableToggle")
:SetHeight(24)
:SetMargin(0, 0, 0, 12)
:SetSettingInfo(TSM.db.global.tooltipOptions, "enabled")
)
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "embedCheckbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Embed TSM tooltip"])
:SetSettingInfo(TSM.db.global.tooltipOptions, "embeddedTooltip")
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(UIElements.New("Frame", "labelRow1")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 4)
:AddChild(UIElements.New("Text", "priceFormatLabel")
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Tooltip price format"])
)
:AddChild(UIElements.New("Text", "modifierLabel")
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Show on modifier"])
)
:AddChild(UIElements.New("Text", "destroyLabel")
:SetFont("BODY_BODY2_MEDIUM")
:SetText(L["Destroy value source"])
)
)
:AddChild(UIElements.New("Frame", "dropdownRow1")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:AddChild(UIElements.New("SelectionDropdown", "priceFormatDropdown")
:SetMargin(0, 8, 0, 0)
:AddItem(format(L["Coins (%s)"], Money.ToString(3451267, nil, "OPT_ICON")), "icon")
:AddItem(format(L["Text (%s)"], Money.ToString(3451267)), "text")
:SetSettingInfo(TSM.db.global.tooltipOptions, "tooltipPriceFormat")
:SetScript("OnSelectionChanged", private.OnSettingChange)
)
:AddChild(UIElements.New("SelectionDropdown", "modifierDropdown")
:SetMargin(0, 8, 0, 0)
:AddItem(L["None (Always Show)"], "none")
:AddItem(ALT_KEY, "alt")
:AddItem(CTRL_KEY, "ctrl")
:SetSettingInfo(TSM.db.global.tooltipOptions, "tooltipShowModifier")
)
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
:SetItems(private.destroySources, private.destroySourceKeys)
:SetSettingInfo(TSM.db.global.coreOptions, "destroyValueSource")
:SetScript("OnSelectionChanged", private.OnSettingChange)
)
)
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Tooltip", "options", L["Tooltip Options"], L["Use the settings below to control which lines are shown in tooltips."])
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(private.GetSettingsHeight())
:AddChild(UIElements.New("Frame", "settings")
:SetLayout("VERTICAL")
:SetMargin(0, 8, 0, -12)
:AddChildrenWithFunction(private.AddTooltipSettings)
)
:AddChild(UIElements.New("Frame", "example")
:SetLayout("VERTICAL")
:AddChild(UIElements.New("Text", "label")
:SetHeight(20)
:SetMargin(0, 0, 0, 6)
:SetFont("BODY_BODY2_BOLD")
:SetText(L["Example Tooltip"])
)
:AddChild(UIElements.New("Frame", "tooltip")
:SetLayout("VERTICAL")
:SetPadding(4)
:SetBackgroundColor("PRIMARY_BG")
:AddChildrenWithFunction(private.AddExampleTooltip)
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
)
)
end
function private.GetSettingsHeight()
-- calculate the height of the settings and use that for the content height since the settings will always be larger than the tooltip
local height = 0
height = height + 32 + #GROUPS_OPS_SETTINGS_INFO * 32
height = height + 32 + #VALUES_SETTINGS_INFO * 32 + Table.Count(TSM.db.global.userData.customPriceSources) * 32
height = height + 32 + #INVENTORY_SETTINGS_INFO * 32
height = height + 32 + #ACCOUNTING_SETTINGS_INFO * 32
height = height + 32 + #AUCTIONDB_SETTINGS_INFO * 32
height = height + 32 + #AUCTIONING_SETTINGS_INFO * 32
height = height + 32 + #CRAFTING_SETTINGS_INFO * 32
height = height + 32 + #SHOPPING_SETTINGS_INFO * 32
height = height + 32 + #SNIPER_SETTINGS_INFO * 32
height = height - 12
return height
end
function private.AddTooltipSettings(frame)
private.AddSettingHeading(frame, "groupsOpsHeading", L["Groups & Operations"])
private.AddSettingsFromInfoTable(frame, GROUPS_OPS_SETTINGS_INFO)
private.AddSettingHeading(frame, "valuesHeading", L["Values"])
private.AddSettingsFromInfoTable(frame, VALUES_SETTINGS_INFO)
local customPriceSources = TempTable.Acquire()
for name in pairs(TSM.db.global.userData.customPriceSources) do
tinsert(customPriceSources, name)
end
sort(customPriceSources)
for _, name in ipairs(customPriceSources) do
frame:AddChild(UIElements.New("Checkbox", "checkbox_"..name)
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:SetFont("BODY_BODY2")
:SetCheckboxPosition("LEFT")
:SetText(format(L["Custom source (%s)"], name))
:SetSettingInfo(TSM.db.global.tooltipOptions.customPriceTooltips, name)
:SetScript("OnValueChanged", private.CustomPriceSourceOnValueChanged)
)
end
TempTable.Release(customPriceSources)
private.AddSettingHeading(frame, "inventoryHeading", L["Inventory"])
private.AddSettingsFromInfoTable(frame, INVENTORY_SETTINGS_INFO)
private.AddSettingHeading(frame, "accountingHeading", L["Accounting"])
private.AddSettingsFromInfoTable(frame, ACCOUNTING_SETTINGS_INFO)
private.AddSettingHeading(frame, "auctiondbHeading", L["AuctionDB"])
private.AddSettingsFromInfoTable(frame, AUCTIONDB_SETTINGS_INFO)
private.AddSettingHeading(frame, "auctioningHeading", L["Auctioning"])
private.AddSettingsFromInfoTable(frame, AUCTIONING_SETTINGS_INFO)
private.AddSettingHeading(frame, "craftingHeading", L["Crafting"])
private.AddSettingsFromInfoTable(frame, CRAFTING_SETTINGS_INFO)
private.AddSettingHeading(frame, "shoppingHeading", L["Shopping"])
private.AddSettingsFromInfoTable(frame, SHOPPING_SETTINGS_INFO)
private.AddSettingHeading(frame, "sniperHeading", L["Sniper"])
private.AddSettingsFromInfoTable(frame, SNIPER_SETTINGS_INFO)
end
function private.AddSettingHeading(frame, id, heading)
frame:AddChild(UIElements.New("Text", id)
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:SetFont("BODY_BODY2_BOLD")
:SetText(heading)
)
end
function private.GetSettingTableFromInfo(info)
local settingTbl = TSM.db.global.tooltipOptions
if info.settingModule then
settingTbl = settingTbl.moduleTooltips[info.settingModule]
end
if info.settingTbl then
settingTbl = settingTbl[info.settingTbl]
end
return settingTbl
end
function private.AddSettingsFromInfoTable(frame, infoTbl)
for i, info in ipairs(infoTbl) do
local settingTbl = private.GetSettingTableFromInfo(info)
frame:AddChild(UIElements.New("Checkbox", "checkbox_"..i)
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:SetFont("BODY_BODY2")
:SetCheckboxPosition("LEFT")
:SetContext(info)
:SetText(info.label)
:SetChecked(settingTbl[info.settingKey] == (info.setValue or true))
:SetScript("OnValueChanged", private.ContentCheckboxOnValueChanged)
)
end
end
function private.AddExampleTooltip(frame)
for i, left, right, lineColor in TSM.Tooltip.SettingsLineIterator() do
frame:AddChild(UIElements.New("Frame", "row_"..i)
:SetLayout("HORIZONTAL")
:SetHeight(20)
:AddChild(UIElements.New("Text", "left_"..i)
:SetWidth("AUTO")
:SetFont("ITEM_BODY3")
:SetTextColor(lineColor)
:SetText(left)
)
:AddChild(UIElements.New("Spacer", "spacer"))
:AddChildIf(right, UIElements.New("Text", "right_"..i)
:SetWidth("AUTO")
:SetFont("ITEM_BODY3")
:SetTextColor(lineColor)
:SetJustifyH("RIGHT")
:SetText(right or "")
)
)
end
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.OnSettingChange(checkbox)
private.RebuildExampleTooltip(checkbox:GetElement("__parent.__parent.__parent.__parent.options.content.content.example.tooltip"))
end
function private.ContentCheckboxOnValueChanged(checkbox)
local info = checkbox:GetContext()
local settingTbl = private.GetSettingTableFromInfo(info)
if checkbox:IsChecked() then
settingTbl[info.settingKey] = info.setValue or true
else
settingTbl[info.settingKey] = info.clearValue or false
end
local frame = checkbox:GetParentElement()
for _, child in frame:LayoutChildrenIterator() do
local childContext = child:GetContext()
if child ~= checkbox and childContext and childContext.settingTbl == info.settingTbl and childContext.settingKey == info.settingKey then
child:SetChecked(settingTbl[childContext.settingKey] == (childContext.setValue or true), true)
:Draw()
end
end
private.RebuildExampleTooltip(checkbox:GetElement("__parent.__parent.example.tooltip"))
end
function private.CustomPriceSourceOnValueChanged(checkbox)
private.RebuildExampleTooltip(checkbox:GetElement("__parent.__parent.example.tooltip"))
end
function private.RebuildExampleTooltip(tooltipFrame)
tooltipFrame:ReleaseAllChildren()
tooltipFrame:AddChildrenWithFunction(private.AddExampleTooltip)
tooltipFrame:Draw()
end

View File

@@ -0,0 +1,83 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Vendoring = TSM.MainUI.Settings:NewPackage("Vendoring")
local L = TSM.Include("Locale").GetTable()
local ItemInfo = TSM.Include("Service.ItemInfo")
local UIElements = TSM.Include("UI.UIElements")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Vendoring.OnInitialize()
TSM.MainUI.Settings.RegisterSettingPage(L["Vendoring"], "middle", private.GetVendoringSettingsFrame)
end
-- ============================================================================
-- Vendoring Settings UI
-- ============================================================================
function private.GetVendoringSettingsFrame()
TSM.UI.AnalyticsRecordPathChange("main", "settings", "vendoring")
return UIElements.New("ScrollFrame", "vendoringSettings")
:SetPadding(8, 8, 8, 0)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Vendoring", "general", L["General Options"], "")
:AddChild(UIElements.New("Frame", "content")
:SetLayout("HORIZONTAL")
:SetHeight(20)
:SetMargin(0, 0, 0, 12)
:AddChild(UIElements.New("Checkbox", "checkbox")
:SetWidth("AUTO")
:SetFont("BODY_BODY2_MEDIUM")
:SetSettingInfo(TSM.db.global.vendoringOptions, "displayMoneyCollected")
:SetText(L["Display total money received in chat"])
)
:AddChild(UIElements.New("Spacer", "spacer"))
)
:AddChild(TSM.MainUI.Settings.CreateInputWithReset("qsMarketValueSourceField", L["Market Value Price Source"], "global.vendoringOptions.qsMarketValue"))
)
:AddChild(TSM.MainUI.Settings.CreateExpandableSection("Vendoring", "ignore", L["Ignored Items"], "Use this list to manage what items you'd like TSM to ignore from vendoring.")
:AddChild(UIElements.New("QueryScrollingTable", "items")
:SetHeight(326)
:GetScrollingTableInfo()
:NewColumn("item")
:SetTitle(L["Item"])
:SetFont("ITEM_BODY3")
:SetJustifyH("LEFT")
:SetIconSize(12)
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
:SetIconInfo("itemString", ItemInfo.GetTexture)
:SetTooltipInfo("itemString")
:SetSortInfo("name")
:DisableHiding()
:Commit()
:Commit()
:SetQuery(TSM.Vendoring.Sell.CreateIgnoreQuery())
:SetAutoReleaseQuery(true)
:SetSelectionDisabled(true)
:SetScript("OnRowClick", private.IgnoredItemsOnRowClick)
)
)
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.IgnoredItemsOnRowClick(_, row, mouseButton)
if mouseButton ~= "LeftButton" then
return
end
TSM.Vendoring.Sell.ForgetIgnoreItemPermanent(row:GetField("itemString"))
end