initial commit
This commit is contained in:
91
Core/UI/MainUI/Core.lua
Normal file
91
Core/UI/MainUI/Core.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local MainUI = TSM:NewPackage("MainUI")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settings = nil,
|
||||
topLevelPages = {},
|
||||
frame = nil,
|
||||
}
|
||||
local MIN_FRAME_SIZE = { width = 720, height = 588 }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function MainUI.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "frame")
|
||||
end
|
||||
|
||||
function MainUI.OnDisable()
|
||||
-- hide the frame
|
||||
if private.frame then
|
||||
MainUI.Toggle()
|
||||
end
|
||||
end
|
||||
|
||||
function MainUI.RegisterTopLevelPage(name, callback)
|
||||
tinsert(private.topLevelPages, { name = name, callback = callback })
|
||||
end
|
||||
|
||||
function MainUI.Toggle()
|
||||
if private.frame then
|
||||
-- it's already shown, so hide it
|
||||
private.frame:Hide()
|
||||
assert(not private.frame)
|
||||
else
|
||||
private.frame = private.CreateMainFrame()
|
||||
private.frame:Draw()
|
||||
private.frame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Main Frame
|
||||
-- ============================================================================
|
||||
|
||||
function private.CreateMainFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main")
|
||||
-- Always show the Dashboard first
|
||||
private.settings.frame.page = 1
|
||||
local frame = UIElements.New("LargeApplicationFrame", "base")
|
||||
:SetParent(UIParent)
|
||||
:SetSettingsContext(private.settings, "frame")
|
||||
:SetMinResize(MIN_FRAME_SIZE.width, MIN_FRAME_SIZE.height)
|
||||
:SetStrata("HIGH")
|
||||
:AddPlayerGold()
|
||||
:AddAppStatusIcon()
|
||||
:SetScript("OnHide", private.BaseFrameOnHide)
|
||||
for _, info in ipairs(private.topLevelPages) do
|
||||
frame:AddNavButton(info.name, info.callback)
|
||||
end
|
||||
local whatsNewDialog = TSM.UI.WhatsNew.GetDialog()
|
||||
if whatsNewDialog then
|
||||
frame:ShowDialogFrame(whatsNewDialog)
|
||||
end
|
||||
return frame
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.BaseFrameOnHide(frame)
|
||||
assert(frame == private.frame)
|
||||
frame:Release()
|
||||
private.frame = nil
|
||||
TSM.UI.AnalyticsRecordClose("main")
|
||||
end
|
||||
936
Core/UI/MainUI/Dashboard.lua
Normal file
936
Core/UI/MainUI/Dashboard.lua
Normal file
@@ -0,0 +1,936 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Dashboard = TSM.MainUI:NewPackage("Dashboard")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local TempTable = TSM.Include("Util.TempTable")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local Math = TSM.Include("Util.Math")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local Analytics = TSM.Include("Util.Analytics")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settings = nil,
|
||||
characterGuilds = {},
|
||||
tempTimeTable = {},
|
||||
selectedTimeRange = nil,
|
||||
}
|
||||
local SECONDS_PER_DAY = 60 * 60 * 24
|
||||
local MIN_GRAPH_STEP_SIZE = TSM.IsWowClassic() and COPPER_PER_GOLD or (COPPER_PER_GOLD * 1000)
|
||||
local TIME_RANGE_LOOKUP = {
|
||||
["1d"] = SECONDS_PER_DAY,
|
||||
["1w"] = SECONDS_PER_DAY * 7,
|
||||
["1m"] = SECONDS_PER_DAY * 30,
|
||||
["3m"] = SECONDS_PER_DAY * 91,
|
||||
["6m"] = SECONDS_PER_DAY * 183,
|
||||
["1y"] = SECONDS_PER_DAY * 365,
|
||||
["2y"] = SECONDS_PER_DAY * 730,
|
||||
["all"] = -1,
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Dashboard.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "dashboardDividedContainer")
|
||||
:AddKey("global", "mainUIContext", "dashboardUnselectedCharacters")
|
||||
:AddKey("global", "mainUIContext", "dashboardTimeRange")
|
||||
private.selectedTimeRange = private.settings.dashboardTimeRange
|
||||
TSM.MainUI.RegisterTopLevelPage(L["Dashboard"], private.GetDashboardFrame)
|
||||
end
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Dashboard UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetDashboardFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "dashboard")
|
||||
|
||||
private.selectedTimeRange = private.settings.dashboardTimeRange
|
||||
wipe(private.characterGuilds)
|
||||
local prevUnselectedCharacters = TempTable.Acquire()
|
||||
for characterGuild in pairs(private.settings.dashboardUnselectedCharacters) do
|
||||
prevUnselectedCharacters[characterGuild] = true
|
||||
end
|
||||
wipe(private.settings.dashboardUnselectedCharacters)
|
||||
for characterGuild in TSM.Accounting.GoldTracker.CharacterGuildIterator() do
|
||||
tinsert(private.characterGuilds, characterGuild)
|
||||
private.settings.dashboardUnselectedCharacters[characterGuild] = prevUnselectedCharacters[characterGuild] or nil
|
||||
end
|
||||
TempTable.Release(prevUnselectedCharacters)
|
||||
|
||||
local frame = UIElements.New("DividedContainer", "dashboard")
|
||||
:SetSettingsContext(private.settings, "dashboardDividedContainer")
|
||||
:SetMinWidth(200, 407)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:SetLeftChild(UIElements.New("Frame", "news")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetSize("AUTO", 24)
|
||||
:SetMargin(8)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(L["News & Information"])
|
||||
)
|
||||
:AddChild(UIElements.New("ScrollFrame", "content")
|
||||
:SetPadding(8, 8, 0, 0)
|
||||
)
|
||||
)
|
||||
:SetRightChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:SetScript("OnUpdate", private.ContentOnUpdate)
|
||||
:AddChild(UIElements.New("Frame", "goldHeader")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(L["Player Gold"])
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "playerDropdown")
|
||||
:SetSize(157, 22)
|
||||
:SetItems(private.characterGuilds, private.characterGuilds)
|
||||
:SetUnselectedItemKeys(private.settings.dashboardUnselectedCharacters)
|
||||
:SetSelectionText(L["No Players"], L["%d Players"], L["All Players"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer"))
|
||||
:AddChild(UIElements.New("Text", "hoverTime")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText("")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "timeBtns")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:AddChild(UIElements.New("Button", "1d")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["1d"])
|
||||
:SetText(L["1D"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "1w")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["1w"])
|
||||
:SetText(L["1W"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "1m")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["1m"])
|
||||
:SetText(L["1M"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "3m")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["3m"])
|
||||
:SetText(L["3M"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "6m")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["6m"])
|
||||
:SetText(L["6M"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "1y")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["1y"])
|
||||
:SetText(L["1Y"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "2y")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["2y"])
|
||||
:SetText(L["2Y"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "all")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(20, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("TEXT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["all"])
|
||||
:SetText(ALL)
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "resetZoom")
|
||||
:SetMargin(8, 0, 0, 0)
|
||||
:SetSize(100, 20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("TEXT")
|
||||
:SetContext(TIME_RANGE_LOOKUP["all"])
|
||||
:SetText(L["Reset Zoom"])
|
||||
:SetScript("OnClick", private.TimeBtnOnClick)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Graph", "goldGraph")
|
||||
:SetMargin(0, 0, 8, 8)
|
||||
:SetAxisStepFunctions(private.GraphXStepFunc, private.GraphYStepFunc)
|
||||
:SetXRange(TSM.Accounting.GoldTracker.GetGraphTimeRange(private.settings.dashboardUnselectedCharacters))
|
||||
:SetYValueFunction(private.GetGraphYValue)
|
||||
:SetFormatFunctions(private.GraphFormatX, private.GraphFormatY)
|
||||
:SetScript("OnZoomChanged", private.GraphOnZoomChanged)
|
||||
:SetScript("OnHoverUpdate", private.GraphOnHoverUpdate)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "summary")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(48)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||||
:AddChild(UIElements.New("Frame", "range")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:AddChild(UIElements.New("Frame", "high")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["HIGH"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "low")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["LOW"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line1")
|
||||
:SetWidth(1)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "daily")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:AddChild(UIElements.New("Frame", "sales")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["DAILY SALES"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "purchases")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["DAILY PURCHASES"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line2")
|
||||
:SetWidth(1)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "top")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:AddChild(UIElements.New("Frame", "sale")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["TOP SALE"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "expense")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["TOP PURCHASE"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "details")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||||
:AddChild(UIElements.New("Text", "salesLabel")
|
||||
:SetHeight(20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["SALES"])
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "salesTotal")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Total Gold Earned"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "salesAvg")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Average Earned per Day"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "salesTop")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Top Item"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Button", "item")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line1")
|
||||
:SetHeight(1)
|
||||
:SetMargin(-8, -8, 4, 4)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "expensesLabel")
|
||||
:SetHeight(20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["EXPENSES"])
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "expensesTotal")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Total Gold Spent"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "expensesAvg")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Average Spent per Day"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "expensesTop")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Top Item"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Button", "item")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line2")
|
||||
:SetHeight(1)
|
||||
:SetMargin(-8, -8, 4, 4)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "profitLabel")
|
||||
:SetHeight(20)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["PROFIT"])
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "profitTotal")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Total Profit"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "profitAvg")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Average Profit per Day"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "amount")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "profitTop")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 4, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Top Item"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Button", "item")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
frame:GetElement("content.goldHeader.timeBtns.resetZoom"):Hide()
|
||||
frame:GetElement("content.goldHeader.hoverTime"):Hide()
|
||||
|
||||
local newsContent = frame:GetElement("news.content")
|
||||
local newsEntries = TSM.GetAppNews()
|
||||
if newsEntries then
|
||||
for i, info in ipairs(newsEntries) do
|
||||
newsContent:AddChild(UIElements.New("Frame", "news"..i)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(0, 0, i == 1 and 6 or 12, 0)
|
||||
:AddChild(UIElements.New("Text", "date")
|
||||
:SetHeight(20)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(date("%b %d, %Y", info.timestamp))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "title")
|
||||
:SetHeight(20)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetText(info.title)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "content")
|
||||
:SetHeight(80)
|
||||
:SetPadding(0, 0, 4, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(info.content)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "readMore")
|
||||
:SetHeight(20)
|
||||
:SetPadding(0, 0, 4, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor("INDICATOR")
|
||||
:SetText(L["Read More"])
|
||||
)
|
||||
)
|
||||
:AddChildNoLayout(UIElements.New("Button", "btn")
|
||||
:AddAnchor("TOPLEFT", "news"..i)
|
||||
:AddAnchor("BOTTOMRIGHT", "news"..i)
|
||||
:SetContext(info)
|
||||
:SetScript("OnClick", private.ButtonOnClick)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.ButtonOnClick(button)
|
||||
local info = button:GetContext()
|
||||
Analytics.Action("NEWS_READ_MORE", info.title)
|
||||
button:GetBaseElement():ShowDialogFrame(UIElements.New("Frame", "frame")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetSize(600, 450)
|
||||
:AddAnchor("CENTER")
|
||||
:SetBackgroundColor("FRAME_BG")
|
||||
:SetBorderColor("ACTIVE_BG")
|
||||
:AddChild(UIElements.New("Text", "title")
|
||||
:SetHeight(44)
|
||||
:SetMargin(16, 16, 16, 8)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetJustifyH("CENTER")
|
||||
:SetText(info.title)
|
||||
)
|
||||
:AddChild(UIElements.New("Input", "linkInput")
|
||||
:SetHeight(26)
|
||||
:SetMargin(16, 16, 0, 16)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:SetValidateFunc(private.LinkValidateFunc)
|
||||
:SetContext(info.link)
|
||||
:SetValue(info.link)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "content")
|
||||
:SetMargin(16, 16, 0, 16)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetJustifyV("TOP")
|
||||
:SetText(info.content)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "buttons")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(26)
|
||||
:SetMargin(16, 16, 0, 16)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("ActionButton", "confirmBtn")
|
||||
:SetWidth(126)
|
||||
:SetText(CLOSE)
|
||||
:SetScript("OnClick", private.DialogCloseBtnOnClick)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function private.LinkValidateFunc(input, value)
|
||||
return value == input:GetContext()
|
||||
end
|
||||
|
||||
function private.DialogCloseBtnOnClick(button)
|
||||
button:GetBaseElement():HideDialog()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.GraphFormatX(timestamp, suggestedStep)
|
||||
if suggestedStep > SECONDS_PER_DAY * 14 then
|
||||
return date("%b '%y", timestamp)
|
||||
elseif suggestedStep > SECONDS_PER_DAY * 2 then
|
||||
return date("%b %d", timestamp)
|
||||
elseif suggestedStep > SECONDS_PER_DAY / 6 then
|
||||
return date("%a", timestamp)
|
||||
else
|
||||
if GetCVar("timeMgrUseMilitaryTime") == "1" then
|
||||
return date("%H:%M", timestamp)
|
||||
else
|
||||
return strtrim(date("%I %p", timestamp), "0")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function private.GraphFormatY(value, suggestedStep, isTooltip)
|
||||
if isTooltip then
|
||||
return Money.ToString(value, nil, "OPT_TRIM")
|
||||
end
|
||||
if TSM.IsWowClassic() and value < COPPER_PER_GOLD * 1000 then
|
||||
-- "###g"
|
||||
return floor(value / COPPER_PER_GOLD)..Money.GetGoldText()
|
||||
elseif TSM.IsWowClassic() and value < COPPER_PER_GOLD * 1000 * 10 then
|
||||
-- "#.##Kg"
|
||||
return format("%.2f", value / (COPPER_PER_GOLD * 1000)).."k"..Money.GetGoldText()
|
||||
elseif value < COPPER_PER_GOLD * 1000 * 1000 then
|
||||
-- "###Kg"
|
||||
return floor(value / (COPPER_PER_GOLD * 1000)).."k"..Money.GetGoldText()
|
||||
elseif value < COPPER_PER_GOLD * 1000 * 1000 * 10 then
|
||||
-- "#.##Mg"
|
||||
return format("%.2f", value / (COPPER_PER_GOLD * 1000 * 1000)).."M"..Money.GetGoldText()
|
||||
else
|
||||
-- "###Mg"
|
||||
return floor(value / (COPPER_PER_GOLD * 1000 * 1000)).."M"..Money.GetGoldText()
|
||||
end
|
||||
end
|
||||
|
||||
function private.GetGraphYValue(xValue)
|
||||
return TSM.Accounting.GoldTracker.GetGoldAtTime(xValue, private.settings.dashboardUnselectedCharacters)
|
||||
end
|
||||
|
||||
function private.ContentOnUpdate(contentFrame)
|
||||
contentFrame:SetScript("OnUpdate", nil)
|
||||
private.UpdateTimeButtons(contentFrame:GetElement("goldHeader.timeBtns"))
|
||||
private.UpdateGraph(contentFrame)
|
||||
end
|
||||
|
||||
function private.DropdownOnSelectionChanged(dropdown)
|
||||
for _, key in ipairs(private.characterGuilds) do
|
||||
private.settings.dashboardUnselectedCharacters[key] = not dropdown:ItemIsSelectedByKey(key) or nil
|
||||
end
|
||||
private.UpdateGraph(dropdown:GetParentElement():GetParentElement())
|
||||
end
|
||||
|
||||
function private.TimeBtnOnClick(button)
|
||||
local timeRange = button:GetContext()
|
||||
assert(timeRange)
|
||||
private.selectedTimeRange = timeRange
|
||||
private.settings.dashboardTimeRange = timeRange
|
||||
private.UpdateTimeButtons(button:GetParentElement())
|
||||
private.UpdateGraph(button:GetParentElement():GetParentElement():GetParentElement())
|
||||
end
|
||||
|
||||
function private.UpdateGraph(contentFrame)
|
||||
-- update the graph
|
||||
local minTime, maxTime = TSM.Accounting.GoldTracker.GetGraphTimeRange(private.settings.dashboardUnselectedCharacters)
|
||||
local goldGraph = contentFrame:GetElement("goldGraph")
|
||||
local zoomStart, zoomEnd = goldGraph:GetZoom()
|
||||
if private.selectedTimeRange == TIME_RANGE_LOOKUP["all"] then
|
||||
zoomStart = minTime
|
||||
zoomEnd = maxTime
|
||||
elseif private.selectedTimeRange then
|
||||
zoomStart = max(time() - private.selectedTimeRange, minTime)
|
||||
zoomEnd = time()
|
||||
end
|
||||
goldGraph:SetXRange(minTime, maxTime)
|
||||
:SetZoom(zoomStart, zoomEnd)
|
||||
:Draw()
|
||||
private.PopulateDetails(contentFrame)
|
||||
end
|
||||
|
||||
function private.GraphOnZoomChanged(graph)
|
||||
private.selectedTimeRange = nil
|
||||
private.settings.dashboardTimeRange = -1
|
||||
private.UpdateTimeButtons(graph:GetElement("__parent.goldHeader.timeBtns"))
|
||||
private.PopulateDetails(graph:GetElement("__parent"))
|
||||
end
|
||||
|
||||
function private.GraphOnHoverUpdate(graph, hoverTime)
|
||||
local goldHeader = graph:GetElement("__parent.goldHeader")
|
||||
if hoverTime then
|
||||
local timeStr = nil
|
||||
if GetCVar("timeMgrUseMilitaryTime") == "1" then
|
||||
timeStr = date("%H:%M %b %d, %Y", hoverTime)
|
||||
else
|
||||
timeStr = gsub(date("%I:%M %p %b %d, %Y", hoverTime), "^0", "")
|
||||
end
|
||||
goldHeader:GetElement("timeBtns"):Hide()
|
||||
goldHeader:GetElement("hoverTime")
|
||||
:SetText(timeStr)
|
||||
:Show()
|
||||
else
|
||||
goldHeader:GetElement("timeBtns"):Show()
|
||||
goldHeader:GetElement("hoverTime"):Hide()
|
||||
private.UpdateTimeButtons(goldHeader:GetElement("timeBtns"))
|
||||
end
|
||||
goldHeader:Draw()
|
||||
end
|
||||
|
||||
function private.UpdateTimeButtons(frame)
|
||||
frame:ShowAllChildren()
|
||||
local resetButton = frame:GetElement("resetZoom")
|
||||
if private.selectedTimeRange then
|
||||
for _, button in frame:LayoutChildrenIterator() do
|
||||
if button ~= resetButton then
|
||||
button:SetTextColor(private.selectedTimeRange == button:GetContext() and "TEXT" or "ACTIVE_BG_ALT")
|
||||
end
|
||||
end
|
||||
resetButton:Hide()
|
||||
else
|
||||
for _, button in frame:LayoutChildrenIterator() do
|
||||
button:Hide()
|
||||
end
|
||||
resetButton:Show()
|
||||
end
|
||||
frame:GetParentElement():Draw()
|
||||
end
|
||||
|
||||
function private.GraphXStepFunc(prevValue, suggestedStep)
|
||||
local year, day, month, hour, min, sec = strsplit(",", date("%Y,%d,%m,%H,%M,%S", prevValue))
|
||||
private.tempTimeTable.year = tonumber(year)
|
||||
private.tempTimeTable.day = tonumber(day)
|
||||
private.tempTimeTable.month = tonumber(month)
|
||||
private.tempTimeTable.hour = tonumber(hour)
|
||||
private.tempTimeTable.min = tonumber(min)
|
||||
private.tempTimeTable.sec = tonumber(sec)
|
||||
if suggestedStep > SECONDS_PER_DAY * 14 then
|
||||
private.tempTimeTable.month = private.tempTimeTable.month + 1
|
||||
private.tempTimeTable.day = 1
|
||||
private.tempTimeTable.hour = 0
|
||||
private.tempTimeTable.min = 0
|
||||
private.tempTimeTable.sec = 0
|
||||
elseif suggestedStep > SECONDS_PER_DAY / 6 then
|
||||
private.tempTimeTable.day = private.tempTimeTable.day + 1
|
||||
if private.tempTimeTable.hour == 23 then
|
||||
-- add an extra hour to avoid DST issues
|
||||
private.tempTimeTable.hour = 1
|
||||
else
|
||||
private.tempTimeTable.hour = 0
|
||||
end
|
||||
private.tempTimeTable.min = 0
|
||||
private.tempTimeTable.sec = 0
|
||||
else
|
||||
private.tempTimeTable.hour = private.tempTimeTable.hour + 1
|
||||
private.tempTimeTable.min = 0
|
||||
private.tempTimeTable.sec = 0
|
||||
end
|
||||
local newValue = time(private.tempTimeTable)
|
||||
assert(newValue > prevValue)
|
||||
return newValue
|
||||
end
|
||||
|
||||
function private.GraphYStepFunc(mode, ...)
|
||||
if mode == "RANGE" then
|
||||
local yMin, yMax, maxNumSteps = ...
|
||||
-- find the smallest 10^X step size which still looks good
|
||||
local minStep = max((yMax - yMin) / maxNumSteps / 10, yMax / 200)
|
||||
local stepSize = MIN_GRAPH_STEP_SIZE
|
||||
while stepSize < minStep do
|
||||
stepSize = stepSize * 10
|
||||
end
|
||||
yMin = Math.Floor(yMin, stepSize)
|
||||
yMax = Math.Ceil(yMax + stepSize / 3, stepSize)
|
||||
if yMin == yMax then
|
||||
yMax = yMax + stepSize
|
||||
end
|
||||
return yMin, yMax
|
||||
elseif mode == "NEXT" then
|
||||
local prevValue, yMax = ...
|
||||
local stepSize = MIN_GRAPH_STEP_SIZE
|
||||
while stepSize < yMax / 1000 do
|
||||
stepSize = stepSize * 10
|
||||
end
|
||||
return Math.Floor(prevValue, stepSize) + stepSize
|
||||
else
|
||||
error("Invalid mode")
|
||||
end
|
||||
end
|
||||
|
||||
function private.PopulateDetails(contentFrame)
|
||||
local goldGraph = contentFrame:GetElement("goldGraph")
|
||||
local unselectedCharacters = next(private.settings.dashboardUnselectedCharacters) and private.settings.dashboardUnselectedCharacters or nil
|
||||
local timeFilterStart, timeFilterEnd, numDays = nil, nil, nil
|
||||
if private.selectedTimeRange and private.selectedTimeRange ~= -1 then
|
||||
timeFilterStart = time() - private.selectedTimeRange
|
||||
timeFilterEnd = time()
|
||||
numDays = ceil(private.selectedTimeRange / SECONDS_PER_DAY)
|
||||
elseif not private.selectedTimeRange then
|
||||
timeFilterStart, timeFilterEnd = goldGraph:GetZoom()
|
||||
numDays = ceil((timeFilterEnd - timeFilterStart) / SECONDS_PER_DAY)
|
||||
else
|
||||
local timeStart, timeEnd = goldGraph:GetXRange()
|
||||
numDays = ceil((timeEnd - timeStart) / SECONDS_PER_DAY)
|
||||
end
|
||||
numDays = max(numDays, 1)
|
||||
|
||||
local saleTotal, salePerDay, saleTopItem, saleTopValue, saleTotalQuantity = 0, nil, nil, 0, 0
|
||||
local buyTotal, buyPerDay, buyTopItem, buyTopValue, buyTotalQuantity = 0, nil, nil, 0, 0
|
||||
local profitTopItem = nil
|
||||
local query = TSM.Accounting.GetSummaryQuery(timeFilterStart, timeFilterEnd, unselectedCharacters)
|
||||
local saleNumDays, buyNumDays = 1, 1
|
||||
local saleItemTotals = TempTable.Acquire()
|
||||
local buyItemTotals = TempTable.Acquire()
|
||||
local saleItemNum = TempTable.Acquire()
|
||||
local buyItemNum = TempTable.Acquire()
|
||||
for _, recordType, itemString, price, quantity, timestamp in query:Iterator() do
|
||||
if recordType == "sale" then
|
||||
local daysAgo = floor((time() - timestamp) / (24 * 60 * 60))
|
||||
saleNumDays = max(saleNumDays, daysAgo)
|
||||
saleItemTotals[itemString] = (saleItemTotals[itemString] or 0) + price * quantity
|
||||
saleTopValue = max(saleTopValue, price)
|
||||
saleTotalQuantity = saleTotalQuantity + quantity
|
||||
saleItemNum[itemString] = (saleItemNum[itemString] or 0) + quantity
|
||||
elseif recordType == "buy" then
|
||||
local daysAgo = floor((time() - timestamp) / (24 * 60 * 60))
|
||||
buyNumDays = max(buyNumDays, daysAgo)
|
||||
buyItemTotals[itemString] = (buyItemTotals[itemString] or 0) + price * quantity
|
||||
buyTopValue = max(buyTopValue, price)
|
||||
buyTotalQuantity = buyTotalQuantity + quantity
|
||||
buyItemNum[itemString] = (buyItemNum[itemString] or 0) + quantity
|
||||
else
|
||||
error("Invalid recordType: "..tostring(recordType))
|
||||
end
|
||||
end
|
||||
query:Release()
|
||||
|
||||
local topSaleItemTotal = 0
|
||||
for itemString, itemTotal in pairs(saleItemTotals) do
|
||||
saleTotal = saleTotal + itemTotal
|
||||
if itemTotal > topSaleItemTotal then
|
||||
saleTopItem = itemString
|
||||
topSaleItemTotal = itemTotal
|
||||
end
|
||||
end
|
||||
salePerDay = Math.Round(saleTotal / saleNumDays)
|
||||
|
||||
local topBuyItemTotal = 0
|
||||
for itemString, itemTotal in pairs(buyItemTotals) do
|
||||
buyTotal = buyTotal + itemTotal
|
||||
if itemTotal > topBuyItemTotal then
|
||||
buyTopItem = itemString
|
||||
topBuyItemTotal = itemTotal
|
||||
end
|
||||
end
|
||||
buyPerDay = Math.Round(buyTotal / buyNumDays)
|
||||
|
||||
local topItemProfit = 0
|
||||
for itemString in pairs(saleItemNum) do
|
||||
if buyItemNum[itemString] then
|
||||
local profit = (saleItemTotals[itemString] / saleItemNum[itemString] - buyItemTotals[itemString] / buyItemNum[itemString]) * min(saleItemNum[itemString], buyItemNum[itemString])
|
||||
if profit > topItemProfit then
|
||||
profitTopItem = itemString
|
||||
topItemProfit = profit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TempTable.Release(saleItemTotals)
|
||||
TempTable.Release(buyItemTotals)
|
||||
TempTable.Release(saleItemNum)
|
||||
TempTable.Release(buyItemNum)
|
||||
|
||||
local profitTotal = saleTotal - buyTotal
|
||||
local profitPerDay = salePerDay - buyPerDay
|
||||
|
||||
local rangeLow, rangeHigh = goldGraph:GetYRange()
|
||||
contentFrame:GetElement("summary.range.low.value")
|
||||
:SetText(Money.ToString(rangeLow, nil, "OPT_TRIM") or "-")
|
||||
contentFrame:GetElement("summary.range.high.value")
|
||||
:SetText(Money.ToString(rangeHigh, nil, "OPT_TRIM") or "-")
|
||||
|
||||
contentFrame:GetElement("summary.daily.sales.value")
|
||||
:SetText(saleTotalQuantity and Math.Round(saleTotalQuantity / numDays) or "-")
|
||||
contentFrame:GetElement("summary.daily.purchases.value")
|
||||
:SetText(buyTotalQuantity and Math.Round(buyTotalQuantity / numDays) or "-")
|
||||
|
||||
contentFrame:GetElement("summary.top.sale.value")
|
||||
:SetText(Money.ToString(Math.Round(saleTopValue, TSM.IsWowClassic() and 1 or COPPER_PER_GOLD), nil, "OPT_TRIM") or "-")
|
||||
contentFrame:GetElement("summary.top.expense.value")
|
||||
:SetText(Money.ToString(Math.Round(buyTopValue, TSM.IsWowClassic() and 1 or COPPER_PER_GOLD), nil, "OPT_TRIM") or "-")
|
||||
|
||||
contentFrame:GetElement("details.salesTotal.amount")
|
||||
:SetText(Money.ToString(saleTotal))
|
||||
contentFrame:GetElement("details.salesAvg.amount")
|
||||
:SetText(Money.ToString(salePerDay))
|
||||
contentFrame:GetElement("details.salesTop.item")
|
||||
:SetText(TSM.UI.GetColoredItemName(saleTopItem) or "-")
|
||||
:SetTooltip(saleTopItem)
|
||||
|
||||
contentFrame:GetElement("details.expensesTotal.amount")
|
||||
:SetText(Money.ToString(buyTotal))
|
||||
contentFrame:GetElement("details.expensesAvg.amount")
|
||||
:SetText(Money.ToString(buyPerDay))
|
||||
contentFrame:GetElement("details.expensesTop.item")
|
||||
:SetText(TSM.UI.GetColoredItemName(buyTopItem) or "-")
|
||||
:SetTooltip(buyTopItem)
|
||||
|
||||
contentFrame:GetElement("details.profitTotal.amount")
|
||||
:SetText(Money.ToString(profitTotal, profitTotal < 0 and Theme.GetFeedbackColor("RED"):GetTextColorPrefix() or nil))
|
||||
contentFrame:GetElement("details.profitAvg.amount")
|
||||
:SetText(Money.ToString(profitPerDay, profitPerDay < 0 and Theme.GetFeedbackColor("RED"):GetTextColorPrefix() or nil))
|
||||
contentFrame:GetElement("details.profitTop.item")
|
||||
:SetText(TSM.UI.GetColoredItemName(profitTopItem) or "-")
|
||||
:SetTooltip(profitTopItem)
|
||||
|
||||
contentFrame:Draw()
|
||||
end
|
||||
1870
Core/UI/MainUI/Groups.lua
Normal file
1870
Core/UI/MainUI/Groups.lua
Normal file
File diff suppressed because it is too large
Load Diff
266
Core/UI/MainUI/Ledger/Common/Auctions.lua
Normal file
266
Core/UI/MainUI/Ledger/Common/Auctions.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Auctions = TSM.MainUI.Ledger.Common:NewPackage("Auctions")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local String = TSM.Include("Util.String")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local SECONDS_PER_DAY = 24 * 60 * 60
|
||||
local private = {
|
||||
settings = nil,
|
||||
query = nil,
|
||||
characters = {},
|
||||
characterFilter = {},
|
||||
searchFilter = "",
|
||||
groupFilter = {},
|
||||
rarityList = {},
|
||||
rarityFilter = {},
|
||||
timeFrameFilter = 30 * SECONDS_PER_DAY,
|
||||
type = nil
|
||||
}
|
||||
do
|
||||
for i = 1, 4 do
|
||||
tinsert(private.rarityList, _G[format("ITEM_QUALITY%d_DESC", i)])
|
||||
private.rarityFilter[i] = true
|
||||
end
|
||||
end
|
||||
local TIME_LIST = { L["All Time"], L["Last 3 Days"], L["Last 7 Days"], L["Last 14 Days"], L["Last 30 Days"], L["Last 60 Days"] }
|
||||
local TIME_KEYS = { 0, 3 * SECONDS_PER_DAY, 7 * SECONDS_PER_DAY, 14 * SECONDS_PER_DAY, 30 * SECONDS_PER_DAY, 60 * SECONDS_PER_DAY }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Auctions.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerAuctionsScrollingTable")
|
||||
TSM.MainUI.Ledger.FailedAuctions.RegisterPage(L["Expired"], private.DrawExpiredPage)
|
||||
TSM.MainUI.Ledger.FailedAuctions.RegisterPage(L["Cancelled"], private.DrawCancelledPage)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Auctions UIs
|
||||
-- ============================================================================
|
||||
|
||||
function private.DrawExpiredPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "failed_auctions", "expired")
|
||||
private.type = "expire"
|
||||
return private.DrawAuctionsPage()
|
||||
end
|
||||
|
||||
function private.DrawCancelledPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "failed_auctions", "cancelled")
|
||||
private.type = "cancel"
|
||||
return private.DrawAuctionsPage()
|
||||
end
|
||||
|
||||
function private.DrawAuctionsPage()
|
||||
private.query = private.query or TSM.Accounting.Auctions.CreateQuery()
|
||||
|
||||
private.query:Reset()
|
||||
:Equal("type", "cancel")
|
||||
:Distinct("player")
|
||||
:Select("player")
|
||||
wipe(private.characters)
|
||||
for _, character in private.query:Iterator() do
|
||||
tinsert(private.characters, character)
|
||||
private.characterFilter[character] = true
|
||||
end
|
||||
|
||||
private.query:Reset()
|
||||
:InnerJoin(ItemInfo.GetDBForJoin(), "itemString")
|
||||
:LeftJoin(TSM.Groups.GetItemDBForJoin(), "itemString")
|
||||
:OrderBy("time", false)
|
||||
private.UpdateQuery()
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "row1")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8)
|
||||
:AddChild(UIElements.New("Input", "filter")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetIconTexture("iconPack.18x18/Search")
|
||||
:SetClearButtonEnabled(true)
|
||||
:AllowItemInsert()
|
||||
:SetHintText(L["Filter by keyword"])
|
||||
:SetValue(private.searchFilter)
|
||||
:SetScript("OnValueChanged", private.SearchFilterChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("GroupSelector", "group")
|
||||
:SetWidth(240)
|
||||
:SetHintText(L["Filter by groups"])
|
||||
:SetScript("OnSelectionChanged", private.GroupFilterChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "row2")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8, 8, 0, 8)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "rarity")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.rarityList)
|
||||
:SetSettingInfo(private, "rarityFilter")
|
||||
:SetSelectionText(L["No Rarities"], L["%d Rarities"], L["All Rarites"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "character")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.characters, private.characters)
|
||||
:SetSettingInfo(private, "characterFilter")
|
||||
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "time")
|
||||
:SetItems(TIME_LIST, TIME_KEYS)
|
||||
:SetSelectedItemByKey(private.timeFrameFilter)
|
||||
:SetSettingInfo(private, "timeFrameFilter")
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "scrollingTable")
|
||||
:SetSettingsContext(private.settings, "ledgerAuctionsScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("item")
|
||||
:SetTitle(L["Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
|
||||
:SetTooltipInfo("itemString")
|
||||
:SetSortInfo("name")
|
||||
:DisableHiding()
|
||||
:Commit()
|
||||
:NewColumn("player")
|
||||
:SetTitle(PLAYER)
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("player")
|
||||
:SetSortInfo("player")
|
||||
:Commit()
|
||||
:NewColumn("stackSize")
|
||||
:SetTitle(L["Stack"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("stackSize")
|
||||
:SetSortInfo("stackSize")
|
||||
:Commit()
|
||||
:NewColumn("quantity")
|
||||
:SetTitle(L["Auctions"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo(nil, private.FormatAuctions)
|
||||
:SetSortInfo("quantity")
|
||||
:Commit()
|
||||
:NewColumn("time")
|
||||
:SetTitle(L["Time Frame"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("time", private.TableGetTimeframeText)
|
||||
:SetSortInfo("time")
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(private.query)
|
||||
:SetScript("OnRowClick", private.TableSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "footer")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Text", "num")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(format(private.type == "expire" and L["%s Items Expired"] or L["%s Items Cancelled"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(private.query:Sum("quantity") or 0))))
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.TableGetTimeframeText(record)
|
||||
return SecondsToTime(time() - record)
|
||||
end
|
||||
|
||||
function private.FormatAuctions(row)
|
||||
return row:GetField("quantity") / row:GetField("stackSize")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.DropdownCommonOnSelectionChanged(dropdown)
|
||||
private.UpdateQuery()
|
||||
dropdown:GetElement("__parent.__parent.scrollingTable")
|
||||
:UpdateData(true)
|
||||
local footer = dropdown:GetElement("__parent.__parent.footer")
|
||||
footer:GetElement("num"):SetText(format(private.type == "expire" and L["%s Items Expired"] or L["%s Items Cancelled"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(private.query:Sum("quantity") or 0))))
|
||||
footer:Draw()
|
||||
end
|
||||
|
||||
function private.SearchFilterChanged(input)
|
||||
private.searchFilter = input:GetValue()
|
||||
private.DropdownCommonOnSelectionChanged(input)
|
||||
end
|
||||
|
||||
function private.GroupFilterChanged(groupSelector)
|
||||
wipe(private.groupFilter)
|
||||
for groupPath in groupSelector:SelectedGroupIterator() do
|
||||
private.groupFilter[groupPath] = true
|
||||
end
|
||||
private.DropdownCommonOnSelectionChanged(groupSelector)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateQuery()
|
||||
private.query:ResetFilters()
|
||||
:Equal("type", private.type)
|
||||
if private.searchFilter ~= "" then
|
||||
private.query:Matches("name", String.Escape(private.searchFilter))
|
||||
end
|
||||
if Table.Count(private.rarityFilter) ~= #private.rarityList then
|
||||
private.query:InTable("quality", private.rarityFilter)
|
||||
end
|
||||
if Table.Count(private.characterFilter) ~= #private.characters then
|
||||
private.query:InTable("player", private.characterFilter)
|
||||
end
|
||||
if private.timeFrameFilter ~= 0 then
|
||||
private.query:GreaterThanOrEqual("time", time() - private.timeFrameFilter)
|
||||
end
|
||||
if next(private.groupFilter) then
|
||||
private.query:InTable("groupPath", private.groupFilter)
|
||||
end
|
||||
end
|
||||
|
||||
function private.TableSelectionChanged(scrollingTable, row)
|
||||
TSM.MainUI.Ledger.ShowItemDetail(scrollingTable:GetParentElement():GetParentElement(), row:GetField("itemString"), "sale")
|
||||
end
|
||||
8
Core/UI/MainUI/Ledger/Common/Core.lua
Normal file
8
Core/UI/MainUI/Ledger/Common/Core.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
TSM.MainUI.Ledger:NewPackage("Common")
|
||||
208
Core/UI/MainUI/Ledger/Common/Other.lua
Normal file
208
Core/UI/MainUI/Ledger/Common/Other.lua
Normal file
@@ -0,0 +1,208 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Other = TSM.MainUI.Ledger.Common:NewPackage("Other")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local SECONDS_PER_DAY = 24 * 60 * 60
|
||||
local private = {
|
||||
settings = nil,
|
||||
query = nil,
|
||||
characters = {},
|
||||
characterFilter = {},
|
||||
typeFilter = {},
|
||||
recordType = nil,
|
||||
timeFrameFilter = 30 * SECONDS_PER_DAY,
|
||||
}
|
||||
local TIME_LIST = { L["All Time"], L["Last 3 Days"], L["Last 7 Days"], L["Last 14 Days"], L["Last 30 Days"], L["Last 60 Days"] }
|
||||
local TIME_KEYS = { 0, 3 * SECONDS_PER_DAY, 7 * SECONDS_PER_DAY, 14 * SECONDS_PER_DAY, 30 * SECONDS_PER_DAY, 60 * SECONDS_PER_DAY }
|
||||
local TYPE_LIST = {
|
||||
expense = { L["Money Transfer"], L["Postage"], L["Repair Bill"] },
|
||||
income = { L["Money Transfer"], L["Garrison"] },
|
||||
}
|
||||
local TYPE_KEYS = {
|
||||
expense = { "Money Transfer", "Postage", "Repair Bill" },
|
||||
income = { "Money Transfer", "Garrison" },
|
||||
}
|
||||
local TYPE_STR_LOOKUP = {}
|
||||
do
|
||||
-- populate lookup table
|
||||
assert(#TYPE_LIST.expense == #TYPE_KEYS.expense)
|
||||
for i = 1, #TYPE_LIST.expense do
|
||||
TYPE_STR_LOOKUP[TYPE_KEYS.expense[i]] = TYPE_LIST.expense[i]
|
||||
end
|
||||
assert(#TYPE_LIST.income == #TYPE_KEYS.income)
|
||||
for i = 1, #TYPE_LIST.income do
|
||||
TYPE_STR_LOOKUP[TYPE_KEYS.income[i]] = TYPE_LIST.income[i]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Other.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerOtherScrollingTable")
|
||||
TSM.MainUI.Ledger.Expenses.RegisterPage(OTHER, private.DrawOtherExpensesPage)
|
||||
TSM.MainUI.Ledger.Revenue.RegisterPage(OTHER, private.DrawOtherRevenuePage)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Other UIs
|
||||
-- ============================================================================
|
||||
|
||||
function private.DrawOtherExpensesPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "expenses", "other")
|
||||
return private.DrawOtherPage("expense")
|
||||
end
|
||||
|
||||
function private.DrawOtherRevenuePage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "revenue", "other")
|
||||
return private.DrawOtherPage("income")
|
||||
end
|
||||
|
||||
function private.DrawOtherPage(recordType)
|
||||
wipe(private.characters)
|
||||
for _, character in TSM.Accounting.Money.CharacterIterator(recordType) do
|
||||
tinsert(private.characters, character)
|
||||
private.characterFilter[character] = true
|
||||
end
|
||||
wipe(private.typeFilter)
|
||||
for _, key in ipairs(TYPE_KEYS[recordType]) do
|
||||
private.typeFilter[key] = true
|
||||
end
|
||||
|
||||
if not private.query then
|
||||
private.query = TSM.Accounting.Money.CreateQuery()
|
||||
:OrderBy("time", false)
|
||||
end
|
||||
private.recordType = recordType
|
||||
private.UpdateQuery()
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "row2")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "type")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(TYPE_LIST[recordType], TYPE_KEYS[recordType])
|
||||
:SetSettingInfo(private, "typeFilter")
|
||||
:SetSelectionText(L["No Types"], L["%d Types"], L["All Types"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "character")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.characters, private.characters)
|
||||
:SetSettingInfo(private, "characterFilter")
|
||||
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "time")
|
||||
:SetItems(TIME_LIST, TIME_KEYS)
|
||||
:SetSelectedItemByKey(private.timeFrameFilter)
|
||||
:SetSettingInfo(private, "timeFrameFilter")
|
||||
:SetScript("OnSelectionChanged", private.DropdownChangedCommon)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "table")
|
||||
:SetSettingsContext(private.settings, "ledgerOtherScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("type")
|
||||
:SetTitle(L["Type"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("type", private.TableGetTypeText)
|
||||
:SetSortInfo("type")
|
||||
:Commit()
|
||||
:NewColumn("character")
|
||||
:SetTitle(L["Character"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("player")
|
||||
:SetSortInfo("player")
|
||||
:Commit()
|
||||
:NewColumn("otherCharacter")
|
||||
:SetTitle(L["Other Character"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("otherPlayer")
|
||||
:SetSortInfo("otherPlayer")
|
||||
:Commit()
|
||||
:NewColumn("amount")
|
||||
:SetTitle(L["Amount"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("amount", Money.ToString)
|
||||
:SetSortInfo("amount")
|
||||
:Commit()
|
||||
:NewColumn("time")
|
||||
:SetTitle(L["Time Frame"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("time", private.TableGetTimeText)
|
||||
:SetSortInfo("time")
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(private.query)
|
||||
:SetSelectionDisabled(true)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.TableGetTypeText(typeValue)
|
||||
return TYPE_STR_LOOKUP[typeValue]
|
||||
end
|
||||
|
||||
function private.TableGetTimeText(timevalue)
|
||||
return SecondsToTime(time() - timevalue)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.DropdownChangedCommon(dropdown)
|
||||
private.UpdateQuery()
|
||||
dropdown:GetElement("__parent.__parent.table"):UpdateData(true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateQuery()
|
||||
private.query:ResetFilters()
|
||||
:Equal("recordType", private.recordType)
|
||||
if Table.Count(private.typeFilter) ~= #TYPE_KEYS[private.recordType] then
|
||||
private.query:InTable("type", private.typeFilter)
|
||||
end
|
||||
if Table.Count(private.characterFilter) ~= #private.characters then
|
||||
private.query:InTable("player", private.characterFilter)
|
||||
end
|
||||
if private.timeFrameFilter ~= 0 then
|
||||
private.query:GreaterThan("time", time() - private.timeFrameFilter)
|
||||
end
|
||||
end
|
||||
329
Core/UI/MainUI/Ledger/Common/Transactions.lua
Normal file
329
Core/UI/MainUI/Ledger/Common/Transactions.lua
Normal file
@@ -0,0 +1,329 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Transactions = TSM.MainUI.Ledger.Common:NewPackage("Transactions")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local String = TSM.Include("Util.String")
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local SECONDS_PER_DAY = 24 * 60 * 60
|
||||
local private = {
|
||||
settings = nil,
|
||||
query = nil,
|
||||
characters = {},
|
||||
characterFilter = {},
|
||||
typeFilter = {},
|
||||
searchFilter = "",
|
||||
groupFilter = {},
|
||||
rarityList = {},
|
||||
rarityFilter = {},
|
||||
timeFrameFilter = 30 * SECONDS_PER_DAY,
|
||||
type = nil
|
||||
}
|
||||
local TYPE_LIST = { L["Auction"], COD, TRADE, L["Vendor"] }
|
||||
local TYPE_KEYS = { "Auction", "COD", "Trade", "Vendor" }
|
||||
do
|
||||
for _, key in ipairs(TYPE_KEYS) do
|
||||
private.typeFilter[key] = true
|
||||
end
|
||||
for i = 1, 4 do
|
||||
tinsert(private.rarityList, _G[format("ITEM_QUALITY%d_DESC", i)])
|
||||
private.rarityFilter[i] = true
|
||||
end
|
||||
end
|
||||
local TIME_LIST = { L["All Time"], L["Last 3 Days"], L["Last 7 Days"], L["Last 14 Days"], L["Last 30 Days"], L["Last 60 Days"] }
|
||||
local TIME_KEYS = { 0, 3 * SECONDS_PER_DAY, 7 * SECONDS_PER_DAY, 14 * SECONDS_PER_DAY, 30 * SECONDS_PER_DAY, 60 * SECONDS_PER_DAY }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Transactions.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerTransactionsScrollingTable")
|
||||
TSM.MainUI.Ledger.Expenses.RegisterPage(L["Purchases"], private.DrawPurchasesPage)
|
||||
TSM.MainUI.Ledger.Revenue.RegisterPage(L["Sales"], private.DrawSalesPage)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Transactions UIs
|
||||
-- ============================================================================
|
||||
|
||||
function private.DrawPurchasesPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "expenses", "purchases")
|
||||
private.type = "buy"
|
||||
return private.DrawTransactionPage()
|
||||
end
|
||||
|
||||
function private.DrawSalesPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "revenue", "sales")
|
||||
private.type = "sale"
|
||||
return private.DrawTransactionPage()
|
||||
end
|
||||
|
||||
function private.DrawTransactionPage()
|
||||
private.query = private.query or TSM.Accounting.Transactions.CreateQuery()
|
||||
|
||||
private.query:Reset()
|
||||
:Equal("type", private.type)
|
||||
:Distinct("player")
|
||||
:Select("player")
|
||||
wipe(private.characters)
|
||||
for _, character in private.query:Iterator() do
|
||||
tinsert(private.characters, character)
|
||||
private.characterFilter[character] = true
|
||||
end
|
||||
|
||||
private.query:Reset()
|
||||
:InnerJoin(ItemInfo.GetDBForJoin(), "itemString")
|
||||
:LeftJoin(TSM.Groups.GetItemDBForJoin(), "itemString")
|
||||
:VirtualField("total", "number", private.GetTotal)
|
||||
:VirtualField("auctions", "number", private.GetAuctions)
|
||||
:OrderBy("time", false)
|
||||
private.UpdateQuery()
|
||||
local numItems = private.query:Sum("quantity") or 0
|
||||
local total = private.query:Sum("total") or 0
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "row1")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8)
|
||||
:AddChild(UIElements.New("Input", "filter")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetIconTexture("iconPack.18x18/Search")
|
||||
:SetClearButtonEnabled(true)
|
||||
:AllowItemInsert()
|
||||
:SetHintText(L["Filter by keyword"])
|
||||
:SetValue(private.searchFilter)
|
||||
:SetScript("OnValueChanged", private.SearchFilterChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("GroupSelector", "group")
|
||||
:SetWidth(240)
|
||||
:SetHintText(L["Filter by groups"])
|
||||
:SetScript("OnSelectionChanged", private.GroupFilterChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "row2")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8, 8, 0, 8)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "type")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(TYPE_LIST, TYPE_KEYS)
|
||||
:SetSettingInfo(private, "typeFilter")
|
||||
:SetSelectionText(L["No Types"], L["%d Types"], L["All Types"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "rarity")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.rarityList)
|
||||
:SetSettingInfo(private, "rarityFilter")
|
||||
:SetSelectionText(L["No Rarities"], L["%d Rarities"], L["All Rarities"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "character")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.characters, private.characters)
|
||||
:SetSettingInfo(private, "characterFilter")
|
||||
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "time")
|
||||
:SetItems(TIME_LIST, TIME_KEYS)
|
||||
:SetSelectedItemByKey(private.timeFrameFilter)
|
||||
:SetSettingInfo(private, "timeFrameFilter")
|
||||
:SetScript("OnSelectionChanged", private.DropdownCommonOnSelectionChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "scrollingTable")
|
||||
:SetSettingsContext(private.settings, "ledgerTransactionsScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("item")
|
||||
:SetTitle(L["Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
|
||||
:SetTooltipInfo("itemString")
|
||||
:SetSortInfo("name")
|
||||
:DisableHiding()
|
||||
:Commit()
|
||||
:NewColumn("player")
|
||||
:SetTitle(PLAYER)
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("otherPlayer")
|
||||
:SetSortInfo("otherPlayer")
|
||||
:Commit()
|
||||
:NewColumn("type")
|
||||
:SetTitle(L["Type"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("source")
|
||||
:SetSortInfo("source")
|
||||
:Commit()
|
||||
:NewColumn("stack")
|
||||
:SetTitle(L["Stack"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("stackSize")
|
||||
:SetSortInfo("stackSize")
|
||||
:Commit()
|
||||
:NewColumn("auctions")
|
||||
:SetTitle(L["Auctions"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("auctions")
|
||||
:SetSortInfo("auctions")
|
||||
:Commit()
|
||||
:NewColumn("perItem")
|
||||
:SetTitle(L["Per Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("price", private.TableGetPriceText)
|
||||
:SetSortInfo("price")
|
||||
:Commit()
|
||||
:NewColumn("total")
|
||||
:SetTitle(L["Total"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("total", private.TableGetPriceText)
|
||||
:SetSortInfo("total")
|
||||
:Commit()
|
||||
:NewColumn("time")
|
||||
:SetTitle(L["Time Frame"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("time", private.TableGetTimeframeText)
|
||||
:SetSortInfo("time")
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(private.query)
|
||||
:SetScript("OnRowClick", private.TableSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "footer")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Text", "num")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(format(private.type == "sale" and L["%s Items Sold"] or L["%s Items Bought"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(numItems))))
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetMargin(4, 8, 0, 0)
|
||||
:SetWidth(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "profit")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(format(L["%s Total"], Money.ToString(total)))
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.TableGetPriceText(price)
|
||||
return Money.ToString(price)
|
||||
end
|
||||
|
||||
function private.TableGetTimeframeText(record)
|
||||
return SecondsToTime(time() - record)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.DropdownCommonOnSelectionChanged(dropdown)
|
||||
private.UpdateQuery()
|
||||
local numItems = private.query:Sum("quantity") or 0
|
||||
local total = private.query:Sum("total") or 0
|
||||
dropdown:GetElement("__parent.__parent.scrollingTable")
|
||||
:UpdateData(true)
|
||||
local footer = dropdown:GetElement("__parent.__parent.footer")
|
||||
footer:GetElement("num"):SetText(format(private.type == "sale" and L["%s Items Sold"] or L["%s Items Bought"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(numItems))))
|
||||
footer:GetElement("profit"):SetText(format(L["%s Total"], Money.ToString(total)))
|
||||
footer:Draw()
|
||||
end
|
||||
|
||||
function private.SearchFilterChanged(input)
|
||||
private.searchFilter = input:GetValue()
|
||||
private.DropdownCommonOnSelectionChanged(input)
|
||||
end
|
||||
|
||||
function private.GroupFilterChanged(groupSelector)
|
||||
wipe(private.groupFilter)
|
||||
for groupPath in groupSelector:SelectedGroupIterator() do
|
||||
private.groupFilter[groupPath] = true
|
||||
end
|
||||
private.DropdownCommonOnSelectionChanged(groupSelector)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetTotal(row)
|
||||
return row:GetField("price") * row:GetField("quantity")
|
||||
end
|
||||
|
||||
function private.GetAuctions(row)
|
||||
return row:GetField("quantity") / row:GetField("stackSize")
|
||||
end
|
||||
|
||||
function private.UpdateQuery()
|
||||
private.query:ResetFilters()
|
||||
:Equal("type", private.type)
|
||||
if private.searchFilter ~= "" then
|
||||
private.query:Matches("name", String.Escape(private.searchFilter))
|
||||
end
|
||||
if Table.Count(private.typeFilter) ~= #TYPE_KEYS then
|
||||
private.query:InTable("source", private.typeFilter)
|
||||
end
|
||||
if Table.Count(private.rarityFilter) ~= #private.rarityList then
|
||||
private.query:InTable("quality", private.rarityFilter)
|
||||
end
|
||||
if Table.Count(private.characterFilter) ~= #private.characters then
|
||||
private.query:InTable("player", private.characterFilter)
|
||||
end
|
||||
if private.timeFrameFilter ~= 0 then
|
||||
private.query:GreaterThan("time", time() - private.timeFrameFilter)
|
||||
end
|
||||
if next(private.groupFilter) then
|
||||
private.query:InTable("groupPath", private.groupFilter)
|
||||
end
|
||||
end
|
||||
|
||||
function private.TableSelectionChanged(scrollingTable, row)
|
||||
TSM.MainUI.Ledger.ShowItemDetail(scrollingTable:GetParentElement():GetParentElement(), row:GetField("itemString"), private.type)
|
||||
end
|
||||
524
Core/UI/MainUI/Ledger/Core.lua
Normal file
524
Core/UI/MainUI/Ledger/Core.lua
Normal file
@@ -0,0 +1,524 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Ledger = TSM.MainUI:NewPackage("Ledger")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local TempTable = TSM.Include("Util.TempTable")
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local Log = TSM.Include("Util.Log")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local SECONDS_PER_DAY = 24 * 60 * 60
|
||||
local private = {
|
||||
settings = nil,
|
||||
pages = {},
|
||||
childPages = {},
|
||||
callback = {},
|
||||
contextPath = nil,
|
||||
contextItemString = nil,
|
||||
itemDetailType = "sale",
|
||||
}
|
||||
local NUM_TOP_PLAYERS = 3
|
||||
local PAGE_PATH_SEP = "`"
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Ledger.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerDetailScrollingTable")
|
||||
TSM.MainUI.RegisterTopLevelPage(L["Ledger"], private.GetLedgerFrame)
|
||||
end
|
||||
|
||||
function Ledger.RegisterPage(name, callback)
|
||||
tinsert(private.pages, name)
|
||||
private.callback[name] = callback
|
||||
end
|
||||
|
||||
function Ledger.RegisterChildPage(parentName, childName, callback)
|
||||
local path = parentName..PAGE_PATH_SEP..childName
|
||||
private.childPages[parentName] = private.childPages[parentName] or {}
|
||||
tinsert(private.childPages[parentName], childName)
|
||||
private.callback[path] = callback
|
||||
end
|
||||
|
||||
function Ledger.ShowItemDetail(frame, itemString, detailType)
|
||||
assert(detailType == "sale" or detailType == "buy")
|
||||
private.contextItemString = itemString
|
||||
private.itemDetailType = detailType
|
||||
frame:SetPath("itemDetail", true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Ledger UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetLedgerFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger")
|
||||
local defaultPage = private.pages[1]
|
||||
local frame = UIElements.New("Frame", "ledger")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("Frame", "navigation")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth(160)
|
||||
:SetPadding(12, 12, 1, 9)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "divider")
|
||||
:SetWidth(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "contentFrame")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("ViewContainer", "content")
|
||||
:SetNavCallback(private.ContentNavCallback)
|
||||
:AddPath("itemDetail")
|
||||
)
|
||||
)
|
||||
:SetScript("OnHide", private.NavButtonOnHide)
|
||||
|
||||
local content = frame:GetElement("contentFrame.content")
|
||||
local navFrame = frame:GetElement("navigation")
|
||||
for _, pageName in ipairs(private.pages) do
|
||||
navFrame:AddChild(UIElements.New("Button", pageName)
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(pageName)
|
||||
:SetText(pageName)
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(pageName, pageName == defaultPage)
|
||||
if private.childPages[pageName] then
|
||||
for _, childPageName in ipairs(private.childPages[pageName]) do
|
||||
local path = pageName..PAGE_PATH_SEP..childPageName
|
||||
navFrame:AddChild(UIElements.New("Button", path)
|
||||
:SetHeight(20)
|
||||
:SetMargin(9, 0, 8, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(path)
|
||||
:SetText(childPageName)
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(path, path == defaultPage)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- make all the navigation align to the top
|
||||
navFrame:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
|
||||
private.UpdateNavFrame(navFrame, defaultPage)
|
||||
private.contextPath = L["Inventory"]
|
||||
return frame
|
||||
end
|
||||
|
||||
function private.ContentNavCallback(self, path)
|
||||
if path == "itemDetail" then
|
||||
return private.GetItemDetail()
|
||||
else
|
||||
return private.callback[path]()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.NavButtonOnClick(button)
|
||||
local path = button:GetContext()
|
||||
if private.contextPath == path then
|
||||
return
|
||||
end
|
||||
if private.childPages[path] then
|
||||
-- select the first child
|
||||
path = path..PAGE_PATH_SEP..private.childPages[path][1]
|
||||
end
|
||||
|
||||
local ledgerFrame = button:GetParentElement():GetParentElement()
|
||||
local contentFrame = ledgerFrame:GetElement("contentFrame")
|
||||
local navFrame = ledgerFrame:GetElement("navigation")
|
||||
private.UpdateNavFrame(navFrame, path)
|
||||
navFrame:Draw()
|
||||
contentFrame:GetElement("content"):SetPath(path, private.contextPath ~= path)
|
||||
private.contextPath = path
|
||||
end
|
||||
|
||||
function private.NavButtonOnHide(button)
|
||||
private.contextPath = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateNavFrame(navFrame, selectedPath)
|
||||
local selectedPage = strsplit(PAGE_PATH_SEP, selectedPath)
|
||||
for _, pageName in ipairs(private.pages) do
|
||||
navFrame:GetElement(pageName):SetTextColor(pageName == selectedPage and "TEXT" or "ACTIVE_BG_ALT")
|
||||
if private.childPages[pageName] then
|
||||
for _, childPageName in ipairs(private.childPages[pageName]) do
|
||||
local path = pageName..PAGE_PATH_SEP..childPageName
|
||||
if pageName == selectedPage then
|
||||
navFrame:GetElement(path)
|
||||
:SetTextColor(path == selectedPath and "INDICATOR" or "TEXT")
|
||||
:Show()
|
||||
else
|
||||
navFrame:GetElement(path):Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function private.GetItemDetail()
|
||||
local query = TSM.Accounting.Transactions.CreateQuery()
|
||||
:Equal("itemString", private.contextItemString)
|
||||
:OrderBy("time", false)
|
||||
|
||||
local topPlayersQuantity = TempTable.Acquire()
|
||||
local topPlayers = TempTable.Acquire()
|
||||
for _, row in query:Iterator() do
|
||||
local recordType, otherPlayer, quantity = row:GetFields("type", "otherPlayer", "quantity")
|
||||
if recordType == private.itemDetailType then
|
||||
if not topPlayersQuantity[otherPlayer] then
|
||||
topPlayersQuantity[otherPlayer] = 0
|
||||
tinsert(topPlayers, otherPlayer)
|
||||
end
|
||||
topPlayersQuantity[otherPlayer] = topPlayersQuantity[otherPlayer] + quantity
|
||||
end
|
||||
end
|
||||
|
||||
Table.SortWithValueLookup(topPlayers, topPlayersQuantity, true)
|
||||
local numTopPlayers = min(#topPlayers, NUM_TOP_PLAYERS)
|
||||
local topPlayersText = ""
|
||||
if numTopPlayers > 0 then
|
||||
for i = 1, numTopPlayers do
|
||||
local player = topPlayers[i]
|
||||
local quantity = topPlayersQuantity[player]
|
||||
topPlayers[i] = player..Theme.GetColor("INDICATOR_ALT"):ColorText(" (" .. quantity .. ")")
|
||||
end
|
||||
topPlayersText = table.concat(topPlayers, ", ", 1, numTopPlayers)
|
||||
else
|
||||
topPlayersText = L["None"]
|
||||
end
|
||||
TempTable.Release(topPlayers)
|
||||
TempTable.Release(topPlayersQuantity)
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "top")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("Frame", "header")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("ActionButton", "button")
|
||||
:SetWidth(64)
|
||||
:SetIcon("iconPack.14x14/Chevron/Right@180")
|
||||
:SetText(BACK)
|
||||
:SetScript("OnClick", private.ItemDetailBackButtonOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "icon")
|
||||
:SetSize(24, 24)
|
||||
:SetMargin(14, 8, 0, 0)
|
||||
:SetBackground(ItemInfo.GetTexture(private.contextItemString))
|
||||
:SetTooltip(private.contextItemString)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "itemName")
|
||||
:SetFont("ITEM_BODY1")
|
||||
:SetText(TSM.UI.GetColoredItemName(private.contextItemString))
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetPadding(12, 12, 8, 10)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||||
:SetBorderColor("ACTIVE_BG")
|
||||
:AddChild(UIElements.New("Frame", "heading")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Button", "saleBtn")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetTextColor(private.itemDetailType == "sale" and "INDICATOR" or "ACTIVE_BG_ALT")
|
||||
:SetContext("sale")
|
||||
:SetText(L["Sale Data"])
|
||||
:SetScript("OnClick", private.ItemDetailTabOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "buyBtn")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetTextColor(private.itemDetailType == "buy" and "INDICATOR" or "ACTIVE_BG_ALT")
|
||||
:SetContext("buy")
|
||||
:SetText(L["Purchase Data"])
|
||||
:SetScript("OnClick", private.ItemDetailTabOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "total")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(L["Total"])
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last7")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(L["Last 7 Days"])
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last30")
|
||||
:SetWidth(120)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(L["Last 30 Days"])
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "quantity")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(private.itemDetailType == "sale" and L["Quantity Sold:"] or L["Quantity Purchased:"])
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "total")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(TSM.Accounting.Transactions.GetQuantity(private.contextItemString, nil, private.itemDetailType))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last7")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(TSM.Accounting.Transactions.GetQuantity(private.contextItemString, SECONDS_PER_DAY * 7, private.itemDetailType))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last30")
|
||||
:SetWidth(120)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(TSM.Accounting.Transactions.GetQuantity(private.contextItemString, SECONDS_PER_DAY * 30, private.itemDetailType))
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "avgPrice")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(L["Average Prices:"])
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "total")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetAveragePrice(private.contextItemString, nil, private.itemDetailType)))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last7")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetAveragePrice(private.contextItemString, SECONDS_PER_DAY * 7, private.itemDetailType)))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last30")
|
||||
:SetWidth(120)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetAveragePrice(private.contextItemString, SECONDS_PER_DAY * 30, private.itemDetailType)))
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "totalPrice")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(L["Total Prices:"])
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "total")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetTotalPrice(private.contextItemString, nil, private.itemDetailType)))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last7")
|
||||
:SetWidth(120)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetTotalPrice(private.contextItemString, SECONDS_PER_DAY * 7, private.itemDetailType)))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "last30")
|
||||
:SetWidth(120)
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(Money.ToString(TSM.Accounting.Transactions.GetTotalPrice(private.contextItemString, SECONDS_PER_DAY * 30, private.itemDetailType)))
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "top")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(private.itemDetailType == "sale" and L["Top Buyers"]..":" or L["Top Sellers"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(topPlayersText)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "scrollingTable")
|
||||
:SetSettingsContext(private.settings, "ledgerDetailScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("activityType")
|
||||
:SetTitle(L["Activity Type"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("type", private.TableGetActivityTypeText)
|
||||
:Commit()
|
||||
:NewColumn("source")
|
||||
:SetTitle(L["Source"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("source")
|
||||
:Commit()
|
||||
:NewColumn("buyerSeller")
|
||||
:SetTitle(L["Buyer/Seller"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("otherPlayer")
|
||||
:Commit()
|
||||
:NewColumn("qty")
|
||||
:SetTitle(L["Qty"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("quantity")
|
||||
:Commit()
|
||||
:NewColumn("perItem")
|
||||
:SetTitle(L["Per Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo(nil, private.TableGetPerItemText)
|
||||
:Commit()
|
||||
:NewColumn("totalPrice")
|
||||
:SetTitle(L["Total Price"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo(nil, private.TableGetTotalPriceText)
|
||||
:Commit()
|
||||
:NewColumn("time")
|
||||
:SetTitle(L["Time"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("time", private.TableGetTimeframeText)
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(query)
|
||||
:SetAutoReleaseQuery(true)
|
||||
:SetSelectionDisabled(true)
|
||||
:SetScript("OnRowClick", private.ItemDetailScrollingTableOnRowClick)
|
||||
)
|
||||
end
|
||||
|
||||
function private.ItemDetailBackButtonOnClick(button)
|
||||
button:GetParentElement():GetParentElement():GetParentElement():GetParentElement():SetPath(private.contextPath, true)
|
||||
end
|
||||
|
||||
function private.ItemDetailTabOnClick(button)
|
||||
private.itemDetailType = button:GetContext()
|
||||
button:GetParentElement():GetParentElement():GetParentElement():GetParentElement():GetParentElement():ReloadContent()
|
||||
end
|
||||
|
||||
function private.ItemDetailScrollingTableOnRowClick(scrollingTable, row, button)
|
||||
if button ~= "RightButton" then
|
||||
return
|
||||
elseif not TSM.Accounting.Transactions.CanDeleteByUUID(row:GetUUID()) then
|
||||
Log.PrintUser(L["This record belongs to another account and can only be deleted on that account."])
|
||||
return
|
||||
end
|
||||
local subtitle = nil
|
||||
local recordType, itemString, quantity, otherPlayer, price = row:GetFields("type", "itemString", "quantity", "otherPlayer", "price")
|
||||
local name = TSM.UI.GetColoredItemName(itemString) or "?"
|
||||
local amount = Money.ToString(price * quantity)
|
||||
if recordType == "sale" then
|
||||
subtitle = format(L["Sold %d of %s to %s for %s"], quantity, name, otherPlayer, amount)
|
||||
elseif recordType == "buy" then
|
||||
subtitle = format(L["Bought %d of %s from %s for %s"], quantity, name, otherPlayer, amount)
|
||||
else
|
||||
error("Unexpected Type: "..tostring(recordType))
|
||||
end
|
||||
scrollingTable:GetBaseElement():ShowConfirmationDialog(L["Delete Record?"], subtitle, private.DeleteRecordConfirmed, row:GetUUID())
|
||||
end
|
||||
|
||||
function private.DeleteRecordConfirmed(uuid)
|
||||
TSM.Accounting.Transactions.RemoveRowByUUID(uuid)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.TableGetActivityTypeText(recordType)
|
||||
if recordType == "sale" then
|
||||
return L["Sale"]
|
||||
elseif recordType == "buy" then
|
||||
return L["Buy"]
|
||||
else
|
||||
error("Unexpected Type: "..tostring(recordType))
|
||||
end
|
||||
end
|
||||
|
||||
function private.TableGetTimeframeText(timestamp)
|
||||
return SecondsToTime(time() - timestamp)
|
||||
end
|
||||
|
||||
function private.TableGetTotalPriceText(row)
|
||||
return Money.ToString(row:GetField("price") * row:GetField("quantity"))
|
||||
end
|
||||
|
||||
function private.TableGetPerItemText(row)
|
||||
return Money.ToString(row:GetField("price"))
|
||||
end
|
||||
23
Core/UI/MainUI/Ledger/Expenses/Core.lua
Normal file
23
Core/UI/MainUI/Ledger/Expenses/Core.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Expenses = TSM.MainUI.Ledger:NewPackage("Expenses")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Expenses.OnInitialize()
|
||||
TSM.MainUI.Ledger.RegisterPage(L["Expenses"])
|
||||
end
|
||||
|
||||
function Expenses.RegisterPage(name, callback)
|
||||
TSM.MainUI.Ledger.RegisterChildPage(L["Expenses"], name, callback)
|
||||
end
|
||||
23
Core/UI/MainUI/Ledger/FailedAuctions/Core.lua
Normal file
23
Core/UI/MainUI/Ledger/FailedAuctions/Core.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local FailedAuctions = TSM.MainUI.Ledger:NewPackage("FailedAuctions")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function FailedAuctions.OnInitialize()
|
||||
TSM.MainUI.Ledger.RegisterPage(L["Failed Auctions"])
|
||||
end
|
||||
|
||||
function FailedAuctions.RegisterPage(name, callback)
|
||||
TSM.MainUI.Ledger.RegisterChildPage(L["Failed Auctions"], name, callback)
|
||||
end
|
||||
329
Core/UI/MainUI/Ledger/Inventory.lua
Normal file
329
Core/UI/MainUI/Ledger/Inventory.lua
Normal file
@@ -0,0 +1,329 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Inventory = TSM.MainUI.Ledger:NewPackage("Inventory")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local TempTable = TSM.Include("Util.TempTable")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local String = TSM.Include("Util.String")
|
||||
local Math = TSM.Include("Util.Math")
|
||||
local Database = TSM.Include("Util.Database")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local CustomPrice = TSM.Include("Service.CustomPrice")
|
||||
local BagTracking = TSM.Include("Service.BagTracking")
|
||||
local GuildTracking = TSM.Include("Service.GuildTracking")
|
||||
local AuctionTracking = TSM.Include("Service.AuctionTracking")
|
||||
local MailTracking = TSM.Include("Service.MailTracking")
|
||||
local AltTracking = TSM.Include("Service.AltTracking")
|
||||
local InventoryService = TSM.Include("Service.Inventory")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settings = nil,
|
||||
db = nil,
|
||||
query = nil,
|
||||
searchFilter = "",
|
||||
groupFilter = {},
|
||||
valuePriceSource = "dbmarket", -- luacheck: ignore 1005 - hidden modify via SetSettingInfo()
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Inventory.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerInventoryScrollingTable")
|
||||
TSM.MainUI.Ledger.RegisterPage(L["Inventory"], private.DrawInventoryPage)
|
||||
end
|
||||
|
||||
function Inventory.OnEnable()
|
||||
private.db = Database.NewSchema("LEDGER_INVENTORY")
|
||||
:AddUniqueStringField("itemString")
|
||||
:Commit()
|
||||
private.query = private.db:NewQuery()
|
||||
:VirtualField("bagQuantity", "number", BagTracking.GetBagsQuantityByBaseItemString, "itemString")
|
||||
:VirtualField("guildQuantity", "number", private.GuildQuantityVirtualField, "itemString")
|
||||
:VirtualField("auctionQuantity", "number", AuctionTracking.GetQuantityByBaseItemString, "itemString")
|
||||
:VirtualField("mailQuantity", "number", MailTracking.GetQuantityByBaseItemString, "itemString")
|
||||
:VirtualField("altQuantity", "number", AltTracking.GetQuantityByBaseItemString, "itemString")
|
||||
:VirtualField("totalQuantity", "number", private.TotalQuantityVirtualField)
|
||||
:VirtualField("totalValue", "number", private.TotalValueVirtualField)
|
||||
:VirtualField("totalBankQuantity", "number", private.GetTotalBankQuantity)
|
||||
:InnerJoin(ItemInfo.GetDBForJoin(), "itemString")
|
||||
:LeftJoin(TSM.Groups.GetItemDBForJoin(), "itemString")
|
||||
:OrderBy("name", true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Inventory UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.DrawInventoryPage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "inventory")
|
||||
local items = TempTable.Acquire()
|
||||
for _, itemString in BagTracking.BaseItemIterator() do
|
||||
items[itemString] = true
|
||||
end
|
||||
for _, itemString in GuildTracking.BaseItemIterator() do
|
||||
items[itemString] = true
|
||||
end
|
||||
for _, itemString in AuctionTracking.BaseItemIterator() do
|
||||
items[itemString] = true
|
||||
end
|
||||
for _, itemString in MailTracking.BaseItemIterator() do
|
||||
items[itemString] = true
|
||||
end
|
||||
for _, itemString in AltTracking.BaseItemIterator() do
|
||||
items[itemString] = true
|
||||
end
|
||||
private.db:TruncateAndBulkInsertStart()
|
||||
for itemString in pairs(items) do
|
||||
private.db:BulkInsertNewRow(itemString)
|
||||
end
|
||||
private.db:BulkInsertEnd()
|
||||
TempTable.Release(items)
|
||||
private.UpdateQuery()
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "row1")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8)
|
||||
:AddChild(UIElements.New("Input", "filter")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetIconTexture("iconPack.18x18/Search")
|
||||
:SetClearButtonEnabled(true)
|
||||
:AllowItemInsert()
|
||||
:SetHintText(L["Filter by keyword"])
|
||||
:SetValue(private.searchFilter)
|
||||
:SetScript("OnValueChanged", private.SearchFilterChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("GroupSelector", "group")
|
||||
:SetWidth(240)
|
||||
:SetHintText(L["Filter by groups"])
|
||||
:SetScript("OnSelectionChanged", private.GroupFilterChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "row2")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8, 8, 0, 8)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(L["Value Price Source"])
|
||||
)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(4, 8, 0, 0)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:SetBorderColor("ACTIVE_BG")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(private, "valuePriceSource")
|
||||
:SetScript("OnValueChanged", private.FilterChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "value")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetWidth(240)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetMargin(0, 4, 0, 0)
|
||||
:SetText(L["Total Value"]..":")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetText(Money.ToString(private.GetTotalValue()))
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "accountingScrollingTableFrame")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "scrollingTable")
|
||||
:SetSettingsContext(private.settings, "ledgerInventoryScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("item")
|
||||
:SetTitle(L["Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
|
||||
:SetTooltipInfo("itemString")
|
||||
:SetSortInfo("name")
|
||||
:DisableHiding()
|
||||
:Commit()
|
||||
:NewColumn("totalItems")
|
||||
:SetTitle(L["Total"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("totalQuantity")
|
||||
:SetSortInfo("totalQuantity")
|
||||
:Commit()
|
||||
:NewColumn("bags")
|
||||
:SetTitle(L["Bags"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("bagQuantity")
|
||||
:SetSortInfo("bagQuantity")
|
||||
:Commit()
|
||||
:NewColumn("banks")
|
||||
:SetTitle(L["Banks"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("totalBankQuantity")
|
||||
:SetSortInfo("totalBankQuantity")
|
||||
:Commit()
|
||||
:NewColumn("mail")
|
||||
:SetTitle(L["Mail"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("mailQuantity")
|
||||
:SetSortInfo("mailQuantity")
|
||||
:Commit()
|
||||
:NewColumn("alts")
|
||||
:SetTitle(L["Alts"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("altQuantity")
|
||||
:SetSortInfo("altQuantity")
|
||||
:Commit()
|
||||
:NewColumn("guildVault")
|
||||
:SetTitle(L["GVault"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("guildQuantity")
|
||||
:SetSortInfo("guildQuantity")
|
||||
:Commit()
|
||||
:NewColumn("auctionHouse")
|
||||
:SetTitle(L["AH"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("auctionQuantity")
|
||||
:SetSortInfo("auctionQuantity")
|
||||
:Commit()
|
||||
:NewColumn("totalValue")
|
||||
:SetTitle(L["Value"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("totalValue", private.TableGetTotalValueText)
|
||||
:SetSortInfo("totalValue")
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetSelectionDisabled(true)
|
||||
:SetQuery(private.query)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.FilterChangedCommon(element)
|
||||
private.UpdateQuery()
|
||||
element:GetElement("__parent.__parent.accountingScrollingTableFrame.scrollingTable")
|
||||
:SetQuery(private.query, true)
|
||||
element:GetElement("__parent.__parent.row2.value.value")
|
||||
:SetText(Money.ToString(private.GetTotalValue()))
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function private.SearchFilterChanged(input)
|
||||
private.searchFilter = input:GetValue()
|
||||
private.FilterChangedCommon(input)
|
||||
end
|
||||
|
||||
function private.GroupFilterChanged(groupSelector)
|
||||
wipe(private.groupFilter)
|
||||
for groupPath in groupSelector:SelectedGroupIterator() do
|
||||
private.groupFilter[groupPath] = true
|
||||
end
|
||||
private.FilterChangedCommon(groupSelector)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.TableGetTotalValueText(totalValue)
|
||||
return Math.IsNan(totalValue) and "" or Money.ToString(totalValue)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.GuildQuantityVirtualField(itemString)
|
||||
local totalNum = 0
|
||||
for guildName in pairs(TSM.db.factionrealm.internalData.guildVaults) do
|
||||
local guildQuantity = InventoryService.GetGuildQuantity(itemString, guildName)
|
||||
totalNum = totalNum + guildQuantity
|
||||
end
|
||||
return totalNum
|
||||
end
|
||||
|
||||
function private.TotalQuantityVirtualField(row)
|
||||
local bagQuantity, totalBankQuantity, guildQuantity, auctionQuantity, mailQuantity, altQuantity = row:GetFields("bagQuantity", "totalBankQuantity", "guildQuantity", "auctionQuantity", "mailQuantity", "altQuantity")
|
||||
return bagQuantity + totalBankQuantity + guildQuantity + auctionQuantity + mailQuantity + altQuantity
|
||||
end
|
||||
|
||||
function private.TotalValueVirtualField(row)
|
||||
local itemString, totalQuantity = row:GetFields("itemString", "totalQuantity")
|
||||
local price = CustomPrice.GetValue(private.valuePriceSource, itemString)
|
||||
if not price then
|
||||
return Math.GetNan()
|
||||
end
|
||||
return price * totalQuantity
|
||||
end
|
||||
|
||||
function private.GetTotalBankQuantity(row)
|
||||
local itemString = row:GetField("itemString")
|
||||
local bankQuantity = BagTracking.GetBankQuantityByBaseItemString(itemString)
|
||||
local reagentBankQuantity = BagTracking.GetReagentBankQuantityByBaseItemString(itemString)
|
||||
return bankQuantity + reagentBankQuantity
|
||||
end
|
||||
|
||||
function private.GetTotalValue()
|
||||
-- can't lookup the value of items while the query is iteratoring, so grab the list of items first
|
||||
local itemQuantities = TempTable.Acquire()
|
||||
for _, row in private.query:Iterator() do
|
||||
local itemString, total = row:GetFields("itemString", "totalQuantity")
|
||||
itemQuantities[itemString] = total
|
||||
end
|
||||
local totalValue = 0
|
||||
for itemString, total in pairs(itemQuantities) do
|
||||
local price = CustomPrice.GetValue(private.valuePriceSource, itemString)
|
||||
if price then
|
||||
totalValue = totalValue + price * total
|
||||
end
|
||||
end
|
||||
TempTable.Release(itemQuantities)
|
||||
return totalValue
|
||||
end
|
||||
|
||||
function private.UpdateQuery()
|
||||
private.query:ResetFilters()
|
||||
if private.searchFilter ~= "" then
|
||||
private.query:Matches("name", String.Escape(private.searchFilter))
|
||||
end
|
||||
if next(private.groupFilter) then
|
||||
private.query:InTable("groupPath", private.groupFilter)
|
||||
end
|
||||
end
|
||||
23
Core/UI/MainUI/Ledger/Revenue/Core.lua
Normal file
23
Core/UI/MainUI/Ledger/Revenue/Core.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Revenue = TSM.MainUI.Ledger:NewPackage("Revenue")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Revenue.OnInitialize()
|
||||
TSM.MainUI.Ledger.RegisterPage(L["Revenue"])
|
||||
end
|
||||
|
||||
function Revenue.RegisterPage(name, callback)
|
||||
TSM.MainUI.Ledger.RegisterChildPage(L["Revenue"], name, callback)
|
||||
end
|
||||
299
Core/UI/MainUI/Ledger/Revenue/Resale.lua
Normal file
299
Core/UI/MainUI/Ledger/Revenue/Resale.lua
Normal file
@@ -0,0 +1,299 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Resale = TSM.MainUI.Ledger.Revenue:NewPackage("Resale")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local ItemInfo = TSM.Include("Service.ItemInfo")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local SECONDS_PER_DAY = 24 * 60 * 60
|
||||
local private = {
|
||||
settings = nil,
|
||||
summaryQuery = nil,
|
||||
characters = {},
|
||||
characterFilter = {},
|
||||
typeFilter = {},
|
||||
rarityList = {},
|
||||
rarityFilter = {},
|
||||
groupFilter = {},
|
||||
searchFilter = "",
|
||||
timeFrameFilter = 30 * SECONDS_PER_DAY
|
||||
}
|
||||
local TYPE_LIST = { L["Auction"], COD, TRADE, L["Vendor"] }
|
||||
local TYPE_KEYS = { "Auction", "COD", "Trade", "Vendor" }
|
||||
do
|
||||
for _, key in ipairs(TYPE_KEYS) do
|
||||
private.typeFilter[key] = true
|
||||
end
|
||||
for i = 1, 4 do
|
||||
tinsert(private.rarityList, _G[format("ITEM_QUALITY%d_DESC", i)])
|
||||
private.rarityFilter[i] = true
|
||||
end
|
||||
end
|
||||
local TIME_LIST = { L["All Time"], L["Last 3 Days"], L["Last 7 Days"], L["Last 14 Days"], L["Last 30 Days"], L["Last 60 Days"] }
|
||||
local TIME_KEYS = { 0, 3 * SECONDS_PER_DAY, 7 * SECONDS_PER_DAY, 14 * SECONDS_PER_DAY, 30 * SECONDS_PER_DAY, 60 * SECONDS_PER_DAY }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Resale.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "ledgerResaleScrollingTable")
|
||||
TSM.MainUI.Ledger.Revenue.RegisterPage(L["Resale"], private.DrawResalePage)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Resale UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.DrawResalePage()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "ledger", "revenue", "resale")
|
||||
wipe(private.characters)
|
||||
TSM.Accounting.Transactions.GetCharacters(private.characters)
|
||||
for _, character in ipairs(private.characters) do
|
||||
private.characterFilter[character] = true
|
||||
end
|
||||
|
||||
private.summaryQuery = private.summaryQuery or TSM.Accounting.Transactions.CreateSummaryQuery()
|
||||
:InnerJoin(ItemInfo.GetDBForJoin(), "itemString")
|
||||
:OrderBy("name", true)
|
||||
private.UpdateQuery()
|
||||
local totalProfit = 0
|
||||
local numItems = 0
|
||||
for _, row in private.summaryQuery:Iterator() do
|
||||
totalProfit = totalProfit + row:GetField("totalProfit")
|
||||
numItems = numItems + min(row:GetFields("sold", "bought"))
|
||||
end
|
||||
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Frame", "row1")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8)
|
||||
:AddChild(UIElements.New("Input", "filter")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetIconTexture("iconPack.18x18/Search")
|
||||
:SetClearButtonEnabled(true)
|
||||
:AllowItemInsert()
|
||||
:SetHintText(L["Filter by keyword"])
|
||||
:SetValue(private.searchFilter)
|
||||
:SetScript("OnValueChanged", private.SearchFilterChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("GroupSelector", "group")
|
||||
:SetWidth(240)
|
||||
:SetHintText(L["Filter by groups"])
|
||||
:SetScript("OnSelectionChanged", private.GroupFilterChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "row2")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8, 8, 0, 8)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "type")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(TYPE_LIST, TYPE_KEYS)
|
||||
:SetSettingInfo(private, "typeFilter")
|
||||
:SetSelectionText(L["No Types"], L["%d Types"], L["All Types"])
|
||||
:SetScript("OnSelectionChanged", private.FilterChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "rarity")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.rarityList)
|
||||
:SetSettingInfo(private, "rarityFilter")
|
||||
:SetSelectionText(L["No Rarities"], L["%d Rarities"], L["All Rarities"])
|
||||
:SetScript("OnSelectionChanged", private.FilterChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "character")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetItems(private.characters, private.characters)
|
||||
:SetSettingInfo(private, "characterFilter")
|
||||
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
|
||||
:SetScript("OnSelectionChanged", private.FilterChangedCommon)
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "time")
|
||||
:SetItems(TIME_LIST, TIME_KEYS)
|
||||
:SetSelectedItemByKey(private.timeFrameFilter)
|
||||
:SetSettingInfo(private, "timeFrameFilter")
|
||||
:SetScript("OnSelectionChanged", private.FilterChangedCommon)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("QueryScrollingTable", "scrollingTable")
|
||||
:SetSettingsContext(private.settings, "ledgerResaleScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("item")
|
||||
:SetTitle(L["Item"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("itemString", TSM.UI.GetColoredItemName)
|
||||
:SetSortInfo("name")
|
||||
:SetTooltipInfo("itemString")
|
||||
:DisableHiding()
|
||||
:Commit()
|
||||
:NewColumn("bought")
|
||||
:SetTitle(L["Bought"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("bought")
|
||||
:SetSortInfo("bought")
|
||||
:Commit()
|
||||
:NewColumn("avgBuyPrice")
|
||||
:SetTitle(L["Avg Buy Price"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("avgBuyPrice", private.GetMoneyText)
|
||||
:SetSortInfo("avgBuyPrice")
|
||||
:Commit()
|
||||
:NewColumn("sold")
|
||||
:SetTitle(L["Sold"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("sold")
|
||||
:SetSortInfo("sold")
|
||||
:Commit()
|
||||
:NewColumn("avgSellPrice")
|
||||
:SetTitle(L["Avg Sell Price"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("avgSellPrice", private.GetMoneyText)
|
||||
:SetSortInfo("avgSellPrice")
|
||||
:Commit()
|
||||
:NewColumn("avgProfit")
|
||||
:SetTitle(L["Avg Profit"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("avgProfit", private.GetColoredMoneyText)
|
||||
:SetSortInfo("avgProfit")
|
||||
:Commit()
|
||||
:NewColumn("totalProfit")
|
||||
:SetTitle(L["Total Profit"])
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("totalProfit", private.GetColoredMoneyText)
|
||||
:SetSortInfo("totalProfit")
|
||||
:Commit()
|
||||
:NewColumn("profitPct")
|
||||
:SetTitle("%")
|
||||
:SetFont("ITEM_BODY3")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetTextInfo("profitPct", private.GetPctText)
|
||||
:SetSortInfo("profitPct")
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(private.summaryQuery)
|
||||
:SetScript("OnRowClick", private.TableSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "footer")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Text", "num")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(format(L["%s Items Resold"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(numItems))))
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetMargin(4, 8, 0, 0)
|
||||
:SetWidth(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "profit")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(format(L["%s Total Profit"], Money.ToString(totalProfit)))
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Scrolling Table Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetMoneyText(value)
|
||||
return Money.ToString(value)
|
||||
end
|
||||
|
||||
function private.GetColoredMoneyText(value)
|
||||
return Money.ToString(value, Theme.GetFeedbackColor(value >= 0 and "GREEN" or "RED"):GetTextColorPrefix())
|
||||
end
|
||||
|
||||
function private.GetPctText(value)
|
||||
return Theme.GetFeedbackColor(value >= 0 and "GREEN" or "RED"):ColorText(value.."%")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.FilterChangedCommon(dropdown)
|
||||
private.UpdateQuery()
|
||||
local totalProfit = 0
|
||||
local numItems = 0
|
||||
for _, row in private.summaryQuery:Iterator() do
|
||||
totalProfit = totalProfit + row:GetField("totalProfit")
|
||||
numItems = numItems + min(row:GetFields("sold", "bought"))
|
||||
end
|
||||
dropdown:GetElement("__parent.__parent.scrollingTable"):UpdateData(true)
|
||||
local footer = dropdown:GetElement("__parent.__parent.footer")
|
||||
footer:GetElement("num"):SetText(format(L["%s Items Resold"], Theme.GetColor("INDICATOR"):ColorText(FormatLargeNumber(numItems))))
|
||||
footer:GetElement("profit"):SetText(format(L["%s Total Profit"], Money.ToString(totalProfit)))
|
||||
footer:Draw()
|
||||
end
|
||||
|
||||
function private.SearchFilterChanged(input)
|
||||
private.searchFilter = input:GetValue()
|
||||
private.FilterChangedCommon(input)
|
||||
end
|
||||
|
||||
function private.GroupFilterChanged(groupSelector)
|
||||
wipe(private.groupFilter)
|
||||
for groupPath in groupSelector:SelectedGroupIterator() do
|
||||
private.groupFilter[groupPath] = true
|
||||
end
|
||||
private.FilterChangedCommon(groupSelector)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateQuery()
|
||||
private.summaryQuery:ResetFilters()
|
||||
local groupFilter = next(private.groupFilter) and private.groupFilter or nil
|
||||
local searchFilter = private.searchFilter ~= "" and private.searchFilter or nil
|
||||
local typeFilter = Table.Count(private.typeFilter) ~= #TYPE_KEYS and private.typeFilter or nil
|
||||
local characterFilter = Table.Count(private.characterFilter) ~= #private.characters and private.characterFilter or nil
|
||||
local minTime = private.timeFrameFilter ~= 0 and (time() - private.timeFrameFilter) or nil
|
||||
TSM.Accounting.Transactions.UpdateSummaryData(groupFilter, searchFilter, typeFilter, characterFilter, minTime)
|
||||
if Table.Count(private.rarityFilter) ~= #private.rarityList then
|
||||
private.summaryQuery:InTable("quality", private.rarityFilter)
|
||||
end
|
||||
end
|
||||
|
||||
function private.TableSelectionChanged(scrollingTable, row)
|
||||
TSM.MainUI.Ledger.ShowItemDetail(scrollingTable:GetParentElement():GetParentElement(), row:GetField("itemString"), "sale")
|
||||
end
|
||||
360
Core/UI/MainUI/Operations/Auctioning.lua
Normal file
360
Core/UI/MainUI/Operations/Auctioning.lua
Normal file
@@ -0,0 +1,360 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Auctioning = TSM.MainUI.Operations:NewPackage("Auctioning")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local String = TSM.Include("Util.String")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local Vararg = TSM.Include("Util.Vararg")
|
||||
local CustomPrice = TSM.Include("Service.CustomPrice")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
currentTab = nil,
|
||||
}
|
||||
local IGNORE_DURATION_OPTIONS = {
|
||||
L["None"],
|
||||
AUCTION_TIME_LEFT1.." ("..AUCTION_TIME_LEFT1_DETAIL..")",
|
||||
AUCTION_TIME_LEFT2.." ("..AUCTION_TIME_LEFT2_DETAIL..")",
|
||||
AUCTION_TIME_LEFT3.." ("..AUCTION_TIME_LEFT3_DETAIL..")",
|
||||
}
|
||||
local BELOW_MIN_ITEMS = { L["Don't Post Items"], L["Post at Minimum Price"], L["Post at Maximum Price"], L["Post at Normal Price"], L["Ignore Auctions Below Min"] }
|
||||
local BELOW_MIN_KEYS = { "none", "minPrice", "maxPrice", "normalPrice", "ignore" }
|
||||
local ABOVE_MAX_ITEMS = { L["Don't Post Items"], L["Post at Minimum Price"], L["Post at Maximum Price"], L["Post at Normal Price"] }
|
||||
local ABOVE_MAX_KEYS = { "none", "minPrice", "maxPrice", "normalPrice" }
|
||||
local BAD_PRICE_SOURCES = { auctioningopmin = true, auctioningopmax = true, auctioningopnormal = true }
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Auctioning.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Auctioning", private.GetAuctioningOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Auctioning Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetAuctioningOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "auctioning")
|
||||
private.currentOperationName = operationName
|
||||
private.currentTab = private.currentTab or L["Details"]
|
||||
return UIElements.New("TabGroup", "tabs")
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetNavCallback(private.GetAuctioningSettings)
|
||||
:AddPath(L["Details"])
|
||||
:AddPath(L["Posting"])
|
||||
:AddPath(L["Canceling"])
|
||||
:SetPath(private.currentTab)
|
||||
end
|
||||
|
||||
function private.GetDetailsSettings()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "auctioning", "details")
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Auctioning", "generalOptions", L["General Options"], L["Adjust some general settings."])
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChildrenWithFunction(private.AddMaxStackSizeSetting)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("ignoreLowDuration", L["Ignore auctions by duration"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 16)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "ignoreLowDuration"))
|
||||
:SetItems(IGNORE_DURATION_OPTIONS)
|
||||
:SetSelectedItemByKey(operation.ignoreLowDuration + 1, true)
|
||||
:SetScript("OnSelectionChanged", private.IgnoreLowDurationOnSelectionChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("blacklist", L["Blacklisted players"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetHintText(L["Enter player name"])
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "blacklist"))
|
||||
:SetScript("OnEnterPressed", private.BlacklistInputOnEnterPressed)
|
||||
)
|
||||
)
|
||||
:AddChildrenWithFunction(private.AddBlacklistPlayers)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Auctioning", private.currentOperationName))
|
||||
end
|
||||
|
||||
function private.AddMaxStackSizeSetting(frame)
|
||||
if TSM.IsWowClassic() then
|
||||
frame:AddChild(private.CreateToggleLine("matchStackSize", L["Match stack size"]))
|
||||
end
|
||||
end
|
||||
|
||||
function private.GetPostingSettings()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "auctioning", "posting")
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Auctioning", "postingSettings", L["Posting Options"], L["Adjust the settings below to set how groups attached to this operation will be auctioned."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("duration", L["Auction duration"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "duration"))
|
||||
:SetItems(TSM.CONST.AUCTION_DURATIONS)
|
||||
:SetSelectedItemByKey(operation.duration)
|
||||
:SetScript("OnSelectionChanged", private.SetAuctioningDuration)
|
||||
)
|
||||
|
||||
)
|
||||
:AddChild(private.CreateInputLine("postCap", L["Post cap"], false, true))
|
||||
:AddChildrenWithFunction(private.AddStackSizeSettings)
|
||||
:AddChild(private.CreateInputLine("keepQuantity", L["Amount kept in bags"], false, true))
|
||||
:AddChild(private.CreateInputLine("maxExpires", L["Don't post after this many expires"]))
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Auctioning", "priceSettings", L["Posting Price"], L["Adjust the settings below to set how groups attached to this operation will be priced."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("bidPercent", L["Set bid as percentage of buyout"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc(private.BidPercentValidateFunc)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "bidPercent"))
|
||||
:SetValue((operation.bidPercent * 100).."%")
|
||||
:SetScript("OnValueChanged", private.BidPercentOnValueChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetFormattedText(L["Enter a value from %d - %d%%"], 0, 100)
|
||||
:SetTextColor(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "bidPercent") and "TEXT_DISABLED" or "TEXT")
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("undercut", L["Undercut amount"], 66, private.CheckUndercut)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("minPrice", L["Minimum price"], 126, BAD_PRICE_SOURCES))
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("priceReset", L["When below minimum:"])
|
||||
:SetMargin(0, 0, 12, 12)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
|
||||
:SetWidth(240)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "priceReset"))
|
||||
:SetItems(BELOW_MIN_ITEMS, BELOW_MIN_KEYS)
|
||||
:SetSettingInfo(operation, "priceReset")
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("maxPrice", L["Maximum price"], 126, BAD_PRICE_SOURCES))
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("aboveMax", L["When above maximum:"])
|
||||
:SetMargin(0, 0, 12, 12)
|
||||
:AddChild(UIElements.New("SelectionDropdown", "dropdown")
|
||||
:SetWidth(240)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, "aboveMax"))
|
||||
:SetItems(ABOVE_MAX_ITEMS, ABOVE_MAX_KEYS)
|
||||
:SetSettingInfo(operation, "aboveMax")
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("normalPrice", L["Normal price"], 126, BAD_PRICE_SOURCES))
|
||||
)
|
||||
end
|
||||
|
||||
function private.AddStackSizeSettings(frame)
|
||||
if not TSM.IsWowClassic() then
|
||||
return
|
||||
end
|
||||
frame:AddChild(private.CreateInputLine("stackSize", L["Stack size"], false, true))
|
||||
frame:AddChild(private.CreateToggleLine("stackSizeIsCap", L["Allow partial stack"]))
|
||||
end
|
||||
|
||||
function private.GetCancelingSettings()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "auctioning", "canceling")
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Auctioning", "priceSettings", L["Canceling Options"], L["Adjust the settings below to set how groups attached to this operation will be cancelled."])
|
||||
:AddChild(private.CreateToggleLine("cancelUndercut", L["Cancel undercut auctions"]))
|
||||
:AddChild(private.CreateToggleLine("cancelRepost", L["Cancel to repost higher"]))
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("cancelRepostThreshold", L["Repost threshold"], 66))
|
||||
)
|
||||
end
|
||||
|
||||
function private.GetAuctioningSettings(self, button)
|
||||
private.currentTab = button
|
||||
if button == L["Details"] then
|
||||
return private.GetDetailsSettings()
|
||||
elseif button == L["Posting"] then
|
||||
return private.GetPostingSettings()
|
||||
elseif button == L["Canceling"] then
|
||||
return private.GetCancelingSettings()
|
||||
else
|
||||
error("Unknown button!")
|
||||
end
|
||||
end
|
||||
|
||||
function private.AddBlacklistPlayers(frame)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
if operation.blacklist == "" then return end
|
||||
local containerFrame = UIElements.New("Frame", "blacklistFrame")
|
||||
:SetLayout("FLOW")
|
||||
for index, player in Vararg.Iterator(strsplit(",", operation.blacklist)) do
|
||||
containerFrame:AddChild(UIElements.New("Frame", "blacklist" .. index)
|
||||
: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.RemoveBlacklistOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
end
|
||||
frame:AddChild(containerFrame)
|
||||
end
|
||||
|
||||
function private.CreateInputLine(key, label, disabled, margin)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
local hasRelationship = TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, key)
|
||||
return TSM.MainUI.Operations.CreateLinkedSettingLine(key, label, disabled)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, margin and 12 or 4)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetContext(key)
|
||||
:SetDisabled(hasRelationship or disabled)
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, key)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((hasRelationship or disabled) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Supported value range: %d - %d"], TSM.Operations.Auctioning.GetMinMaxValues(key))
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function private.CreateToggleLine(key, label)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
return TSM.MainUI.Operations.CreateLinkedSettingLine(key, label)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Auctioning", private.currentOperationName, key))
|
||||
:SetSettingInfo(operation, key)
|
||||
)
|
||||
end
|
||||
|
||||
function private.CheckUndercut(_, value)
|
||||
if not TSM.IsWowClassic() and Money.FromString(Money.ToString(value) or value) == 0 then
|
||||
return true
|
||||
elseif not TSM.IsWowClassic() and (Money.FromString(Money.ToString(value) or value) or math.huge) < COPPER_PER_SILVER then
|
||||
return false, L["Invalid undercut. To post below the cheapest auction without a significant undercut, set your undercut to 0c."]
|
||||
else
|
||||
local isValid, err = CustomPrice.Validate(value)
|
||||
if isValid then
|
||||
return true
|
||||
end
|
||||
return false, L["Invalid custom price."].." "..err
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.IgnoreLowDurationOnSelectionChanged(self)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
operation.ignoreLowDuration = self:GetSelectedItemKey() - 1
|
||||
end
|
||||
|
||||
function private.BlacklistInputOnEnterPressed(input)
|
||||
local newPlayer = input:GetValue()
|
||||
if newPlayer == "" or strfind(newPlayer, ",") or newPlayer ~= String.Escape(newPlayer) then
|
||||
-- this is an invalid player name
|
||||
return
|
||||
end
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
local found = false
|
||||
for _, player in Vararg.Iterator(strsplit(",", operation.blacklist)) do
|
||||
if newPlayer == player then
|
||||
-- this player is already added
|
||||
input:SetValue("")
|
||||
found = true
|
||||
end
|
||||
end
|
||||
if found then
|
||||
return
|
||||
end
|
||||
operation.blacklist = (operation.blacklist == "") and newPlayer or (operation.blacklist..","..newPlayer)
|
||||
input:GetElement("__parent.__parent.__parent.__parent.__parent.__parent"):ReloadContent()
|
||||
end
|
||||
|
||||
function private.RemoveBlacklistOnClick(button)
|
||||
local player = button:GetContext()
|
||||
-- FIXME: This sort of logic should go within some Auctioning-specific operation setting wrapper code
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
if operation.blacklist == player then
|
||||
operation.blacklist = ""
|
||||
else
|
||||
-- handle cases where this entry is at the start, in the middle, and at the end
|
||||
operation.blacklist = gsub(operation.blacklist, "^"..player..",", "")
|
||||
operation.blacklist = gsub(operation.blacklist, ","..player..",", ",")
|
||||
operation.blacklist = gsub(operation.blacklist, ","..player.."$", "")
|
||||
end
|
||||
button:GetElement("__parent.__parent.__parent.__parent.__parent.__parent.__parent"):ReloadContent()
|
||||
end
|
||||
|
||||
function private.SetAuctioningDuration(dropdown)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
operation.duration = dropdown:GetSelectedItemKey()
|
||||
end
|
||||
|
||||
function private.BidPercentValidateFunc(_, value)
|
||||
value = strmatch(value, "^([0-9]+) *%%?$")
|
||||
value = tonumber(value)
|
||||
if not value or value < 0 or value > 100 then
|
||||
return false, L["Bid percent must be between 0 and 100."]
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function private.BidPercentOnValueChanged(input)
|
||||
local operation = TSM.Operations.GetSettings("Auctioning", private.currentOperationName)
|
||||
local value = strmatch(input:GetValue(), "^([0-9]+) *%%?$")
|
||||
value = tonumber(value) / 100
|
||||
operation.bidPercent = value
|
||||
end
|
||||
867
Core/UI/MainUI/Operations/Core.lua
Normal file
867
Core/UI/MainUI/Operations/Core.lua
Normal file
@@ -0,0 +1,867 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Operations = TSM.MainUI:NewPackage("Operations")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Log = TSM.Include("Util.Log")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local Money = TSM.Include("Util.Money")
|
||||
local TempTable = TSM.Include("Util.TempTable")
|
||||
local Settings = TSM.Include("Service.Settings")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settings = nil,
|
||||
moduleNames = {},
|
||||
moduleCollapsed = {},
|
||||
moduleCallbacks = {},
|
||||
currentModule = nil,
|
||||
currentOperationName = nil,
|
||||
playerList = {},
|
||||
linkMenuEntries = {},
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Operations.OnInitialize()
|
||||
private.settings = Settings.NewView()
|
||||
:AddKey("global", "mainUIContext", "operationsDividedContainer")
|
||||
:AddKey("global", "mainUIContext", "operationsSummaryScrollingTable")
|
||||
TSM.MainUI.RegisterTopLevelPage(L["Operations"], private.GetOperationsFrame)
|
||||
end
|
||||
|
||||
function Operations.RegisterModule(name, callback)
|
||||
tinsert(private.moduleNames, name)
|
||||
private.moduleCallbacks[name] = callback
|
||||
end
|
||||
|
||||
function Operations.ShowOperationSettings(baseFrame, moduleName, operationName)
|
||||
baseFrame:SetSelectedNavButton(L["Operations"], true)
|
||||
baseFrame:GetElement("content.operations.selection.operationTree"):SetSelectedOperation(moduleName, operationName)
|
||||
end
|
||||
|
||||
function Operations.GetOperationManagementElements(moduleName, operationName)
|
||||
local operation = TSM.Operations.GetSettings(private.currentModule, private.currentOperationName)
|
||||
wipe(private.playerList)
|
||||
for factionrealm in TSM.db:GetConnectedRealmIterator("factionrealm") do
|
||||
for _, character in TSM.db:FactionrealmCharacterIterator(factionrealm) do
|
||||
tinsert(private.playerList, character.." - "..factionrealm)
|
||||
end
|
||||
end
|
||||
return UIElements.New("Frame", "management")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(Operations.CreateExpandableSection(moduleName, "managementOptions", L["Management Options"], L["Below you can ignore this operation on certain characters or realms."])
|
||||
:AddChild(Operations.CreateSettingLine("ignoreFactionRealms", L["Ignore operation on faction-realms"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetItems(TSM.db:GetScopeKeys("factionrealm"), TSM.db:GetScopeKeys("factionrealm"))
|
||||
:SetSelectionText(L["No Faction-Realms"], L["%d Faction-Realms"], L["All Faction-Realms"])
|
||||
:SetSettingInfo(operation, "ignoreFactionrealm")
|
||||
)
|
||||
)
|
||||
:AddChild(Operations.CreateSettingLine("ignoreCharacters", L["Ignore operation on characters"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetItems(private.playerList, private.playerList)
|
||||
:SetSelectionText(L["No Characters"], L["%d Characters"], L["All Characters"])
|
||||
:SetSettingInfo(operation, "ignorePlayer")
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(Operations.CreateExpandableSection(moduleName, "groupManagement", L["Group Management"], L["Here you can add/remove what groups this operation is attached to."])
|
||||
:AddChild(Operations.CreateSettingLine("applyNewGroup", L["Apply operation to group"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("GroupSelector", "group")
|
||||
:SetHintText(L["Add operation to groups"])
|
||||
:SetScript("OnSelectionChanged", private.GroupSelectionChanged)
|
||||
)
|
||||
)
|
||||
:AddChildrenWithFunction(private.AddOperationGroups)
|
||||
)
|
||||
end
|
||||
|
||||
function Operations.CreateExpandableSection(moduleName, id, text, description)
|
||||
return UIElements.New("CollapsibleContainer", id)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetMargin(0, 0, 0, 8)
|
||||
:SetContextTable(private.moduleCollapsed, moduleName..text)
|
||||
:SetHeadingText(text)
|
||||
:AddChild(UIElements.New("Text", "description")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(description)
|
||||
)
|
||||
end
|
||||
|
||||
function Operations.CreateLinkedSettingLine(settingKey, labelText, disabled, alternateName)
|
||||
local relationshipSet = TSM.Operations.HasRelationship(private.currentModule, private.currentOperationName, settingKey)
|
||||
return UIElements.New("Frame", alternateName or settingKey)
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Frame", "line")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor((relationshipSet or disabled) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetText(labelText)
|
||||
)
|
||||
:AddChild(private.CreateLinkButton(disabled, settingKey))
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
end
|
||||
|
||||
function Operations.CreateSettingLine(id, labelText, disabled)
|
||||
return UIElements.New("Frame", id)
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor(disabled and "TEXT_DISABLED" or "TEXT")
|
||||
:SetText(labelText)
|
||||
)
|
||||
end
|
||||
|
||||
function Operations.CreateLinkedPriceInput(settingKey, label, height, validate, defaultValue)
|
||||
local isDisabled = TSM.Operations.HasRelationship(private.currentModule, private.currentOperationName, settingKey)
|
||||
local operation = TSM.Operations.GetSettings(private.currentModule, private.currentOperationName)
|
||||
local value = operation[settingKey]
|
||||
if defaultValue ~= nil and (not value or value == "") then
|
||||
isDisabled = true
|
||||
value = defaultValue
|
||||
end
|
||||
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 Operations.CreateLinkedSettingLine(settingKey, label)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(height)
|
||||
:AddChild(UIElements.New("MultiLineInput", "input")
|
||||
:SetHeight(height - 24)
|
||||
:SetDisabled(isDisabled)
|
||||
:SetValidateFunc(validateFunc, validateContext)
|
||||
:SetSettingInfo(operation, settingKey)
|
||||
:SetValue(Money.ToString(value) or value)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Operations UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetOperationsFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations")
|
||||
local frame = UIElements.New("DividedContainer", "operations")
|
||||
:SetSettingsContext(private.settings, "operationsDividedContainer")
|
||||
:SetMinWidth(250, 250)
|
||||
:SetLeftChild(UIElements.New("Frame", "selection")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("Input", "search")
|
||||
:SetHeight(24)
|
||||
:SetMargin(8, 8, 8, 16)
|
||||
:SetIconTexture("iconPack.18x18/Search")
|
||||
:SetClearButtonEnabled(true)
|
||||
:AllowItemInsert(true)
|
||||
:SetHintText(L["Search Operations"])
|
||||
:SetScript("OnValueChanged", private.OperationSearchOnValueChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("OperationTree", "operationTree")
|
||||
:SetScript("OnOperationAdded", private.OperationTreeOnOperationAdded)
|
||||
:SetScript("OnOperationDeleted", private.OperationTreeOnOperationConfirmDelete)
|
||||
:SetScript("OnOperationSelected", private.OperationTreeOnOperationSelected)
|
||||
)
|
||||
)
|
||||
:SetRightChild(UIElements.New("ViewContainer", "content")
|
||||
:SetNavCallback(private.GetOperationsContent)
|
||||
:AddPath("none", true)
|
||||
:AddPath("summary")
|
||||
:AddPath("operation")
|
||||
)
|
||||
return frame
|
||||
end
|
||||
|
||||
function private.GetOperationsContent(_, path)
|
||||
if path == "none" then
|
||||
return UIElements.New("Frame", "settings")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth("EXPAND")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Frame", "title")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:AddChild(UIElements.New("Texture", "icon")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetTextureAndSize(TSM.UI.TexturePacks.GetColoredKey("iconPack.18x18/Operation", "TEXT"))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(L["No Operation Selected"])
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
elseif path == "summary" then
|
||||
return UIElements.New("Frame", "settings")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth("EXPAND")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Frame", "title")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer"))
|
||||
:AddChild(UIElements.New("Button", "addBtn")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(12, 12, 0, 0)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetIcon("iconPack.14x14/Add/Circle", "LEFT")
|
||||
:SetText(L["Create New"])
|
||||
:SetScript("OnClick", private.CreateNewOperationOnClick)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
-- will be filled in by the operation selection callback
|
||||
)
|
||||
elseif path == "operation" then
|
||||
return UIElements.New("Frame", "settings")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth("EXPAND")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Frame", "title")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:AddChild(UIElements.New("Texture", "icon")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetTextureAndSize(TSM.UI.TexturePacks.GetColoredKey("iconPack.18x18/Operation", "TEXT"))
|
||||
)
|
||||
:AddChild(UIElements.New("EditableText", "text")
|
||||
:SetWidth("AUTO")
|
||||
:AllowItemInsert(true)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(L["No Operation Selected"])
|
||||
:SetScript("OnValueChanged", private.OperationNameChanged)
|
||||
:SetScript("OnEditingChanged", private.NameOnEditingChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer"))
|
||||
:AddChild(UIElements.New("Button", "renameBtn")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(12, 12, 0, 0)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetIcon("iconPack.14x14/Edit", "LEFT")
|
||||
:SetText(L["Rename"])
|
||||
:SetScript("OnClick", private.RenameOperationOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "resetBtn")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetIcon("iconPack.14x14/Reset", "LEFT")
|
||||
:SetText(L["Reset"])
|
||||
:SetScript("OnClick", private.ResetOperationOnClick)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
-- will be filled in by the operation selection callback
|
||||
)
|
||||
else
|
||||
error("Invalid path: "..tostring(path))
|
||||
end
|
||||
end
|
||||
|
||||
function private.GetSummaryContent()
|
||||
local query = TSM.Operations.CreateQuery()
|
||||
:Equal("moduleName", private.currentModule)
|
||||
:VirtualField("numGroups", "number", private.NumGroupsVirtualField)
|
||||
:VirtualField("numItems", "number", private.NumItemsVirtualField)
|
||||
:OrderBy("operationName", true)
|
||||
local mostGroupsName, mostGroupsValue = "---", -math.huge
|
||||
local leastGroupsName, leastGroupsValue = "---", math.huge
|
||||
local mostItemsName, mostItemsValue = "---", -math.huge
|
||||
local leastItemsName, leastItemsValue = "---", math.huge
|
||||
for _, row in query:Iterator() do
|
||||
local operationName, numGroups, numItems = row:GetFields("operationName", "numGroups", "numItems")
|
||||
if numGroups > mostGroupsValue then
|
||||
mostGroupsValue = numGroups
|
||||
mostGroupsName = operationName
|
||||
end
|
||||
if numGroups < leastGroupsValue then
|
||||
leastGroupsValue = numGroups
|
||||
leastGroupsName = operationName
|
||||
end
|
||||
if numItems > mostItemsValue then
|
||||
mostItemsValue = numItems
|
||||
mostItemsName = operationName
|
||||
end
|
||||
if numItems < leastItemsValue then
|
||||
leastItemsValue = numItems
|
||||
leastItemsName = operationName
|
||||
end
|
||||
end
|
||||
return UIElements.New("Frame", "summary")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("Frame", "summary")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(8, 8, 0, 16)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT", true)
|
||||
:AddChild(UIElements.New("Frame", "groups")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:AddChild(UIElements.New("Frame", "most")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["MOST GROUPS"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(mostGroupsName)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "least")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["LEAST GROUPS"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(leastGroupsName)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line1")
|
||||
:SetWidth(1)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "items")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:AddChild(UIElements.New("Frame", "most")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["MOST ITEMS"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(mostItemsName)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "least")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetTextColor("ACTIVE_BG_ALT")
|
||||
:SetText(L["LEAST ITEMS"])
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
:AddChild(UIElements.New("Text", "value")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("RIGHT")
|
||||
:SetText(leastItemsName)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionScrollingTable", "list")
|
||||
:SetSettingsContext(private.settings, "operationsSummaryScrollingTable")
|
||||
:GetScrollingTableInfo()
|
||||
:NewColumn("name")
|
||||
:SetTitle(L["Operation"])
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("operationName")
|
||||
:SetSortInfo("operationName")
|
||||
:SetActionIconInfo(1, 12, private.GetConfigureIcon, true)
|
||||
:SetActionIconClickHandler(private.OnConfigureIconClick)
|
||||
:DisableHiding()
|
||||
:Commit()
|
||||
:NewColumn("groups")
|
||||
:SetTitle(L["Groups Using"])
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("numGroups")
|
||||
:SetSortInfo("numGroups")
|
||||
:Commit()
|
||||
:NewColumn("items")
|
||||
:SetTitle(L["Items Using"])
|
||||
:SetFont("TABLE_TABLE1")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetTextInfo("numItems", private.GetNumItemsText)
|
||||
:SetSortInfo("numItems")
|
||||
:SetTooltipInfo("numItems", private.GetNumItemsTooltip)
|
||||
:Commit()
|
||||
:Commit()
|
||||
:SetQuery(query)
|
||||
:SetContext(query)
|
||||
:SetAutoReleaseQuery(true)
|
||||
:SetScript("OnSelectionChanged", private.OperationListOnSelectionChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "footer")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(40)
|
||||
:SetPadding(8)
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("ActionButton", "deleteSelected")
|
||||
:SetHeight(24)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetDisabled(true)
|
||||
:SetText(L["Delete Operations"])
|
||||
:SetScript("OnClick", private.DeleteSelectedOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "selectAll")
|
||||
:SetSize("AUTO", 20)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Select All"])
|
||||
:SetScript("OnClick", private.SelectAllOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetSize(2, 20)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "clearAll")
|
||||
:SetSize("AUTO", 20)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetText(L["Clear All"])
|
||||
:SetDisabled(true)
|
||||
:SetScript("OnClick", private.ClearAllOnClick)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function private.AddOperationGroups(frame)
|
||||
for _, groupPath in TSM.Operations.GroupIterator(private.currentModule, private.currentOperationName, true) do
|
||||
frame:AddChild(private.CreateGroupOperationLine(groupPath))
|
||||
end
|
||||
end
|
||||
|
||||
function private.CreateGroupOperationLine(groupPath)
|
||||
local groupName = groupPath == TSM.CONST.ROOT_GROUP_PATH and L["Base Group"] or TSM.Groups.Path.GetName(groupPath)
|
||||
local level = select('#', strsplit(TSM.CONST.GROUP_SEP, groupPath))
|
||||
return UIElements.New("Frame", "group")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(20)
|
||||
:SetMargin(2, 0, 0, 0)
|
||||
:AddChild(UIElements.New("Text", "text")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY2")
|
||||
:SetTextColor(Theme.GetGroupColor(level))
|
||||
:SetText(groupName)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "viewBtn")
|
||||
:SetMargin(2, 2, 0, 0)
|
||||
:SetBackgroundAndSize("iconPack.14x14/Groups")
|
||||
:SetContext(groupPath)
|
||||
:SetScript("OnClick", private.ViewGroupOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "removeBtn")
|
||||
:SetBackgroundAndSize("iconPack.14x14/Close/Default")
|
||||
:SetContext(groupPath)
|
||||
:SetScript("OnClick", private.RemoveOperationGroupOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
end
|
||||
|
||||
function private.CreateLinkButton(disabled, settingKey)
|
||||
local relationshipSet = TSM.Operations.HasRelationship(private.currentModule, private.currentOperationName, settingKey)
|
||||
local linkTexture = nil
|
||||
if disabled and relationshipSet then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR_DISABLED")
|
||||
elseif disabled then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT_DISABLED")
|
||||
elseif relationshipSet then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR")
|
||||
else
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT")
|
||||
end
|
||||
return UIElements.New("Button", "linkBtn")
|
||||
:SetMargin(4, 4, 0, 0)
|
||||
:SetBackgroundAndSize(linkTexture)
|
||||
:SetDisabled(disabled)
|
||||
:SetContext(settingKey)
|
||||
:SetScript("OnClick", private.LinkBtnOnClick)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.OperationSearchOnValueChanged(input)
|
||||
local filter = strlower(input:GetValue())
|
||||
input:GetElement("__parent.operationTree"):SetOperationNameFilter(filter)
|
||||
end
|
||||
|
||||
function private.OperationTreeOnOperationAdded(operationTree, moduleName, operationName, copyOperationName)
|
||||
-- clear the filter
|
||||
operationTree:GetElement("__parent.search")
|
||||
:SetValue("")
|
||||
:Draw()
|
||||
operationTree:SetOperationNameFilter("")
|
||||
TSM.Operations.Create(moduleName, operationName)
|
||||
if copyOperationName then
|
||||
TSM.Operations.Copy(moduleName, operationName, copyOperationName)
|
||||
end
|
||||
end
|
||||
|
||||
function private.OperationTreeOnOperationConfirmDelete(self, moduleName, operationName)
|
||||
self:GetBaseElement():ShowConfirmationDialog(L["Delete Operation?"], L["Are you sure you want to delete this operation?"], private.OperationTreeOnOperationDeleted, self, moduleName, operationName)
|
||||
end
|
||||
|
||||
function private.OperationTreeOnOperationDeleted(self, moduleName, operationName)
|
||||
TSM.Operations.Delete(moduleName, operationName)
|
||||
local operationTree = self:GetElement("__parent.operationTree")
|
||||
operationTree:SetSelectedOperation(moduleName, nil)
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function private.OperationTreeOnOperationSelected(self, moduleName, operationName)
|
||||
private.currentModule = moduleName
|
||||
private.currentOperationName = operationName
|
||||
|
||||
local viewContainer = self:GetParentElement():GetParentElement():GetElement("content")
|
||||
if moduleName and operationName then
|
||||
TSM.Operations.Update(moduleName, operationName)
|
||||
viewContainer:SetPath("operation")
|
||||
viewContainer:GetElement("settings.title.text"):SetText(operationName)
|
||||
local contentFrame = viewContainer:GetElement("settings.content")
|
||||
contentFrame:ReleaseAllChildren()
|
||||
contentFrame:AddChild(private.moduleCallbacks[moduleName](operationName))
|
||||
elseif moduleName then
|
||||
local numOperations = 0
|
||||
for _ in TSM.Operations.OperationIterator(moduleName) do
|
||||
numOperations = numOperations + 1
|
||||
end
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "summary")
|
||||
viewContainer:SetPath("summary")
|
||||
viewContainer:GetElement("settings.title.text"):SetText(format(L["%s %s Operations"], Theme.GetColor("INDICATOR"):ColorText(numOperations), moduleName))
|
||||
local contentFrame = viewContainer:GetElement("settings.content")
|
||||
contentFrame:ReleaseAllChildren()
|
||||
contentFrame:AddChild(private.GetSummaryContent())
|
||||
else
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "none")
|
||||
viewContainer:SetPath("none")
|
||||
viewContainer:GetElement("settings.title.text"):SetText(L["No Operation Selected"])
|
||||
end
|
||||
viewContainer:Draw()
|
||||
end
|
||||
|
||||
function private.CreateNewOperationOnClick(button)
|
||||
local operationName = "New Operation"
|
||||
local num = 1
|
||||
while TSM.Operations.Exists(private.currentModule, operationName.." "..num) do
|
||||
num = num + 1
|
||||
end
|
||||
operationName = operationName .. " " .. num
|
||||
TSM.Operations.Create(private.currentModule, operationName)
|
||||
button:GetElement("__parent.__parent.__parent.__parent.selection.operationTree")
|
||||
:SetSelectedOperation(private.currentModule, operationName)
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function private.OperationNameChanged(text, newValue)
|
||||
newValue = strtrim(newValue)
|
||||
if newValue == private.currentOperationName then
|
||||
-- didn't change
|
||||
text:Draw()
|
||||
elseif newValue == "" then
|
||||
Log.PrintUser(L["Invalid operation name."])
|
||||
text:Draw()
|
||||
elseif TSM.Operations.Exists(private.currentModule, newValue) then
|
||||
Log.PrintUser(L["Group already exists."])
|
||||
text:Draw()
|
||||
else
|
||||
TSM.Operations.Rename(private.currentModule, private.currentOperationName, newValue)
|
||||
text:GetElement("__parent.__parent.__parent.__parent.selection.operationTree")
|
||||
:SetSelectedOperation(private.currentModule, newValue)
|
||||
:Draw()
|
||||
end
|
||||
end
|
||||
|
||||
function private.NameOnEditingChanged(text, editing)
|
||||
if editing then
|
||||
text:GetElement("__parent.renameBtn"):Hide()
|
||||
else
|
||||
text:GetElement("__parent.renameBtn"):Show()
|
||||
end
|
||||
end
|
||||
|
||||
function private.RenameOperationOnClick(button)
|
||||
button:GetElement("__parent.text"):SetEditing(true)
|
||||
end
|
||||
|
||||
function private.ResetOperationOnClick(button)
|
||||
button:GetBaseElement():ShowConfirmationDialog(L["Reset Operation?"], L["Resetting the operation will return all inputs back to default and cannot be unddone. Click confirm to reset."], private.ConfirmResetOnClick, button)
|
||||
end
|
||||
|
||||
function private.ConfirmResetOnClick(button)
|
||||
TSM.Operations.Reset(private.currentModule, private.currentOperationName)
|
||||
local settingsFrame = button:GetBaseElement():GetElement("content.operations.content.settings")
|
||||
local contentFrame = settingsFrame:GetElement("content")
|
||||
contentFrame:ReleaseAllChildren()
|
||||
TSM.Operations.Update(private.currentModule, private.currentOperationName)
|
||||
contentFrame:AddChild(private.moduleCallbacks[private.currentModule](private.currentOperationName))
|
||||
button:GetBaseElement():HideDialog()
|
||||
settingsFrame:Draw()
|
||||
Log.PrintfUser(L["%s - %s has been reset to default values."], private.currentModule, Theme.GetColor("INDICATOR_ALT"):ColorText(private.currentOperationName))
|
||||
end
|
||||
|
||||
function private.GroupSelectionChanged(groupSelector)
|
||||
for groupPath in groupSelector:SelectedGroupIterator() do
|
||||
if not TSM.Operations.GroupHasOperation(private.currentModule, groupPath, private.currentOperationName) then
|
||||
local parentElement = groupSelector:GetParentElement():GetParentElement()
|
||||
if groupPath ~= TSM.CONST.ROOT_GROUP_PATH then
|
||||
TSM.Groups.SetOperationOverride(groupPath, private.currentModule, true)
|
||||
end
|
||||
local numOperations = 0
|
||||
local lastOperationName = nil
|
||||
for _, groupOperationName in TSM.Groups.OperationIterator(groupPath, private.currentModule) do
|
||||
lastOperationName = groupOperationName
|
||||
numOperations = numOperations + 1
|
||||
end
|
||||
if numOperations == TSM.Operations.GetMaxNumber(private.currentModule) then
|
||||
-- replace the last operation since we're already at the max number of operations
|
||||
TSM.Groups.RemoveOperation(groupPath, private.currentModule, numOperations)
|
||||
Log.PrintfUser(L["%s previously had the max number of operations, so removed %s."], Log.ColorUserAccentText(TSM.Groups.Path.Format(groupPath)), Log.ColorUserAccentText(lastOperationName))
|
||||
end
|
||||
TSM.Groups.AppendOperation(groupPath, private.currentModule, private.currentOperationName)
|
||||
Log.PrintfUser(L["Added %s to %s."], Log.ColorUserAccentText(private.currentOperationName), Log.ColorUserAccentText(groupPath == TSM.CONST.ROOT_GROUP_PATH and L["Base Group"] or TSM.Groups.Path.Format(groupPath)))
|
||||
parentElement:AddChild(private.CreateGroupOperationLine(groupPath))
|
||||
end
|
||||
end
|
||||
groupSelector:ClearSelectedGroups(true)
|
||||
groupSelector:GetParentElement():GetParentElement():GetParentElement():GetParentElement():GetParentElement():GetParentElement():Draw()
|
||||
end
|
||||
|
||||
function private.ViewGroupOnClick(button)
|
||||
local baseFrame = button:GetBaseElement()
|
||||
TSM.MainUI.Groups.ShowGroupSettings(baseFrame, button:GetContext())
|
||||
end
|
||||
|
||||
function private.RemoveOperationGroupOnClick(self)
|
||||
local groupPath = self:GetContext()
|
||||
TSM.Groups.RemoveOperationByName(groupPath, private.currentModule, private.currentOperationName)
|
||||
|
||||
-- remove the line for this group
|
||||
local removeElement = self:GetParentElement()
|
||||
local removeElementParent = removeElement:GetParentElement()
|
||||
removeElementParent:RemoveChild(removeElement)
|
||||
removeElement:Release()
|
||||
removeElementParent:GetParentElement():GetParentElement():GetParentElement():Draw()
|
||||
end
|
||||
|
||||
function private.LinkBtnOnClick(button)
|
||||
local settingKey = button:GetContext()
|
||||
wipe(private.linkMenuEntries)
|
||||
for _, operationName in TSM.Operations.OperationIterator(private.currentModule) do
|
||||
if operationName ~= private.currentOperationName and not TSM.Operations.IsCircularRelationship(private.currentModule, private.currentOperationName, settingKey) then
|
||||
tinsert(private.linkMenuEntries, operationName)
|
||||
end
|
||||
end
|
||||
sort(private.linkMenuEntries)
|
||||
button:GetBaseElement():ShowDialogFrame(UIElements.New("PopupFrame", "linkDialog")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetSize(263, 243)
|
||||
:AddAnchor("TOPRIGHT", button:_GetBaseFrame(), "BOTTOM", 22, -16)
|
||||
:AddChild(UIElements.New("Frame", "titleFrame")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(37)
|
||||
:AddChild(UIElements.New("Text", "title")
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetJustifyH("CENTER")
|
||||
:SetText(L["Link to Another Operation"])
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("TEXT")
|
||||
)
|
||||
:AddChild(UIElements.New("SelectionList", "list")
|
||||
:SetContext(settingKey)
|
||||
:SetMargin(2, 2, 0, 3)
|
||||
:SetEntries(private.linkMenuEntries, TSM.Operations.GetRelationship(private.currentModule, private.currentOperationName, settingKey))
|
||||
:SetScript("OnEntrySelected", private.ListOnEntrySelected)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function private.ListOnEntrySelected(list, operationName)
|
||||
local settingKey = list:GetContext()
|
||||
local previousValue = TSM.Operations.GetRelationship(private.currentModule, private.currentOperationName, settingKey)
|
||||
if operationName == previousValue then
|
||||
TSM.Operations.SetRelationship(private.currentModule, private.currentOperationName, settingKey, nil)
|
||||
else
|
||||
TSM.Operations.SetRelationship(private.currentModule, private.currentOperationName, settingKey, operationName)
|
||||
end
|
||||
|
||||
local baseFrame = list:GetBaseElement()
|
||||
baseFrame:HideDialog()
|
||||
Operations.ShowOperationSettings(baseFrame, private.currentModule, private.currentOperationName)
|
||||
end
|
||||
|
||||
function private.OperationListOnSelectionChanged(scrollingTable)
|
||||
local selectionCleared = scrollingTable:IsSelectionCleared()
|
||||
local numSelected = 0
|
||||
for _ in scrollingTable:SelectionIterator() do
|
||||
numSelected = numSelected + 1
|
||||
end
|
||||
local footer = scrollingTable:GetElement("__parent.footer")
|
||||
footer:GetElement("deleteSelected")
|
||||
:SetText(numSelected > 0 and format(L["Delete %d Operations"], numSelected) or L["Delete Operations"])
|
||||
:SetDisabled(selectionCleared)
|
||||
footer:GetElement("selectAll")
|
||||
:SetDisabled(scrollingTable:IsAllSelected())
|
||||
footer:GetElement("clearAll")
|
||||
:SetDisabled(selectionCleared)
|
||||
footer:Draw()
|
||||
end
|
||||
|
||||
function private.SelectAllOnClick(button)
|
||||
button:GetElement("__parent.__parent.list"):SelectAll()
|
||||
end
|
||||
|
||||
function private.ClearAllOnClick(button)
|
||||
button:GetElement("__parent.__parent.list"):ClearSelection()
|
||||
end
|
||||
|
||||
function private.DeleteSelectedOnClick(button)
|
||||
local scrollingTable = button:GetElement("__parent.__parent.list")
|
||||
button:GetBaseElement():ShowConfirmationDialog(L["Delete Operations?"], L["Are you sure you want to delete the selected operations?"], private.DeleteSelectedOperations, scrollingTable)
|
||||
end
|
||||
|
||||
function private.DeleteSelectedOperations(scrollingTable)
|
||||
local toDelete = TempTable.Acquire()
|
||||
for _, row in scrollingTable:SelectionIterator() do
|
||||
local moduleName, operationName = row:GetFields("moduleName", "operationName")
|
||||
assert(moduleName == private.currentModule)
|
||||
tinsert(toDelete, operationName)
|
||||
end
|
||||
TSM.Operations.DeleteList(private.currentModule, toDelete)
|
||||
TempTable.Release(toDelete)
|
||||
scrollingTable:UpdateData(true)
|
||||
private.OperationListOnSelectionChanged(scrollingTable)
|
||||
scrollingTable:GetElement("__parent.__parent.__parent.__parent.__parent.selection.operationTree"):UpdateData(true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.NumGroupsVirtualField(row)
|
||||
local num = 0
|
||||
for _ in TSM.Operations.GroupIterator(row:GetField("moduleName"), row:GetField("operationName")) do
|
||||
num = num + 1
|
||||
end
|
||||
return num
|
||||
end
|
||||
|
||||
function private.NumItemsVirtualField(row)
|
||||
local includesBaseGroup = false
|
||||
local num = 0
|
||||
for _, groupPath in TSM.Operations.GroupIterator(row:GetField("moduleName"), row:GetField("operationName")) do
|
||||
if groupPath == TSM.CONST.ROOT_GROUP_PATH then
|
||||
includesBaseGroup = true
|
||||
else
|
||||
num = num + TSM.Groups.GetNumItems(groupPath)
|
||||
end
|
||||
end
|
||||
if includesBaseGroup then
|
||||
num = num + 0.9
|
||||
end
|
||||
return num
|
||||
end
|
||||
|
||||
function private.GetConfigureIcon(_, _, iconIndex)
|
||||
assert(iconIndex == 1)
|
||||
return true, "iconPack.12x12/Popout", false
|
||||
end
|
||||
|
||||
function private.OnConfigureIconClick(scrollingTable, data, iconIndex)
|
||||
assert(iconIndex == 1)
|
||||
local operationName = scrollingTable:GetContext():GetResultRowByUUID(data):GetField("operationName")
|
||||
scrollingTable:GetElement("__parent.__parent.__parent.__parent.__parent.selection.operationTree")
|
||||
:SetSelectedOperation(private.currentModule, operationName)
|
||||
end
|
||||
|
||||
function private.GetNumItemsText(numItems)
|
||||
if numItems == floor(numItems) then
|
||||
return numItems
|
||||
else
|
||||
return floor(numItems).."*"
|
||||
end
|
||||
end
|
||||
|
||||
function private.GetNumItemsTooltip(numItems)
|
||||
if numItems == floor(numItems) then
|
||||
return nil
|
||||
end
|
||||
return L["This operation is applied to the base group which includes every item not in another group."]
|
||||
end
|
||||
159
Core/UI/MainUI/Operations/Crafting.lua
Normal file
159
Core/UI/MainUI/Operations/Crafting.lua
Normal file
@@ -0,0 +1,159 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Crafting = TSM.MainUI.Operations:NewPackage("Crafting")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
}
|
||||
local BAD_CRAFT_VALUE_PRICE_SOURCES = {
|
||||
crafting = true,
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Crafting.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Crafting", private.GetCraftingOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Crafting Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetCraftingOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "crafting")
|
||||
private.currentOperationName = operationName
|
||||
local operation = TSM.Operations.GetSettings("Crafting", private.currentOperationName)
|
||||
local frame = UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Crafting", "restockQuantity", L["Restock Options"], L["Adjust how crafted items are restocked."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("minRestock", L["Min restock quantity"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "minRestock")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "minRestock"))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "minRestock") and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Supported range: %d - %d"], TSM.Operations.Crafting.GetRestockRange())
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("maxRestock", L["Max restock quantity"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "maxRestock")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "maxRestock"))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "maxRestock") and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Supported range: %d - %d"], TSM.Operations.Crafting.GetRestockRange())
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("minProfit", L["Set min profit"], nil, "minProfitToggle")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(42)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetValue(operation.minProfit ~= "")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "minProfit"))
|
||||
:SetScript("OnValueChanged", private.MinProfitToggleOnValueChanged)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Crafting", "priceSettings", L["Crafting Value"], L["Adjust how TSM values crafted items when calculating profit."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("craftPriceMethod", L["Override default craft value"], nil, "craftPriceMethodToggle")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(42)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetValue(operation.craftPriceMethod ~= "")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Crafting", private.currentOperationName, "craftPriceMethod"))
|
||||
:SetScript("OnValueChanged", private.CraftPriceToggleOnValueChanged)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Crafting", private.currentOperationName))
|
||||
|
||||
if operation.minProfit ~= "" then
|
||||
frame:GetElement("restockQuantity.content.minProfitToggle"):SetMargin(0, 0, 0, 12)
|
||||
frame:GetElement("restockQuantity"):AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("minProfit", L["Min profit amount"], 80))
|
||||
end
|
||||
if operation.craftPriceMethod ~= "" then
|
||||
frame:GetElement("priceSettings.content.craftPriceMethodToggle"):SetMargin(0, 0, 0, 12)
|
||||
frame:GetElement("priceSettings"):AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("craftPriceMethod", L["Craft Value"], 80, BAD_CRAFT_VALUE_PRICE_SOURCES, TSM.db.global.craftingOptions.defaultCraftPriceMethod))
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.MinProfitToggleOnValueChanged(toggle, value)
|
||||
local operation = TSM.Operations.GetSettings("Crafting", private.currentOperationName)
|
||||
local defaultValue = TSM.Operations.GetSettingDefault("Crafting", "minProfit")
|
||||
operation.minProfit = value and defaultValue or ""
|
||||
local settingsFrame = toggle:GetParentElement():GetParentElement()
|
||||
if value then
|
||||
settingsFrame:GetElement("minProfitToggle"):SetMargin(0, 0, 0, 12)
|
||||
settingsFrame:GetParentElement():AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("minProfit", L["Min profit amount"], 80))
|
||||
else
|
||||
settingsFrame:GetElement("minProfitToggle"):SetMargin(0, 0, 0, 0)
|
||||
local linkedPriceLine = settingsFrame:GetElement("minProfit")
|
||||
settingsFrame:RemoveChild(linkedPriceLine)
|
||||
linkedPriceLine:Release()
|
||||
end
|
||||
settingsFrame:GetParentElement():GetParentElement():Draw()
|
||||
end
|
||||
|
||||
function private.CraftPriceToggleOnValueChanged(toggle, value)
|
||||
local operation = TSM.Operations.GetSettings("Crafting", private.currentOperationName)
|
||||
operation.craftPriceMethod = value and TSM.db.global.craftingOptions.defaultCraftPriceMethod or ""
|
||||
local settingsFrame = toggle:GetParentElement():GetParentElement()
|
||||
if value then
|
||||
settingsFrame:GetElement("craftPriceMethodToggle"):SetMargin(0, 0, 0, 12)
|
||||
settingsFrame:GetParentElement():AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("craftPriceMethod", L["Craft Value"], 80, BAD_CRAFT_VALUE_PRICE_SOURCES, TSM.db.global.craftingOptions.defaultCraftPriceMethod))
|
||||
else
|
||||
settingsFrame:GetElement("craftPriceMethodToggle"):SetMargin(0, 0, 0, 0)
|
||||
local linkedPriceLine = settingsFrame:GetElement("craftPriceMethod")
|
||||
settingsFrame:RemoveChild(linkedPriceLine)
|
||||
linkedPriceLine:Release()
|
||||
end
|
||||
settingsFrame:GetParentElement():GetParentElement():Draw()
|
||||
end
|
||||
220
Core/UI/MainUI/Operations/Mailing.lua
Normal file
220
Core/UI/MainUI/Operations/Mailing.lua
Normal file
@@ -0,0 +1,220 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Mailing = TSM.MainUI.Operations:NewPackage("Mailing")
|
||||
local PlayerInfo = TSM.Include("Service.PlayerInfo")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Mailing.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Mailing", private.GetMailingOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Mailing Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetMailingOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "mailing")
|
||||
private.currentOperationName = operationName
|
||||
local operation = TSM.Operations.GetSettings("Mailing", private.currentOperationName)
|
||||
return UIElements.New("ScrollFrame", "content")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Mailing", "generalOptions", L["General Options"], L["Adjust how items are mailed."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("target", L["Target character"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetHintText(L["Enter player name"])
|
||||
:SetAutoComplete(PlayerInfo.GetConnectedAlts())
|
||||
:SetClearButtonEnabled(true)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "target"))
|
||||
:SetSettingInfo(operation, "target")
|
||||
)
|
||||
:AddChild(UIElements.New("ActionButton", "contacts")
|
||||
:SetSize(152, 24)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetText(L["Contacts"])
|
||||
:SetScript("OnClick", private.ContactsBtnOnClick)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("keepQty", L["Keep this amount"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", "0:50000")
|
||||
:SetSettingInfo(operation, "keepQty")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "keepQty"))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "keepQty") and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], 0, 50000)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("maxQtyEnabled", L["Set max quantity"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(42)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "maxQtyEnabled")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "maxQtyEnabled"))
|
||||
:SetScript("OnValueChanged", private.MaxQuantityToggleOnValueChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("maxQty", L["Max quantity"], not operation.maxQtyEnabled)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", "1:50000")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "maxQty") or not operation.maxQtyEnabled)
|
||||
:SetSettingInfo(operation, "maxQty")
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "maxQty") or not operation.maxQtyEnabled) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], 1, 50000)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restock", L["Restock target to max quantity"], not operation.maxQtyEnabled)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(42)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "restock")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "restock") or not operation.maxQtyEnabled)
|
||||
:SetScript("OnValueChanged", private.RestockToggleOnValueChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restockSources", L["Sources to include for restock"], not operation.restock or not operation.maxQtyEnabled)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:AddItem(BANK, "bank")
|
||||
:AddItem(GUILD, "guild")
|
||||
:SetSettingInfo(operation, "restockSources")
|
||||
:SetSelectionText(L["No Sources"], L["%d Sources"], L["All Sources"])
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "restockSources") or not operation.restock or not operation.maxQtyEnabled)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Mailing", private.currentOperationName))
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.ContactsBtnOnClick(button)
|
||||
TSM.UI.Util.Contacts.ShowDialog(button, button:GetElement("__parent.input"))
|
||||
end
|
||||
|
||||
|
||||
function private.MaxQuantityToggleOnValueChanged(toggle, value)
|
||||
local settingsFrame = toggle:GetElement("__parent.__parent")
|
||||
local restockValue = settingsFrame:GetElement("restock.toggle"):GetValue()
|
||||
local relationshipSet, linkTexture, textColor = TSM.Operations.GetRelationshipColors("Mailing", private.currentOperationName, "maxQty", value)
|
||||
settingsFrame:GetElement("maxQty.line.linkBtn")
|
||||
:SetBackground(linkTexture)
|
||||
:SetDisabled(not value)
|
||||
settingsFrame:GetElement("maxQty.line.label")
|
||||
:SetTextColor(textColor)
|
||||
settingsFrame:GetElement("maxQty.content.label")
|
||||
:SetTextColor(textColor)
|
||||
settingsFrame:GetElement("maxQty.content.input")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
|
||||
relationshipSet, linkTexture, textColor = TSM.Operations.GetRelationshipColors("Mailing", private.currentOperationName, "restock", value)
|
||||
settingsFrame:GetElement("restock.line.linkBtn")
|
||||
:SetBackground(linkTexture)
|
||||
:SetDisabled(not value)
|
||||
settingsFrame:GetElement("restock.line.label")
|
||||
:SetTextColor(textColor)
|
||||
settingsFrame:GetElement("restock.toggle")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
|
||||
relationshipSet = TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "restockSources")
|
||||
if relationshipSet and value and restockValue then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR")
|
||||
elseif (relationshipSet and not value and restockValue) or (relationshipSet and value and not restockValue) or (relationshipSet and not value and not restockValue) then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR_DISABLED")
|
||||
elseif (value and not restockValue) or (not value and restockValue) or (not value and not restockValue) then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT_DISABLED")
|
||||
else
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT")
|
||||
end
|
||||
settingsFrame:GetElement("restockSources.line.linkBtn")
|
||||
:SetBackground(linkTexture)
|
||||
:SetDisabled(not value)
|
||||
settingsFrame:GetElement("restockSources.line.label")
|
||||
:SetTextColor(relationshipSet and "TEXT_DISABLED" or ((value and restockValue) and "TEXT" or "TEXT_DISABLED"))
|
||||
settingsFrame:GetElement("restockSources.dropdown")
|
||||
:SetDisabled(relationshipSet or not value or not restockValue)
|
||||
settingsFrame:Draw()
|
||||
end
|
||||
|
||||
function private.RestockToggleOnValueChanged(toggle, value)
|
||||
local settingsFrame = toggle:GetElement("__parent.__parent")
|
||||
local maxQtyEnabled = settingsFrame:GetElement("maxQtyEnabled.toggle"):GetValue()
|
||||
local relationshipSet = TSM.Operations.HasRelationship("Mailing", private.currentOperationName, "restockSources")
|
||||
local linkTexture = nil
|
||||
if relationshipSet and value and maxQtyEnabled then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR")
|
||||
elseif (relationshipSet and not value and maxQtyEnabled) or (relationshipSet and value and not maxQtyEnabled) or (relationshipSet and not value and not maxQtyEnabled) then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "INDICATOR_DISABLED")
|
||||
elseif (value and not maxQtyEnabled) or (not value and maxQtyEnabled) or (not value and not maxQtyEnabled) then
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT_DISABLED")
|
||||
else
|
||||
linkTexture = TSM.UI.TexturePacks.GetColoredKey("iconPack.14x14/Link", "TEXT")
|
||||
end
|
||||
settingsFrame:GetElement("restockSources.line.linkBtn")
|
||||
:SetBackground(linkTexture)
|
||||
:SetDisabled(not value)
|
||||
settingsFrame:GetElement("restockSources.line.label")
|
||||
:SetTextColor(relationshipSet and "TEXT_DISABLED" or ((value and maxQtyEnabled) and "TEXT" or "TEXT_DISABLED"))
|
||||
settingsFrame:GetElement("restockSources.dropdown")
|
||||
:SetDisabled(relationshipSet or not value or not maxQtyEnabled)
|
||||
settingsFrame:Draw()
|
||||
end
|
||||
88
Core/UI/MainUI/Operations/Shopping.lua
Normal file
88
Core/UI/MainUI/Operations/Shopping.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Shopping = TSM.MainUI.Operations:NewPackage("Shopping")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
}
|
||||
local RESTOCK_SOURCES = { L["Alts"], L["Auctions"], BANK, GUILD }
|
||||
local RESTOCK_SOURCES_KEYS = { "alts", "auctions", "bank", "guild" }
|
||||
local BAD_PRICE_SOURCES = { shoppingopmax = true }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Shopping.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Shopping", private.GetShoppingOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Shopping Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetShoppingOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "shopping")
|
||||
private.currentOperationName = operationName
|
||||
local operation = TSM.Operations.GetSettings("Shopping", private.currentOperationName)
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Shopping", "generalOptions", L["General Options"], L["Set what items are shown during a Shopping scan."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("maxPrice", L["Maximum auction price"], 124, BAD_PRICE_SOURCES))
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("showAboveMaxPrice", L["Show auctions above max price"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 12, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "showAboveMaxPrice")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Shopping", private.currentOperationName, "showAboveMaxPrice"))
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restockQuantity", L["Maximum restock quantity"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "restockQuantity")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Shopping", private.currentOperationName, "restockQuantity"))
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor(TSM.Operations.HasRelationship("Shopping", private.currentOperationName, "restockQuantity") and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Supported range: %d - %d"], TSM.Operations.Shopping.GetRestockRange())
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restockSources", L["Sources to include for restock"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetItems(RESTOCK_SOURCES, RESTOCK_SOURCES_KEYS)
|
||||
:SetSettingInfo(operation, "restockSources")
|
||||
:SetSelectionText(L["No Sources"], L["%d Sources"], L["All Sources"])
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Shopping", private.currentOperationName, "restockSources"))
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Shopping", private.currentOperationName))
|
||||
end
|
||||
42
Core/UI/MainUI/Operations/Sniper.lua
Normal file
42
Core/UI/MainUI/Operations/Sniper.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Sniper = TSM.MainUI.Operations:NewPackage("Sniper")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
}
|
||||
local BAD_PRICE_SOURCES = { sniperopmax = true }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Sniper.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Sniper", private.GetSniperOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Sniper Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetSniperOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "sniper")
|
||||
private.currentOperationName = operationName
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Sniper", "settings", L["General Options"], L["Set what items are shown during a Sniper scan."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedPriceInput("belowPrice", L["Maximum price"], 124, BAD_PRICE_SOURCES))
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Sniper", private.currentOperationName))
|
||||
end
|
||||
268
Core/UI/MainUI/Operations/Vendoring.lua
Normal file
268
Core/UI/MainUI/Operations/Vendoring.lua
Normal file
@@ -0,0 +1,268 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Vendoring = TSM.MainUI.Operations:NewPackage("Vendoring")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
currentOperationName = nil,
|
||||
}
|
||||
local RESTOCK_SOURCES = { BANK, GUILD, L["Alts"], L["Alts AH"], L["AH"], L["Mail"] }
|
||||
local RESTOCK_SOURCES_KEYS = { "bank", "guild", "alts", "alts_ah", "ah", "mail" }
|
||||
local SETTING_INFO = {
|
||||
restockQty = "INPUT_LABEL",
|
||||
restockSources = "DROPDOWN",
|
||||
keepQty = "INPUT_LABEL",
|
||||
sellAfterExpired = "INPUT_LABEL",
|
||||
vsMarketValue = "INPUT",
|
||||
vsMaxMarketValue = "INPUT",
|
||||
vsDestroyValue = "INPUT",
|
||||
vsMaxDestroyValue = "INPUT",
|
||||
sellSoulbound = "TOGGLE",
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Vendoring.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Vendoring", private.GetVendoringOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Vendoring Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetVendoringOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "vendoring")
|
||||
private.currentOperationName = operationName
|
||||
|
||||
local operation = TSM.Operations.GetSettings("Vendoring", private.currentOperationName)
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Vendoring", "buyOptionsHeading", L["Buy Options"], L["Set what is bought from a vendor."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("enableBuy", L["Enable buying"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "enableBuy")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "enableBuy"))
|
||||
:SetScript("OnValueChanged", private.EnableBuyingToggleOnValueChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restockQty", L["Restock quantity"], not operation.enableBuy)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", "0:50000")
|
||||
:SetSettingInfo(operation, "restockQty")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "restockQty") or not operation.enableBuy)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "restockQty") or not operation.enableBuy) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], 0, 50000)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("restockSources", L["Sources to include for restock"], not operation.enableBuy)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:AddChild(UIElements.New("MultiselectionDropdown", "dropdown")
|
||||
:SetHeight(24)
|
||||
:SetItems(RESTOCK_SOURCES, RESTOCK_SOURCES_KEYS)
|
||||
:SetSettingInfo(operation, "restockSources")
|
||||
:SetSelectionText(L["No Sources"], L["%d Sources"], L["All Sources"])
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "restockSources") or not operation.enableBuy)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Vendoring", "sellOptionsHeading", L["Sell Options"], L["Set what is sold to a vendor."])
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("enableSell", L["Enable selling"])
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "enableSell")
|
||||
:SetScript("OnValueChanged", private.EnableSellingToggleOnValueChanged)
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "enableSell"))
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("keepQty", L["Keep quantity"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", "0:50000")
|
||||
:SetSettingInfo(operation, "keepQty")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "keepQty") or not operation.enableSell)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "keepQty") or not operation.enableSell) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], 0, 50000)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("sellAfterExpired", L["Min number of expires"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", "0:50000")
|
||||
:SetSettingInfo(operation, "sellAfterExpired")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "sellAfterExpired") or not operation.enableSell)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "sellAfterExpired") or not operation.enableSell) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], 0, 50000)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("vsMarketValue", L["Market value"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "vsMarketValue")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "vsMarketValue") or not operation.enableSell)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("vsMaxMarketValue", L["Max market value (Enter '0c' to disable)"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "vsMaxMarketValue")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "vsMaxMarketValue") or not operation.enableSell)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("vsDestroyValue", L["Destroy value"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "vsDestroyValue")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "vsDestroyValue") or not operation.enableSell)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("vsMaxDestroyValue", L["Max destroy value (Enter '0c' to disable)"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetHeight(24)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("CUSTOM_PRICE")
|
||||
:SetSettingInfo(operation, "vsMaxDestroyValue")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "vsMaxDestroyValue") or not operation.enableSell)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine("sellSoulbound", L["Sell soulbound items"], not operation.enableSell)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 0)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetSettingInfo(operation, "sellSoulbound")
|
||||
:SetDisabled(TSM.Operations.HasRelationship("Vendoring", private.currentOperationName, "sellSoulbound") or not operation.enableSell)
|
||||
)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Vendoring", private.currentOperationName))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateSettingState(settingsFrame, key, operation, value)
|
||||
local relationshipSet, linkTexture, textColor = TSM.Operations.GetRelationshipColors("Vendoring", private.currentOperationName, key, value)
|
||||
local settingKeyFrame = settingsFrame:GetElement(key)
|
||||
settingKeyFrame:GetElement("line.linkBtn")
|
||||
:SetBackground(linkTexture)
|
||||
:SetDisabled(not value)
|
||||
settingKeyFrame:GetElement("line.label")
|
||||
:SetTextColor(textColor)
|
||||
local settingType = SETTING_INFO[key]
|
||||
if settingType == "INPUT_LABEL" then
|
||||
settingKeyFrame:GetElement("content.input")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
:SetValue(operation[key] or "")
|
||||
settingKeyFrame:GetElement("content.label")
|
||||
:SetTextColor(textColor)
|
||||
elseif settingType == "INPUT" then
|
||||
settingKeyFrame:GetElement("input")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
elseif settingType == "TOGGLE" then
|
||||
settingKeyFrame:GetElement("toggle")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
elseif settingType == "DROPDOWN" then
|
||||
settingKeyFrame:GetElement("dropdown")
|
||||
:SetDisabled(relationshipSet or not value)
|
||||
else
|
||||
error("Invalid settingType: "..tostring(settingType))
|
||||
end
|
||||
end
|
||||
|
||||
function private.EnableBuyingToggleOnValueChanged(toggle, value)
|
||||
local operation = TSM.Operations.GetSettings("Vendoring", private.currentOperationName)
|
||||
local settingsFrame = toggle:GetElement("__parent.__parent")
|
||||
private.UpdateSettingState(settingsFrame, "restockQty", operation, value)
|
||||
private.UpdateSettingState(settingsFrame, "restockSources", operation, value)
|
||||
settingsFrame:Draw()
|
||||
end
|
||||
|
||||
function private.EnableSellingToggleOnValueChanged(toggle, value)
|
||||
local operation = TSM.Operations.GetSettings("Vendoring", private.currentOperationName)
|
||||
local settingsFrame = toggle:GetElement("__parent.__parent")
|
||||
for key in pairs(SETTING_INFO) do
|
||||
if key ~= "restockQty" and key ~= "restockSources" then
|
||||
private.UpdateSettingState(settingsFrame, key, operation, value)
|
||||
end
|
||||
end
|
||||
settingsFrame:Draw()
|
||||
end
|
||||
108
Core/UI/MainUI/Operations/Warehousing.lua
Normal file
108
Core/UI/MainUI/Operations/Warehousing.lua
Normal file
@@ -0,0 +1,108 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Warehousing = TSM.MainUI.Operations:NewPackage("Warehousing")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = { currentOperationName = nil }
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Warehousing.OnInitialize()
|
||||
TSM.MainUI.Operations.RegisterModule("Warehousing", private.GetWarehousingOperationSettings)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Warehousing Operation Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetWarehousingOperationSettings(operationName)
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "operations", "warehousing")
|
||||
private.currentOperationName = operationName
|
||||
return UIElements.New("ScrollFrame", "settings")
|
||||
:SetPadding(8, 8, 8, 0)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Warehousing", "moveSettings", L["Move Quantity Options"], L["Set how items are moved out of the bank."])
|
||||
:AddChild(private.CreateEnabledSettingLine("moveQuantity", L["Set move quantity"], L["Quantity to move"], 0, 50000, true))
|
||||
:AddChild(private.CreateEnabledSettingLine("stackSize", L["Set stack size"], L["Stack size multiple"], 0, 200, true))
|
||||
:AddChild(private.CreateEnabledSettingLine("keepBagQuantity", L["Set keep in bags quantity"], L["Keep in bags quantity"], 0, 50000, true))
|
||||
:AddChild(private.CreateEnabledSettingLine("keepBankQuantity", L["Set keep in bank quantity"], L["Keep in bank quantity"], 0, 50000))
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateExpandableSection("Warehousing", "restockSettings", L["Restock Options"], L["Set how items are restocked from the bank."])
|
||||
:AddChild(private.CreateEnabledSettingLine("restockQuantity", L["Enable restock"], L["Restock quantity"], 0, 50000, true))
|
||||
:AddChild(private.CreateEnabledSettingLine("restockStackSize", L["Set stack size for restock"], L["Stack size multiple"], 0, 200, true))
|
||||
:AddChild(private.CreateEnabledSettingLine("restockKeepBankQuantity", L["Set keep in bank quantity"], L["Keep in bank quantity"], 0, 50000))
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.GetOperationManagementElements("Warehousing", private.currentOperationName))
|
||||
end
|
||||
|
||||
function private.CreateEnabledSettingLine(key, enableText, text, minValue, maxValue, margin)
|
||||
local operation = TSM.Operations.GetSettings("Warehousing", private.currentOperationName)
|
||||
local hasRelationship = TSM.Operations.HasRelationship("Warehousing", private.currentOperationName, key)
|
||||
return UIElements.New("Frame", "content")
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(TSM.MainUI.Operations.CreateLinkedSettingLine(key, text)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:AddChild(UIElements.New("ToggleOnOff", "toggle")
|
||||
:SetHeight(18)
|
||||
:SetValue(operation[key] ~= 0)
|
||||
:SetDisabled(hasRelationship)
|
||||
:SetContext(key)
|
||||
:SetScript("OnValueChanged", private.EnabledSettingEnableOnValueChanged)
|
||||
)
|
||||
)
|
||||
:AddChild(TSM.MainUI.Operations.CreateSettingLine("content", text, hasRelationship or operation[key] == 0)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetHeight(48)
|
||||
:SetMargin(0, 0, 0, margin and 12 or 4)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc("NUMBER", minValue..":"..maxValue)
|
||||
:SetSettingInfo(operation, key)
|
||||
:SetDisabled(hasRelationship or operation[key] == 0)
|
||||
)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth("AUTO")
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetTextColor((hasRelationship or operation[key] == 0) and "TEXT_DISABLED" or "TEXT")
|
||||
:SetFormattedText(L["Enter a value from %d - %d"], minValue, maxValue)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.EnabledSettingEnableOnValueChanged(toggle, value)
|
||||
local key = toggle:GetContext()
|
||||
local operation = TSM.Operations.GetSettings("Warehousing", private.currentOperationName)
|
||||
operation[key] = value and 1 or 0
|
||||
local settingFrame = toggle:GetElement("__parent.__parent.content")
|
||||
settingFrame:GetElement("label")
|
||||
:SetTextColor(value and "TEXT" or "TEXT_DISABLED")
|
||||
settingFrame:GetElement("content.input")
|
||||
:SetDisabled(not value)
|
||||
:SetValue(operation[key])
|
||||
settingFrame:GetElement("content.label")
|
||||
:SetTextColor(value and "TEXT" or "TEXT_DISABLED")
|
||||
settingFrame:Draw()
|
||||
end
|
||||
105
Core/UI/MainUI/Settings/Accounting.lua
Normal file
105
Core/UI/MainUI/Settings/Accounting.lua
Normal 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
|
||||
182
Core/UI/MainUI/Settings/Appearance.lua
Normal file
182
Core/UI/MainUI/Settings/Appearance.lua
Normal 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
|
||||
225
Core/UI/MainUI/Settings/Auctioning.lua
Normal file
225
Core/UI/MainUI/Settings/Auctioning.lua
Normal 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
|
||||
287
Core/UI/MainUI/Settings/Core.lua
Normal file
287
Core/UI/MainUI/Settings/Core.lua
Normal file
@@ -0,0 +1,287 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local _, TSM = ...
|
||||
local Settings = TSM.MainUI:NewPackage("Settings")
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Wow = TSM.Include("Util.Wow")
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
local private = {
|
||||
settingPages = {
|
||||
top = {},
|
||||
middle = {},
|
||||
bottom = {},
|
||||
},
|
||||
callback = {},
|
||||
childSettingsPages = {},
|
||||
sectionCollapsed = {},
|
||||
}
|
||||
local SECTIONS = { "top", "middle" }
|
||||
local SETTING_PATH_SEP = "`"
|
||||
local SETTING_LABEL_WIDTH = 400
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Module Functions
|
||||
-- ============================================================================
|
||||
|
||||
function Settings.OnInitialize()
|
||||
TSM.MainUI.RegisterTopLevelPage(L["Settings"], private.GetSettingsFrame)
|
||||
end
|
||||
|
||||
function Settings.RegisterSettingPage(name, section, callback)
|
||||
assert(tContains(SECTIONS, section))
|
||||
tinsert(private.settingPages[section], name)
|
||||
private.callback[name] = callback
|
||||
end
|
||||
|
||||
function Settings.RegisterChildSettingPage(parentName, childName, callback)
|
||||
local path = parentName..SETTING_PATH_SEP..childName
|
||||
private.childSettingsPages[parentName] = private.childSettingsPages[parentName] or {}
|
||||
tinsert(private.childSettingsPages[parentName], childName)
|
||||
private.callback[path] = callback
|
||||
end
|
||||
|
||||
function Settings.CreateSettingLine(id, labelText, width)
|
||||
width = width or SETTING_LABEL_WIDTH
|
||||
|
||||
return UIElements.New("Frame", id)
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(26)
|
||||
:SetMargin(0, 0, 0, 16)
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetWidth(width)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(labelText)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.CreateHeading(id, text)
|
||||
return UIElements.New("Text", id)
|
||||
:SetHeight(19)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:SetFont("BODY_BODY1_BOLD")
|
||||
:SetText(text)
|
||||
end
|
||||
|
||||
function Settings.CreateInputWithReset(id, label, context, validate)
|
||||
local scope, namespace, key = strsplit(".", context)
|
||||
local validateFunc, validateContext = nil, nil
|
||||
if type(validate) == "table" then
|
||||
validateFunc = "CUSTOM_PRICE"
|
||||
validateContext = validate
|
||||
elseif type(validate) == "function" then
|
||||
validateFunc = validate
|
||||
elseif validate == nil then
|
||||
validateFunc = "CUSTOM_PRICE"
|
||||
else
|
||||
error("Invalid validate: "..tostring(validate))
|
||||
end
|
||||
return UIElements.New("Frame", id)
|
||||
:SetLayout("VERTICAL")
|
||||
:AddChild(UIElements.New("Text", "label")
|
||||
:SetHeight(18)
|
||||
:SetMargin(0, 0, 0, 4)
|
||||
:SetFont("BODY_BODY2_MEDIUM")
|
||||
:SetTextColor("TEXT_ALT")
|
||||
:SetText(label)
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "content")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Input", "input")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetBackgroundColor("ACTIVE_BG")
|
||||
:SetValidateFunc(validateFunc, validateContext)
|
||||
:SetSettingInfo(TSM.db[scope][namespace], key)
|
||||
:SetScript("OnValueChanged", private.InputOnValueChanged)
|
||||
)
|
||||
:AddChild(UIElements.New("ActionButton", "resetButton")
|
||||
:SetWidth(108)
|
||||
:SetText(L["Reset"])
|
||||
:SetDisabled(TSM.db[scope][namespace][key] == TSM.db:GetDefault(scope, namespace, key))
|
||||
:SetScript("OnClick", private.ResetBtnOnClick)
|
||||
:SetContext(context)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.CreateExpandableSection(pageName, id, text, description, descriptionHeight)
|
||||
return UIElements.New("CollapsibleContainer", id)
|
||||
:SetLayout("VERTICAL")
|
||||
:SetMargin(0, 0, 0, 8)
|
||||
:SetContextTable(private.sectionCollapsed, pageName..text)
|
||||
:SetHeadingText(text)
|
||||
:AddChild(UIElements.New("Text", "description")
|
||||
:SetHeight(descriptionHeight or 20)
|
||||
:SetMargin(0, 0, 0, 12)
|
||||
:SetFont("BODY_BODY3")
|
||||
:SetText(description)
|
||||
)
|
||||
end
|
||||
|
||||
function Settings.PromptToReload()
|
||||
StaticPopupDialogs["TSMReloadPrompt"] = StaticPopupDialogs["TSMReloadPrompt"] or {
|
||||
text = L["You must reload your UI for these settings to take effect. Reload now?"],
|
||||
button1 = YES,
|
||||
button2 = NO,
|
||||
timeout = 0,
|
||||
OnAccept = ReloadUI,
|
||||
}
|
||||
Wow.ShowStaticPopupDialog("TSMReloadPrompt")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Settings UI
|
||||
-- ============================================================================
|
||||
|
||||
function private.GetSettingsFrame()
|
||||
TSM.UI.AnalyticsRecordPathChange("main", "settings")
|
||||
local defaultPage = private.settingPages.top[1]
|
||||
|
||||
local frame = UIElements.New("Frame", "settings")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetBackgroundColor("PRIMARY_BG_ALT")
|
||||
:AddChild(UIElements.New("Frame", "settingNavigation")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetWidth(160)
|
||||
:SetPadding(12, 12, 1, 9)
|
||||
:AddChild(UIElements.New("Frame", "top")
|
||||
:SetLayout("VERTICAL")
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "vline")
|
||||
:SetHeight(1)
|
||||
:SetMargin(0, 0, 8, 8)
|
||||
:SetTexture("ACTIVE_BG_ALT")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "middle")
|
||||
:SetLayout("VERTICAL")
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer")
|
||||
-- make all the navigation align to the top
|
||||
)
|
||||
)
|
||||
:AddChild(UIElements.New("Texture", "divider")
|
||||
:SetWidth(2)
|
||||
:SetTexture("ACTIVE_BG")
|
||||
)
|
||||
:AddChild(UIElements.New("Frame", "contentFrame")
|
||||
:SetLayout("VERTICAL")
|
||||
:SetBackgroundColor("PRIMARY_BG")
|
||||
:AddChild(UIElements.New("ViewContainer", "content")
|
||||
:SetNavCallback(private.ContentNavCallback)
|
||||
)
|
||||
)
|
||||
|
||||
local content = frame:GetElement("contentFrame.content")
|
||||
local settingNav = frame:GetElement("settingNavigation")
|
||||
for _, location in ipairs(SECTIONS) do
|
||||
local navFrame = settingNav:GetElement(location)
|
||||
for _, settingName in ipairs(private.settingPages[location]) do
|
||||
navFrame:AddChild(UIElements.New("Button", settingName)
|
||||
:SetHeight(20)
|
||||
:SetMargin(0, 0, 8, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(settingName)
|
||||
:SetText(settingName)
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(settingName, settingName == defaultPage)
|
||||
if private.childSettingsPages[settingName] then
|
||||
for _, childSettingName in ipairs(private.childSettingsPages[settingName]) do
|
||||
local path = settingName..SETTING_PATH_SEP..childSettingName
|
||||
navFrame:AddChild(UIElements.New("Button", path)
|
||||
:SetHeight(20)
|
||||
:SetMargin(9, 0, 8, 0)
|
||||
:SetFont("BODY_BODY3_MEDIUM")
|
||||
:SetJustifyH("LEFT")
|
||||
:SetContext(path)
|
||||
:SetText(strupper(childSettingName))
|
||||
:SetScript("OnClick", private.NavButtonOnClick)
|
||||
)
|
||||
content:AddPath(path, path == defaultPage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
private.UpdateNavFrame(settingNav, defaultPage)
|
||||
return frame
|
||||
end
|
||||
|
||||
function private.ContentNavCallback(content, path)
|
||||
return private.callback[path]()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Local Script Handlers
|
||||
-- ============================================================================
|
||||
|
||||
function private.NavButtonOnClick(button)
|
||||
local path = button:GetContext()
|
||||
if private.childSettingsPages[path] then
|
||||
-- select the first child
|
||||
path = path..SETTING_PATH_SEP..private.childSettingsPages[path][1]
|
||||
end
|
||||
|
||||
local contentFrame = button:GetElement("__parent.__parent.__parent.contentFrame")
|
||||
local navFrame = contentFrame:GetElement("__parent.settingNavigation")
|
||||
private.UpdateNavFrame(navFrame, path)
|
||||
navFrame:Draw()
|
||||
contentFrame:GetElement("content"):SetPath(path, true)
|
||||
end
|
||||
|
||||
function private.InputOnValueChanged(input)
|
||||
local button = input:GetElement("__parent.resetButton")
|
||||
local scope, namespace, key = strsplit(".", button:GetContext())
|
||||
button:SetDisabled(TSM.db[scope][namespace][key] == TSM.db:GetDefault(scope, namespace, key))
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function private.ResetBtnOnClick(button)
|
||||
local scope, namespace, key = strsplit(".", button:GetContext())
|
||||
local defaultValue = TSM.db:GetDefault(scope, namespace, key)
|
||||
TSM.db:Set(scope, nil, namespace, key, defaultValue)
|
||||
button:GetElement("__parent.input")
|
||||
:SetValue(defaultValue)
|
||||
:Draw()
|
||||
button:SetDisabled(true)
|
||||
:Draw()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.UpdateNavFrame(navFrame, selectedPath)
|
||||
local selectedSetting = strsplit(SETTING_PATH_SEP, selectedPath)
|
||||
for _, location in ipairs(SECTIONS) do
|
||||
for _, settingName in ipairs(private.settingPages[location]) do
|
||||
navFrame:GetElement(location ..".".. settingName)
|
||||
:SetTextColor(settingName == selectedSetting and "TEXT" or "ACTIVE_BG_ALT")
|
||||
if private.childSettingsPages[settingName] then
|
||||
for _, childSettingName in ipairs(private.childSettingsPages[settingName]) do
|
||||
local path = settingName..SETTING_PATH_SEP..childSettingName
|
||||
if settingName == selectedSetting then
|
||||
navFrame:GetElement(location ..".".. path)
|
||||
:SetTextColor(path == selectedPath and "INDICATOR" or "TEXT")
|
||||
:Show()
|
||||
else
|
||||
navFrame:GetElement(location ..".".. path):Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
142
Core/UI/MainUI/Settings/Crafting.lua
Normal file
142
Core/UI/MainUI/Settings/Crafting.lua
Normal 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
|
||||
297
Core/UI/MainUI/Settings/CustomSources.lua
Normal file
297
Core/UI/MainUI/Settings/CustomSources.lua
Normal 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
|
||||
122
Core/UI/MainUI/Settings/Destroying.lua
Normal file
122
Core/UI/MainUI/Settings/Destroying.lua
Normal 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
|
||||
672
Core/UI/MainUI/Settings/General.lua
Normal file
672
Core/UI/MainUI/Settings/General.lua
Normal 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
|
||||
270
Core/UI/MainUI/Settings/Macros.lua
Normal file
270
Core/UI/MainUI/Settings/Macros.lua
Normal 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
|
||||
167
Core/UI/MainUI/Settings/Mailing.lua
Normal file
167
Core/UI/MainUI/Settings/Mailing.lua
Normal 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
|
||||
168
Core/UI/MainUI/Settings/Shopping.lua
Normal file
168
Core/UI/MainUI/Settings/Shopping.lua
Normal 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
|
||||
395
Core/UI/MainUI/Settings/Tooltip.lua
Normal file
395
Core/UI/MainUI/Settings/Tooltip.lua
Normal 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
|
||||
83
Core/UI/MainUI/Settings/Vendoring.lua
Normal file
83
Core/UI/MainUI/Settings/Vendoring.lua
Normal 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
|
||||
Reference in New Issue
Block a user