868 lines
31 KiB
Lua
868 lines
31 KiB
Lua
|
-- ------------------------------------------------------------------------------ --
|
||
|
-- 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
|