Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix][refactors]: Fix taint issues related UIDropDownMenu api usage #345

Merged
merged 3 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions LFGBulletinBoard/Chat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -145,24 +145,3 @@ function GBB.Announce()
GroupBulletinBoardFrameAnnounceMsg:ClearFocus()
end
end

function GBB.CreateChannelPulldown (frame, level, menuList)
if level~=1 then return end
local t= GBB.PhraseChannelList(GetChannelList())

local info = UIDropDownMenu_CreateInfo()


for i,channel in pairs(t) do
info.text = i..". "..channel.name
info.checked = (channel.name == GBB.DB.AnnounceChannel)
info.disabled = channel.hidden
info.arg1 = i
info.arg2 = channel.name
info.func = function(self, arg1, arg2, checked)
GBB.DB.AnnounceChannel=arg2
GroupBulletinBoardFrameSelectChannel:SetText(arg2)
end
UIDropDownMenu_AddButton(info)
end
end
44 changes: 24 additions & 20 deletions LFGBulletinBoard/GroupBulletinBoard.lua
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,6 @@ hooksecurefunc("SetItemRef", function(link)
end
end)

function GBB.BtnSelectChannel()
if UIDROPDOWNMENU_OPEN_MENU ~= GBB.FramePullDownChannel then
UIDropDownMenu_Initialize( GBB.FramePullDownChannel, GBB.CreateChannelPulldown, "MENU")
end
ToggleDropDownMenu(nil, nil, GBB.FramePullDownChannel, GroupBulletinBoardFrameSelectChannel, 0,0)
end

--gui
-------------------------------------------------------------------------------------

Expand Down Expand Up @@ -357,7 +350,7 @@ function GBB.BtnSettings(button )
if shouldOpen then
GBB.PopupDynamic:AddItem(FILTERS, false, GBB.OptionsBuilder.OpenCategoryPanel, 2)
GBB.PopupDynamic:AddItem(ALL_SETTINGS, false, GBB.OptionsBuilder.OpenCategoryPanel, 1)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"],false)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"], false, nil, nil, nil, true)
GBB.PopupDynamic:Show(GroupBulletinBoardFrameSettingsButton,0,0)
end
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION, "SFX")
Expand Down Expand Up @@ -539,7 +532,7 @@ function GBB.Popup_Minimap(frame,showMinimapOptions)
end
end
GBB.PopupDynamic:AddItem("",true)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"],false)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"], false, nil, nil, nil, true)

GBB.PopupDynamic:Show(frame,0,0)
end
Expand Down Expand Up @@ -705,18 +698,31 @@ function GBB.Init()
end
end,
GBB.Title
)

GBB.FramePullDownChannel=CreateFrame("Frame", "GBB.PullDownMenu", UIParent, "UIDropDownMenuTemplate")
)
GroupBulletinBoardFrameTitle:SetFontObject(GBB.DB.FontSize)

if GBB.DB.AnnounceChannel == nil then
if GBB.L["lfg_channel"] ~= "" then
GBB.DB.AnnounceChannel = GBB.L["lfg_channel"]
else
_, GBB.DB.AnnounceChannel = GetChannelList()
if GBB.L["lfg_channel"] ~= "" then GBB.DB.AnnounceChannel = GBB.L["lfg_channel"];
else GBB.DB.AnnounceChannel = select(2, GetChannelList()) end;
end
DropdownSelectionTextMixin.OnLoad(GroupBulletinBoardFrameSelectChannel)
GroupBulletinBoardFrameSelectChannel:SetSelectionTranslator(function(selection) return selection.data end)
GroupBulletinBoardFrameSelectChannel:SetupMenu(function(frame, rootDescription)
---@cast rootDescription RootMenuDescriptionProxy
local channelInfo = GBB.PhraseChannelList(GetChannelList())
local setting = GBB.OptionsBuilder.GetSavedVarHandle(GBB.DB, "AnnounceChannel");
local isSelected = function(channel) return channel == setting:GetValue() end
local setSelected = function(channel) setting:SetValue(channel) end
for i, channel in pairs(channelInfo) do
local button = rootDescription:CreateRadio(i..". "..channel.name, isSelected, setSelected, channel.name)
button:SetEnabled(not channel.hidden)
end
end

end)
--hack: early in addon loading process `GetChannelList` can return nil; re-generate the menu in these cases.
GroupBulletinBoardFrameSelectChannel:HookScript("OnShow", function(self)
if not self:GetText() then self:GenerateMenu() end;
end)

---@type EditBox # making this local isnt required, just here for the luals linter
local GroupBulletinBoardFrameResultsFilter = _G["GroupBulletinBoardFrameResultsFilter"];
GroupBulletinBoardFrameResultsFilter:SetParent(GroupBulletinBoardFrame_ScrollFrame)
Expand All @@ -741,8 +747,6 @@ function GBB.Init()
return self.filterPatterns
end

GroupBulletinBoardFrameSelectChannel:SetText(GBB.DB.AnnounceChannel)

GBB.ResizeFrameList()

if GBB.DB.EscapeQuit then
Expand Down
12 changes: 5 additions & 7 deletions LFGBulletinBoard/GroupBulletinBoard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@
</Button>

<!-- announcebox -->
<Button name="$parentSelectChannel" inherits="UIPanelButtonTemplate" text="channel">
<DropdownButton name="$parentSelectChannel" inherits="UIPanelButtonTemplate" text="channel" mixin="WowStyle1DropdownMixin">
<KeyValues>
<KeyValue key="menuMixin" value="MenuStyle2Mixin" type="global"/>
</KeyValues>
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" relativeTo="$parent" >
<Offset>
Expand All @@ -114,12 +117,7 @@
</Anchor>
</Anchors>
<Size><AbsDimension x="150" y="20" /></Size>
<Scripts>
<OnClick>
GroupBulletinBoard_Addon.BtnSelectChannel()
</OnClick>
</Scripts>
</Button>
</DropdownButton>

<Button name="$parentAnnounce" inherits="UIPanelButtonTemplate" text="Post">
<Anchors>
Expand Down
16 changes: 8 additions & 8 deletions LFGBulletinBoard/LfgToolList.lua
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,16 @@ local function createMenu(DungeonID,req) -- shared right-click menu for headers
return
end
if req then
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnWho"],req.name),false,WhoRequest,req.name)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnWhisper"],req.name),false,WhisperRequest,req.name)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnInvite"],req.name),false,InviteRequest,req.name)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnIgnore"],req.name),false,IgnoreRequest,req.name)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnWho"],req.name),false,WhoRequest,req.name,nil,true)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnWhisper"],req.name),false,WhisperRequest,req.name,nil,true)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnInvite"],req.name),false,InviteRequest,req.name,nil,true)
GBB.PopupDynamic:AddItem(string.format(GBB.L["BtnIgnore"],req.name),false,IgnoreRequest,req.name,nil,true)
GBB.PopupDynamic:AddItem("",true)
end
if DungeonID then
GBB.PopupDynamic:AddItem(GBB.L["BtnFold"], false, toggleHeaderCollapseByKey, DungeonID)
GBB.PopupDynamic:AddItem(GBB.L["BtnFoldAll"], false, setAllHeadersCollapsed, true)
GBB.PopupDynamic:AddItem(GBB.L["BtnUnFoldAll"], false, setAllHeadersCollapsed, false)
GBB.PopupDynamic:AddItem(GBB.L["BtnFold"], false, toggleHeaderCollapseByKey, DungeonID, nil, true)
GBB.PopupDynamic:AddItem(GBB.L["BtnFoldAll"], false, setAllHeadersCollapsed, true, nil, true)
GBB.PopupDynamic:AddItem(GBB.L["BtnUnFoldAll"], false, setAllHeadersCollapsed, false, nil, true)
GBB.PopupDynamic:AddItem("",true)
end
GBB.PopupDynamic:AddItem(GBB.L["CboxShowTotalTime"],false,GBB.DB,"ShowTotalTime")
Expand All @@ -345,7 +345,7 @@ local function createMenu(DungeonID,req) -- shared right-click menu for headers
GBB.PopupDynamic:AddItem(GBB.L["CboxRemoveRealm"],false,GBB.DB,"RemoveRealm")
GBB.PopupDynamic:AddItem("",true)
GBB.PopupDynamic:AddItem(SETTINGS, false, GBB.OptionsBuilder.OpenCategoryPanel, 1)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"],false)
GBB.PopupDynamic:AddItem(GBB.L["BtnCancel"], false, nil, nil, nil, true)
GBB.PopupDynamic:Show()
end
--------------------------------------------------------------------------------
Expand Down
106 changes: 44 additions & 62 deletions LFGBulletinBoard/LibGPIOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -512,86 +512,68 @@ end

---@param dbTable table
---@param key string
---@param default string|number|boolean
---@param default string|number|boolean
---@param menuButtons string[]|{value: string|number|boolean, text: string?}[]
function Options.AddDropdownToCurrentPanel(dbTable,key,default,menuButtons)
function Options.AddRadioDropdownToCurrentPanel(dbTable,key,default,menuButtons)
local frameIdx = Options.Frames.count + 1
Options.Frames.count = frameIdx
local dropdownName = Options.Prefix..'DropDownMenu'..frameIdx

---@class Dropdown: UIDropDownMenu, RegisteredFrameMixin, Frame
local dropdownFrame = CreateFrame('Frame', dropdownName, Options.CurrentPanel, 'UIDropDownMenuTemplate')
--note: defaulting for uninitialized saved vars now done in RegisterFrameWithSavedVar
local _, sVarHandle = Options.RegisterFrameWithSavedVar(dropdownFrame, dbTable, key, default)
dropdownFrame.Button:SetScript("OnMouseDown", function(self, button)
RegisteredFrame_OnShiftRightClick(dropdownFrame, button) -- Default on right-click of the dropdown toggle

---@class RadioDropdown: WowStyle1DropdownTemplate, RegisteredFrameMixin, Button
local dropdownButton = CreateFrame('DropdownButton', dropdownName, Options.CurrentPanel, 'WowStyle1DropdownTemplate')
dropdownButton:RegisterForMouse("AnyUp", "AnyDown")
dropdownButton:HookScript("OnMouseDown", function(self, button)
RegisteredFrame_OnShiftRightClick(dropdownButton, button) -- Default on right-click of the dropdown toggle
PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
end)

local maxWidth = 0; -- find widest button in the dropdown
local fontString = dropdownFrame:CreateFontString(nil, 'OVERLAY', 'GameFontNormal');

local maxWidth = 60; -- find widest button in the dropdown
for _, data in pairs(menuButtons) do
if type(data) == 'string' then
fontString:SetText(data);
dropdownButton.Text:SetText(data)
else
fontString:SetText(data.text or tostring(data.value));
dropdownButton.Text:SetText(data.text or tostring(data.value));
end
maxWidth = max(maxWidth, (fontString:GetStringWidth() + 20))
end
---@type fun(button: UIDropDownMenuButton) Dropdown menu button's on click handler
local dropdownButtonOnClick = function(button)
dropdownFrame:SetSavedValue(button.value)
UIDropDownMenu_SetSelectedValue(dropdownFrame, button.value)
UIDropDownMenu_SetText(dropdownFrame, button.text or button.value)
end
-- syncs dropdown display with the text that matches the passed value (expects the current saved variable)
local syncDropDownWithValue = function(value)
for _, data in pairs(menuButtons) do
if type(data) == 'string' and data == value then
UIDropDownMenu_SetText(dropdownFrame, data)
break;
elseif type(data) == 'table' and (data.value == value) then
UIDropDownMenu_SetText(dropdownFrame, data.text or data.value)
break;
maxWidth = max(maxWidth, (dropdownButton.Text:GetUnboundedStringWidth() + 20))
end
dropdownButton:SetWidth(maxWidth + (dropdownButton.Arrow and dropdownButton.Arrow:GetWidth() or 0));
-- Alternatively, use auto resize feature of the mixin
-- dropdownButton.resizeToText = true
-- dropdownButton.resizeToTextPadding = (dropdownButton.Arrow and dropdownButton.Arrow:GetWidth() or 0) + 20

-- Setup the dropdown menu radio button generator func
local _, setting = Options.RegisterFrameWithSavedVar(dropdownButton, dbTable, key, default)
local function isSelected(value) return value == setting:GetValue(); end
local function setSelected(value) setting:SetValue(value); end
local function menuGenerator(dropdown, rootDescription)
for index = 1, #menuButtons do
local info = menuButtons[index]
if type(info) == "table" then
rootDescription:CreateRadio(info.text or tostring(info.value), isSelected, setSelected, info.value);
else -- info == (value and display text)
rootDescription:CreateRadio(info, isSelected, setSelected, info);
end
end
end
UIDropDownMenu_SetWidth(dropdownFrame, maxWidth);
syncDropDownWithValue(dropdownFrame:GetSavedValue()); -- set initial text
sVarHandle:AddUpdateHook(syncDropDownWithValue)
-- Create and bind the initialization function to the dropdown menu
UIDropDownMenu_Initialize(dropdownFrame, function(self, level, menuList)
local buttonInfo = UIDropDownMenu_CreateInfo()
for _, buttonData in ipairs(menuButtons) do
if type(buttonData) == 'string' then
buttonInfo.text = buttonData
buttonInfo.value = buttonData
else
assert(buttonData.value ~= nil, 'data.value is required for button data table', 'data=q', buttonData);
for key, value in pairs(buttonData) do
buttonInfo[key] = value
end
buttonInfo.text = buttonData.text or tostring(buttonData.value)
end
buttonInfo.checked = function(button)
return dropdownFrame:GetSavedValue() == button.value
end
buttonInfo.func = dropdownButtonOnClick
UIDropDownMenu_AddButton(buttonInfo)
end
end)
local generateMenu = function() dropdownButton:SetupMenu(menuGenerator) end
setting:AddUpdateHook(generateMenu) -- syncs dropdown display when saved var externally updated
generateMenu() -- call once to initialize

local leftOffset, topOffset = 9, -4 -- tweaks to make up for bg texture
if not Options.inLine or not Options.LineRelativ then
dropdownFrame:SetPoint('TOPLEFT', Options.NextRelativ, 'BOTTOMLEFT', Options.NextRelativX, Options.NextRelativY)
Options.NextRelativ = dropdownName
Options.LineRelativ = dropdownName
dropdownButton:SetPoint('TOPLEFT', Options.NextRelativ, 'BOTTOMLEFT',
(Options.NextRelativX or 0) + leftOffset, (Options.NextRelativY or 0) + topOffset
);
Options.NextRelativ = dropdownButton.Background
Options.LineRelativ = dropdownButton.Background
Options.NextRelativX = 0
Options.NextRelativY = 0
else
dropdownFrame:SetPoint('TOP', Options.LineRelativ, 'TOP', 0, 0)
dropdownFrame:SetPoint('LEFT', Options.LineRelativ..'Text', 'RIGHT', 0, 3)
Options.LineRelativ = dropdownName
dropdownButton:SetPoint('TOP', Options.LineRelativ, 'TOP', 0, 0)
dropdownButton:SetPoint('LEFT', Options.LineRelativ..'Text', 'RIGHT', leftOffset, 3)
Options.LineRelativ = dropdownButton.Background
end
return dropdownFrame
return dropdownButton
end

---@param checkBox CheckButton|{Text: FontString, func: function}
Expand Down
Loading