initial commit
This commit is contained in:
292
Core/UI/Elements/MultiselectionDropdown.lua
Normal file
292
Core/UI/Elements/MultiselectionDropdown.lua
Normal file
@@ -0,0 +1,292 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster --
|
||||
-- https://tradeskillmaster.com --
|
||||
-- All Rights Reserved - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
--- Multiselection Dropdown UI Element Class.
|
||||
-- A dropdown element allows the user to select from a dialog list. It is a subclass of the @{BaseDropdown} class.
|
||||
-- @classmod MultiselectionDropdown
|
||||
|
||||
local _, TSM = ...
|
||||
local L = TSM.Include("Locale").GetTable()
|
||||
local Table = TSM.Include("Util.Table")
|
||||
local Theme = TSM.Include("Util.Theme")
|
||||
local MultiselectionDropdown = TSM.Include("LibTSMClass").DefineClass("MultiselectionDropdown", TSM.UI.BaseDropdown)
|
||||
local UIElements = TSM.Include("UI.UIElements")
|
||||
UIElements.Register(MultiselectionDropdown)
|
||||
TSM.UI.MultiselectionDropdown = MultiselectionDropdown
|
||||
local private = {}
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Meta Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function MultiselectionDropdown.__init(self)
|
||||
self.__super:__init()
|
||||
self._itemIsSelected = {}
|
||||
self._settingTableDirect = nil
|
||||
self._text = self:_GetBaseFrame():CreateFontString()
|
||||
self._text:SetFont(Theme.GetFont("BODY_BODY3"):GetWowFont())
|
||||
self._text:Hide()
|
||||
self._noneSelectionText = L["None Selected"]
|
||||
self._partialSelectionText = L["%d Selected"]
|
||||
self._allSelectionText = L["All Selected"]
|
||||
end
|
||||
|
||||
function MultiselectionDropdown.Release(self)
|
||||
wipe(self._itemIsSelected)
|
||||
self._settingTableDirect = nil
|
||||
self._noneSelectionText = L["None Selected"]
|
||||
self._partialSelectionText = L["%d Selected"]
|
||||
self._allSelectionText = L["All Selected"]
|
||||
self.__super:Release()
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Public Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
--- Set whether the item is selected.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam string item The item
|
||||
-- @tparam boolean selected Whether or not the item should be selected
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetItemSelected(self, item, selected)
|
||||
self:_SetItemSelectedHelper(item, selected)
|
||||
if self._onSelectionChangedHandler then
|
||||
self:_onSelectionChangedHandler()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set whether the item is selected by key.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam string itemKey The key for the item
|
||||
-- @tparam boolean selected Whether or not the item should be selected
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetItemSelectedByKey(self, itemKey, selected)
|
||||
self:SetItemSelected(Table.GetDistinctKey(self._itemKeyLookup, itemKey), selected)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the selected items.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam table selected A table where the keys are the items to be selected
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetSelectedItems(self, selected)
|
||||
wipe(self._itemIsSelected)
|
||||
if self._settingTableDirect then
|
||||
wipe(self._settingTableDirect)
|
||||
end
|
||||
for _, item in ipairs(self._items) do
|
||||
self:_SetItemSelectedHelper(item, selected[item])
|
||||
end
|
||||
if self._onSelectionChangedHandler then
|
||||
self:_onSelectionChangedHandler()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the selected items.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam table selected A table where the keys are the items to be selected
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetSelectedItemKeys(self, selected)
|
||||
wipe(self._itemIsSelected)
|
||||
if self._settingTableDirect then
|
||||
wipe(self._settingTableDirect)
|
||||
end
|
||||
for _, item in ipairs(self._items) do
|
||||
self:_SetItemSelectedHelper(item, selected[self._itemKeyLookup[item]])
|
||||
end
|
||||
if self._onSelectionChangedHandler then
|
||||
self:_onSelectionChangedHandler()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the unselected items.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam table unselected A table where the keys are the items which aren't selected
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetUnselectedItemKeys(self, unselected)
|
||||
wipe(self._itemIsSelected)
|
||||
if self._settingTableDirect then
|
||||
wipe(self._settingTableDirect)
|
||||
end
|
||||
for _, item in ipairs(self._items) do
|
||||
self:_SetItemSelectedHelper(item, not unselected[self._itemKeyLookup[item]])
|
||||
end
|
||||
if self._onSelectionChangedHandler then
|
||||
self:_onSelectionChangedHandler()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get the currently selected item.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam string item The item
|
||||
-- @treturn ?string The selected item
|
||||
function MultiselectionDropdown.ItemIsSelected(self, item)
|
||||
return self._itemIsSelected[item]
|
||||
end
|
||||
|
||||
--- Get the currently selected item.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam string|number itemKey The key for the item
|
||||
-- @treturn boolean Whether or not the item is selected
|
||||
function MultiselectionDropdown.ItemIsSelectedByKey(self, itemKey)
|
||||
return self:ItemIsSelected(Table.GetDistinctKey(self._itemKeyLookup, itemKey))
|
||||
end
|
||||
|
||||
--- Sets the setting info.
|
||||
-- This method is used to have the selected keys of the dropdown automatically correspond with the value of a field in a
|
||||
-- table. This is useful for dropdowns which are tied directly to settings.
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam table tbl The table which the field to set belongs to
|
||||
-- @tparam string key The key into the table to be set based on the dropdown state
|
||||
-- @treturn MultiselectionDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetSettingInfo(self, tbl, key)
|
||||
local directTbl = tbl[key]
|
||||
assert(type(directTbl) == "table")
|
||||
-- this function wipes our settingTable, so set the selected items first
|
||||
self:SetSelectedItemKeys(directTbl)
|
||||
self._settingTableDirect = directTbl
|
||||
return self
|
||||
end
|
||||
|
||||
--- Populate the specified table with a list of selected items
|
||||
-- @tparam MultiselectionDropdown self The dropdown object
|
||||
-- @tparam table resultTbl The table to populate
|
||||
function MultiselectionDropdown.GetSelectedItems(self, resultTbl)
|
||||
for _, item in ipairs(self._items) do
|
||||
if self:ItemIsSelected(item) then
|
||||
tinsert(resultTbl, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets the selection text which is shown to summarize the current value.
|
||||
-- @tparam BaseDropdown self The dropdown object
|
||||
-- @tparam string noneText The selection text string when none are selected
|
||||
-- @tparam string partialText The selection text string for a partial selection
|
||||
-- @tparam string allText The selection text string when all are selected
|
||||
-- @treturn BaseDropdown The dropdown object
|
||||
function MultiselectionDropdown.SetSelectionText(self, noneText, partialText, allText)
|
||||
assert(type(partialText) == "string" and type(partialText) == "string" and type(allText) == "string")
|
||||
self._noneSelectionText = noneText
|
||||
self._partialSelectionText = partialText
|
||||
self._allSelectionText = allText
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Class Methods
|
||||
-- ============================================================================
|
||||
|
||||
function MultiselectionDropdown._GetDialogSize(self)
|
||||
local width, height = self.__super:_GetDialogSize()
|
||||
width = max(width + 12, 200) -- check icon, and big enough for select all / deselect all buttons
|
||||
height = height + 26 -- header + line
|
||||
return width, height
|
||||
end
|
||||
|
||||
function MultiselectionDropdown._GetNumSelected(self)
|
||||
local num = 0
|
||||
for _, item in ipairs(self._items) do
|
||||
if self:ItemIsSelected(item) then
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
return num
|
||||
end
|
||||
|
||||
function MultiselectionDropdown._AddDialogChildren(self, frame)
|
||||
local numSelected = self:_GetNumSelected()
|
||||
frame:AddChild(UIElements.New("Frame", "header")
|
||||
:SetLayout("HORIZONTAL")
|
||||
:SetPadding(8, 8, 2, 2)
|
||||
:SetHeight(24)
|
||||
:AddChild(UIElements.New("Button", "selectAll")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetTextColor(numSelected == #self._items and "ACTIVE_BG_ALT" or "TEXT")
|
||||
:SetDisabled(numSelected == #self._items)
|
||||
:SetText(L["Select All"])
|
||||
:SetScript("OnClick", private.SelectAllOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Button", "deselectAll")
|
||||
:SetWidth("AUTO")
|
||||
:SetMargin(0, 8, 0, 0)
|
||||
:SetFont("BODY_BODY2_BOLD")
|
||||
:SetTextColor(numSelected == 0 and "ACTIVE_BG_ALT" or "TEXT")
|
||||
:SetDisabled(numSelected == 0)
|
||||
:SetText(L["Deselect All"])
|
||||
:SetScript("OnClick", private.DeselectAllOnClick)
|
||||
)
|
||||
:AddChild(UIElements.New("Spacer", "spacer"))
|
||||
)
|
||||
frame:AddChild(UIElements.New("Texture", "line")
|
||||
:SetHeight(2)
|
||||
:SetTexture("ACTIVE_BG_ALT")
|
||||
)
|
||||
frame:AddChild(UIElements.New("DropdownList", "list")
|
||||
:SetMultiselect(true)
|
||||
:SetItems(self._items, self._itemIsSelected)
|
||||
)
|
||||
end
|
||||
|
||||
function MultiselectionDropdown._GetCurrentSelectionString(self)
|
||||
local numSelected = self:_GetNumSelected()
|
||||
local result = nil
|
||||
if numSelected == 0 then
|
||||
result = self._hintText ~= "" and self._hintText or self._noneSelectionText
|
||||
elseif numSelected == #self._items then
|
||||
result = self._allSelectionText.." ("..numSelected..")"
|
||||
else
|
||||
result = format(self._partialSelectionText, numSelected)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function MultiselectionDropdown._OnListSelectionChanged(self, dropdownList, selection)
|
||||
self:SetSelectedItems(selection)
|
||||
local numSelected = self:_GetNumSelected()
|
||||
dropdownList:GetElement("__parent.header.selectAll")
|
||||
:SetTextColor(numSelected == #self._items and "ACTIVE_BG_ALT" or "TEXT")
|
||||
:SetDisabled(numSelected == #self._items)
|
||||
:Draw()
|
||||
dropdownList:GetElement("__parent.header.deselectAll")
|
||||
:SetTextColor(numSelected == 0 and "ACTIVE_BG_ALT" or "TEXT")
|
||||
:SetDisabled(numSelected == 0)
|
||||
:Draw()
|
||||
end
|
||||
|
||||
function MultiselectionDropdown._SetItemSelectedHelper(self, item, selected)
|
||||
self._itemIsSelected[item] = selected and true or nil
|
||||
if self._settingTableDirect then
|
||||
self._settingTableDirect[self._itemKeyLookup[item]] = self._itemIsSelected[item]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Private Helper Functions
|
||||
-- ============================================================================
|
||||
|
||||
function private.SelectAllOnClick(button)
|
||||
button:GetElement("__parent.__parent.list"):SelectAll()
|
||||
end
|
||||
|
||||
function private.DeselectAllOnClick(button)
|
||||
button:GetElement("__parent.__parent.list"):DeselectAll()
|
||||
end
|
||||
Reference in New Issue
Block a user