You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
14 KiB
362 lines
14 KiB
local _, S = ...
|
|
local pairs, ipairs, string, type, time = pairs, ipairs, string, type, time
|
|
|
|
S.Dropdown = {}
|
|
|
|
local ENTRY_HEIGHT = 24
|
|
local MAX_HEIGHT = 400
|
|
|
|
-- Make a frame just below the dropdown menu that fills the screen
|
|
-- When clicked it hides the dropdown menu
|
|
-- Essentially adds GLOBAL_MOUSE_DOWN functionality to Classic
|
|
local screen = CreateFrame("FRAME", nil, UIParent)
|
|
screen:SetFrameStrata("DIALOG")
|
|
screen:SetFrameLevel(1)
|
|
screen:SetAllPoints()
|
|
screen:SetScript("OnMouseDown", function(self)
|
|
SortedDropdownMenu:Hide()
|
|
self:Hide()
|
|
end)
|
|
screen:Hide()
|
|
|
|
local dropdownMenu = CreateFrame("FRAME", "SortedDropdownMenu", UIParent)
|
|
S.dropdownMenu = dropdownMenu
|
|
table.insert(UISpecialFrames, "SortedDropdownMenu")
|
|
dropdownMenu:SetFrameStrata("DIALOG")
|
|
dropdownMenu:SetFrameLevel(10)
|
|
dropdownMenu:SetClampedToScreen(true)
|
|
dropdownMenu:SetScript("OnShow", function(self)
|
|
screen:Show()
|
|
end)
|
|
dropdownMenu:SetScript("OnHide", function(self)
|
|
screen:Hide()
|
|
end)
|
|
|
|
function dropdownMenu:UpdateScale()
|
|
dropdownMenu:SetScale(S.Settings.Get("scale"))
|
|
end
|
|
S.Utils.RunOnEvent(dropdownMenu, "SettingChanged-scale", dropdownMenu.UpdateScale)
|
|
|
|
dropdownMenu.scrollFrame = CreateFrame("SCROLLFRAME", nil, dropdownMenu)
|
|
dropdownMenu.scrollFrame:SetPoint("TOPLEFT")
|
|
dropdownMenu.scrollFrame:SetPoint("BOTTOM")
|
|
dropdownMenu.content = CreateFrame("FRAME", nil, dropdownMenu.scrollFrame)
|
|
dropdownMenu.scrollFrame:SetScrollChild(dropdownMenu.content)
|
|
dropdownMenu.scrollBar = CreateFrame("Slider", nil, dropdownMenu.scrollFrame, "MinimalScrollBarTemplate")
|
|
dropdownMenu.scrollBar.trackBG:Hide()
|
|
dropdownMenu.scrollBar:SetPoint("TOPLEFT", dropdownMenu.scrollFrame, "TOPRIGHT", 1, -18)
|
|
dropdownMenu.scrollBar:SetPoint("BOTTOM", 0, 16)
|
|
dropdownMenu.scrollBar:SetMinMaxValues(1, 1)
|
|
dropdownMenu.scrollBar:SetValueStep(1)
|
|
dropdownMenu.scrollBar.scrollStep = 16
|
|
dropdownMenu.scrollBar:SetValue(0)
|
|
|
|
local inset = 6
|
|
local outset = 4
|
|
dropdownMenu.bg = dropdownMenu:CreateTexture()
|
|
dropdownMenu.bg:SetPoint("TOPLEFT", inset, -inset)
|
|
dropdownMenu.bg:SetPoint("BOTTOMRIGHT", -inset, inset)
|
|
dropdownMenu.bg:SetTexture("Interface\\Addons\\Sorted\\Textures\\Dropdown-Border")
|
|
dropdownMenu.bg:SetTexCoord(0.49,0.5,0.49,0.5)
|
|
--dropdownMenu.bg:SetColorTexture(0.04, 0.034, 0.035, 0.95)
|
|
|
|
S.FrameTools.AddBorder(dropdownMenu, "border", "Interface\\Addons\\Sorted\\Textures\\Dropdown-Border", inset, outset)
|
|
dropdownMenu.border:SetFrameLevel(dropdownMenu:GetFrameLevel() - 1)
|
|
--[[for k,v in pairs(dropdownMenu.border.parts) do
|
|
v:SetVertexColor(S.Utils.GetButtonTextColor())
|
|
end]]
|
|
|
|
-- Original border, with textures rather than solid colour
|
|
--[[dropdownMenu.bg:SetTexture("Interface\\Addons\\Sorted\\Textures\\Abstract", "REPEAT", "REPEAT")
|
|
dropdownMenu.bg:SetHorizTile(true)
|
|
dropdownMenu.bg:SetVertTile(true)
|
|
dropdownMenu.bg:SetAllPoints()
|
|
dropdownMenu:EnableMouse()
|
|
dropdownMenu:SetScript("OnEnter", function(self) end)
|
|
|
|
S.FrameTools.AddBorder(dropdownMenu, "border", "Interface\\Addons\\Sorted\\Textures\\Dropdown-Border", 10, 8)
|
|
S.FrameTools.AddInnerShadow(dropdownMenu, 16)
|
|
dropdownMenu.border:SetFrameLevel(dropdownMenu:GetFrameLevel() + 15)
|
|
S.Utils.RunOnEvent(dropdownMenu, "SettingChanged-backdrop", function(self, event, setting, value)
|
|
if setting == "backdrop" then
|
|
self.bg:SetTexture(S.Utils.GetBackgroundPath(value))
|
|
elseif setting == "backdropColor" then
|
|
self.bg:SetVertexColor(unpack(value))
|
|
end
|
|
end)]]
|
|
|
|
local function EntryOnEnter(self)
|
|
self:GetHighlightTexture():Show()
|
|
self.text:SetTextColor(self.textHighlightColor:GetRGB())
|
|
self.deleteButton:GetNormalTexture():SetTexCoord(0, 0.375, 0, 0.375)
|
|
end
|
|
local function EntryOnLeave(self)
|
|
self:GetHighlightTexture():Hide()
|
|
self.text:SetTextColor(self.textColor:GetRGB())
|
|
self.deleteButton:GetNormalTexture():SetTexCoord(0, 0.375, 0.375, 0.75)
|
|
end
|
|
local function EntryOnMouseWheel(self, delta)
|
|
dropdownMenu.scrollBar:SetValue(dropdownMenu.scrollBar:GetValue() - delta * 50)
|
|
end
|
|
|
|
dropdownMenu.entries = {}
|
|
local function CreateEntry()
|
|
local index = #dropdownMenu.entries + 1
|
|
local self = CreateFrame("BUTTON", nil, dropdownMenu.content)
|
|
self:SetPoint("TOPLEFT", 0, -index * ENTRY_HEIGHT + ENTRY_HEIGHT - 6)
|
|
self:SetPoint("BOTTOMRIGHT", dropdownMenu.content, "TOPRIGHT", 0, -index * ENTRY_HEIGHT - 6)
|
|
self:SetHighlightTexture("Interface\\Addons\\Sorted\\Textures\\Dropdown-Highlight")
|
|
self:GetHighlightTexture():SetVertexColor(0.9, 0.7, 0.04)
|
|
self:GetHighlightTexture():SetDrawLayer("ARTWORK")
|
|
self:GetHighlightTexture():Hide()
|
|
self:SetPushedTexture("Interface\\Addons\\Sorted\\Textures\\Dropdown-Highlight")
|
|
self:GetPushedTexture():SetVertexColor(0.9, 0.7, 0.04, 0.5)
|
|
self:GetPushedTexture():SetBlendMode("ADD")
|
|
self.text = self:CreateFontString(nil, "OVERLAY", "SortedFont")
|
|
self.text:SetPoint("LEFT", 8, 0)
|
|
self.rightText = self:CreateFontString(nil, "OVERLAY", "SortedFont")
|
|
self.rightText:SetPoint("RIGHT", -8, 0)
|
|
self.deleteButton = CreateFrame("BUTTON", nil, self)
|
|
self.deleteButton:SetSize(22, 22)
|
|
self.deleteButton:SetPoint("RIGHT", -2, 0)
|
|
self.deleteButton:SetNormalTexture("Interface\\Addons\\Sorted\\Textures\\Close-Button")
|
|
self.deleteButton:GetNormalTexture():SetTexCoord(0, 0.375, 0.375, 0.75)
|
|
self.deleteButton:SetHighlightTexture("Interface\\Addons\\Sorted\\Textures\\Close-Button-Highlight")
|
|
self.deleteButton:SetPushedTexture("Interface\\Addons\\Sorted\\Textures\\Close-Button")
|
|
self.deleteButton:GetPushedTexture():SetTexCoord(0.375, 0.75, 0, 0.375)
|
|
self.deleteButton:SetScript("OnEnter", function(self)
|
|
S.Tooltip.CreateLocalized(self, "ANCHOR_RIGHT", self.tooltip, S.GetData(self.data1).name)
|
|
self:GetNormalTexture():SetTexCoord(0, 0.375, 0, 0.375)
|
|
end)
|
|
self.deleteButton:SetScript("OnLeave", function(self)
|
|
S.Tooltip.Cancel()
|
|
if not self:GetParent():IsMouseOver() then
|
|
self:GetNormalTexture():SetTexCoord(0, 0.375, 0.375, 0.75)
|
|
end
|
|
end)
|
|
|
|
self.checkboxTexture = self:CreateTexture(nil, "OVERLAY")
|
|
self.checkboxTexture:SetTexture("Interface\\Addons\\Sorted\\Textures\\Checkbox-Tick")
|
|
self.checkboxTexture:SetPoint("LEFT", 8, 0)
|
|
self.checkboxTexture:SetSize(18, 18)
|
|
self.radioButtonTexture = self:CreateTexture(nil, "OVERLAY")
|
|
self.radioButtonTexture:SetTexture("Interface\\Addons\\Sorted\\Textures\\Radio-Button-Dot")
|
|
self.radioButtonTexture:SetTexCoord(0.1, 0.9, 0.1, 0.9)
|
|
self.radioButtonTexture:SetPoint("LEFT", 8, 0)
|
|
self.radioButtonTexture:SetSize(18, 18)
|
|
function self:SetChecked(checked)
|
|
self.checked = checked
|
|
if self.hasCheckbox then
|
|
if checked then
|
|
self.checkboxTexture:SetTexture("Interface\\Addons\\Sorted\\Textures\\Checkbox-Tick")
|
|
else
|
|
self.checkboxTexture:SetTexture("Interface\\Addons\\Sorted\\Textures\\Checkbox-Cross")
|
|
end
|
|
end
|
|
if self.hasRadioButton then
|
|
self.radioButtonTexture:SetShown(checked)
|
|
end
|
|
end
|
|
|
|
self:SetScript("OnMouseDown", function(self)
|
|
self.text:SetPoint("CENTER", 1, -1)
|
|
end)
|
|
self:SetScript("OnMouseUp", function(self)
|
|
self.text:SetPoint("CENTER")
|
|
end)
|
|
self:SetScript("OnEnter", EntryOnEnter)
|
|
self:SetScript("OnLeave", EntryOnLeave)
|
|
self:SetScript("OnClick", function(self)
|
|
if self.hasCheckbox then
|
|
self:SetChecked(not self.checked)
|
|
elseif self.hasRadioButton then
|
|
if not self.checked or not self.disableTogglingOff then
|
|
self:SetChecked(not self.checked)
|
|
for k,v in pairs(dropdownMenu.entries) do
|
|
if v.hasRadioButton and v ~= self then
|
|
v:SetChecked(false)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
dropdownMenu:Hide()
|
|
end
|
|
self.OnClick(self)
|
|
end)
|
|
self:SetScript("OnMouseWheel", EntryOnMouseWheel)
|
|
dropdownMenu.entries[index] = self
|
|
return self
|
|
end
|
|
|
|
|
|
local currentEntryIndex = 1
|
|
function S.Dropdown.Reset()
|
|
dropdownMenu.scrollPositionBeforeReset = dropdownMenu.scrollBar:GetValue()
|
|
currentEntryIndex = 1
|
|
for i, v in ipairs(dropdownMenu.entries) do
|
|
v:Hide()
|
|
end
|
|
end
|
|
|
|
function S.Dropdown.AddEntry(text, OnClick, data1, data2, color)
|
|
if not dropdownMenu.entries[currentEntryIndex] then
|
|
CreateEntry()
|
|
end
|
|
local entry = dropdownMenu.entries[currentEntryIndex]
|
|
entry:Show()
|
|
entry:SetScript("OnEnter", EntryOnEnter)
|
|
entry:SetScript("OnLeave", EntryOnLeave)
|
|
entry.text:SetPoint("LEFT", 8, 0)
|
|
entry.text:SetFont(S.Utils.GetFontPath(S.Settings.Get("font")), S.Settings.Get("fontSizePts"))
|
|
entry.rightText:SetText("")
|
|
entry.rightText:SetPoint("RIGHT", -8, 0)
|
|
entry.deleteButton:Hide()
|
|
entry.hasCheckbox = false
|
|
entry.checkboxTexture:Hide()
|
|
entry.hasRadioButton = false
|
|
entry.checked = false
|
|
entry.radioButtonTexture:Hide()
|
|
entry.text:SetText(text)
|
|
entry.data1 = data1
|
|
entry.data2 = data2
|
|
if not OnClick then
|
|
entry:Disable()
|
|
else
|
|
entry:Enable()
|
|
entry.OnClick = OnClick
|
|
end
|
|
if color then
|
|
entry:GetHighlightTexture():SetVertexColor(color:GetRGB())
|
|
entry:GetPushedTexture():SetVertexColor(color:GetRGB())
|
|
entry.text:SetTextColor(color:GetRGB())
|
|
entry.textColor = color
|
|
else
|
|
entry:GetHighlightTexture():SetVertexColor(0.9, 0.7, 0.04)
|
|
entry:GetPushedTexture():SetVertexColor(0.9, 0.7, 0.04)
|
|
entry.text:SetTextColor(1, 1, 1)
|
|
entry.textColor = CreateColor(1, 1, 1)
|
|
end
|
|
entry.textHighlightColor = CreateColor(entry.textColor.r + 0.4, entry.textColor.g + 0.4, entry.textColor.b + 0.4)
|
|
currentEntryIndex = currentEntryIndex + 1
|
|
end
|
|
function S.Dropdown.AddRightText(text)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry.rightText:SetText(text)
|
|
end
|
|
function S.Dropdown.AddDeleteButton(OnClick, data1, data2, tooltip)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry.rightText:SetPoint("RIGHT", -24, 0)
|
|
entry.deleteButton:Show()
|
|
entry.deleteButton.data1 = data1
|
|
entry.deleteButton.data2 = data2
|
|
entry.deleteButton:SetScript("OnClick", OnClick)
|
|
entry.deleteButton.tooltip = tooltip
|
|
end
|
|
function S.Dropdown.AddCheckbox(checked)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry.text:SetPoint("LEFT", 30, 0)
|
|
entry.hasCheckbox = true
|
|
entry.checkboxTexture:Show()
|
|
entry:SetChecked(checked)
|
|
end
|
|
function S.Dropdown.AddRadioButton(checked, disableTogglingOff)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry.text:SetPoint("LEFT", 30, 0)
|
|
entry.hasRadioButton = true
|
|
entry.checked = checked
|
|
entry.disableTogglingOff = disableTogglingOff
|
|
entry.radioButtonTexture:SetShown(checked)
|
|
end
|
|
function S.Dropdown.RestoreScrollPosition()
|
|
dropdownMenu.scrollBar:SetValue(dropdownMenu.scrollPositionBeforeReset)
|
|
end
|
|
function S.Dropdown.SetFont(font)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry.text:SetFont(S.Utils.GetFontPath(font), S.Settings.Get("fontSizePts"))
|
|
end
|
|
function S.Dropdown.OnEnter(func)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry:HookScript("OnEnter", func)
|
|
end
|
|
function S.Dropdown.OnLeave(func)
|
|
local entry = dropdownMenu.entries[currentEntryIndex - 1]
|
|
entry:HookScript("OnLeave", func)
|
|
end
|
|
|
|
|
|
function S.Dropdown.Show(parent, anchor, anchorTo, offsetX, offsetY)
|
|
dropdownMenu:ClearAllPoints()
|
|
dropdownMenu:SetPoint(anchor, parent, anchorTo, offsetX, offsetY)
|
|
dropdownMenu:SetFrameStrata("DIALOG")
|
|
dropdownMenu:SetHeight((currentEntryIndex - 1) * ENTRY_HEIGHT + 12)
|
|
dropdownMenu.content:SetHeight((currentEntryIndex - 1) * ENTRY_HEIGHT + 12)
|
|
local scrollBarShown = false
|
|
if dropdownMenu:GetHeight() > MAX_HEIGHT then
|
|
dropdownMenu.scrollBar:Show()
|
|
dropdownMenu.scrollBar:SetMinMaxValues(0, dropdownMenu:GetHeight() - MAX_HEIGHT)
|
|
dropdownMenu.scrollBar:SetValue(0)
|
|
dropdownMenu:SetHeight(MAX_HEIGHT)
|
|
scrollBarShown = true
|
|
else
|
|
dropdownMenu.scrollBar:SetMinMaxValues(0, 0)
|
|
dropdownMenu.scrollBar:Hide()
|
|
end
|
|
local width = 0
|
|
for i = 1,currentEntryIndex - 1 do
|
|
local entry = dropdownMenu.entries[i]
|
|
local entryWidth = entry.text:GetStringWidth() + entry.rightText:GetStringWidth()
|
|
if entry.deleteButton:IsShown() then
|
|
entryWidth = entryWidth + 24
|
|
end
|
|
if entry.hasCheckbox or entry.hasRadioButton then
|
|
entryWidth = entryWidth + 22
|
|
end
|
|
if entryWidth > width then
|
|
width = entryWidth
|
|
end
|
|
end
|
|
width = width + 24
|
|
dropdownMenu.scrollFrame:SetWidth(width)
|
|
dropdownMenu.content:SetWidth(width)
|
|
if scrollBarShown then
|
|
width = width + 24
|
|
end
|
|
dropdownMenu:SetWidth(width)
|
|
dropdownMenu:Show()
|
|
--dropdownMenu.shown = true
|
|
end
|
|
function S.Dropdown.IsShown()
|
|
return dropdownMenu:IsShown()
|
|
--return dropdownMenu.shown
|
|
end
|
|
function S.Dropdown.Hide()
|
|
dropdownMenu:Hide()
|
|
end
|
|
--[[dropdownMenu:SetScript("OnHide", function(self)
|
|
-- Set result of IsShown() to false on the next frame
|
|
-- This prevents GLOBAL_MOUSE_DOWN from hiding the dropdown menu on the same frame as something else toggles it, making it always toggle back to shown
|
|
C_Timer.After(0.0001, function()
|
|
self.shown = false
|
|
end)
|
|
end)]]
|
|
S.primaryFrame:HookScript("OnHide", function(self)
|
|
dropdownMenu:Hide()
|
|
end)
|
|
|
|
|
|
-- Hide when user clicks outside of the dropdown menu. (Now done with a fullscreen frame for compatibility with Classic)
|
|
--[[if S.WoWVersion() >= 3 then
|
|
dropdownMenu:RegisterEvent("GLOBAL_MOUSE_DOWN")
|
|
dropdownMenu:SetScript("OnEvent", function(self, event)
|
|
if S.Dropdown.IsShown() and event == "GLOBAL_MOUSE_DOWN" then
|
|
if not self:IsMouseOver() then
|
|
S.Dropdown.Hide()
|
|
end
|
|
end
|
|
end)
|
|
end]]
|
|
|
|
S.Dropdown.Reset()
|
|
|
|
|
|
dropdownMenu:Hide()
|