Usually I use "info.checked = variable == 'value'" to simulate radio buttons with checkmarks within a dropdown menu.
Now, the problem is I want to set "info.keepShownOnClick = true" and find a way to refresh the checkmarks at the current menu level when an item is clicked.
Below is an ugly attempt to do this but it seems to conflict with the Blizzard's handling of checkmarks and only works half of the time.
[php]
local function SetOption(frame, var, val, checked)
config[var] = val or checked -- works with "radio" & "check"
-- ugly attempt to refresh checkmarks
local sub = strsub(frame:GetName(), 1, 19)
for i = 1, 5 do
local menuFrame = _G[ sub .. tostring(i) ]
local checkmark = _G[ sub .. tostring(i) .. "Check" ]
checkmark:SetTexture(menuFrame == frame and "Interface\\Buttons\\UI-CheckBox-Check" or "")
end
-- --> something to clear the menu lines
-- dropdown_init(nil, UIDROPDOWNMENU_MENU_LEVEL)
end
local options = {
{ text = format( "|cffffb366Ara|r Reputations (%s)", GetAddOnMetadata( "Ara_Broker_Reputations", "Version") ), isTitle = true },
{ text = "Block display", submenu = {
{ text = "ASCII Bar", var = "blockDisplay", type = "radio", val = "ascii", submenu = {
{ text = "Single Color", var = "asciiBar", type = "radio", val = "singleColor" },
{ text = "Dual Colors", var = "asciiBar", type = "radio", val = "dualColors" }, } },
{ text = "Text", var = "blockDisplay", type = "radio", val = "text", submenu = {
{ text = levels[6].." - 7500/12000 ", var = "textInfo", type = "radio", val = "standingValues" },
{ text = levels[6].." - 62%", var = "textInfo", type = "radio", val = "standingPerc" }, } } } },
{ text = "Tooltip bars", submenu = {
{ text = "Standard", var = "tipDisplay", type = "radio", val = "standard" },
{ text = "Double Wide", var = "tipDisplay", type = "radio", val = "doubleWide" } } },
{ text = "Hide Hints", var = "hideHints", type = "check" }
}
dropdown_init = function(self, level)
level = level or 1
for i, v in ipairs( level > 1 and UIDROPDOWNMENU_MENU_VALUE or options ) do
local info = UIDropDownMenu_CreateInfo()
info.text = v.text
info.isTitle = v.isTitle
if v.type == "radio" then
info.checked = config[v.var] == v.val
info.func, info.arg1, info.arg2 = SetOption, v.var, v.val
info.keepShownOnClick = true -- TRY
elseif v.type == "check" then
info.checked = config[v.var]
info.func, info.arg1 = SetOption, v.var
info.keepShownOnClick = true
end
info.hasArrow = v.submenu ~= nil
info.value = v.submenu
UIDropDownMenu_AddButton( info, level )
end
end
[/php]
Is there a way to clear the lines of the current menu level and call the dropdown init function to redraw the menu, or something clever ?
works for most of the radio button menus. Unfortunatly it doesn't work if a radio button has a sub-menu as shown below:
i don't have any code in front of me, but you can look at lilsparky's workshop. i have a rudimentary dropdown menu registration system in that. handles radio buttons and submenus, but it's not a dynamic system -- you register everything once, then build your menu table and call easymenu to open your menu over and over. from there, the menus are self-sustaining (they check/uncheck, handle callbacks, etc).
Is there a way to clear the lines of the current menu level and call the dropdown init function to redraw the menu, or something clever ?
Sorry for my bad explanations. :(
There is no such way to do it.
You have to manually get the button name/object of the menu item and :Show() and :Hide() the checkmark. My addon WoWEquip does this on the options for "Select all the above" and "Unselect all the above" menu options in the filter options for the menu.
The function looks like this:
[php]
function WoWEquip.SetFilterOptionsSelectAll(dropdownbutton, arg1, arg2, checked)
-- arg1 is whether to select all or unselect all
local i, j = string.match(dropdownbutton:GetName(), "DropDownList(%d+)Button(%d+)")
_G[dropdownbutton:GetName().."Check"]:Hide()
dropdownbutton.checked = false
for k = 2, j-(arg1 and 1 or 2) do
if arg1 then
_G["DropDownList"..i.."Button"..k.."Check"]:Show()
else
_G["DropDownList"..i.."Button"..k.."Check"]:Hide()
end
local b = _G["DropDownList"..i.."Button"..k]
b.checked = arg1
WoWEquip.db.global.EquipFilters[b.arg1] = arg1
end
local inputBox = WoWEquip.EquipFrame.InputBox
inputBox:SetScript("OnUpdate", inputBox.OnUpdate)
inputBox.time = GetTime()
end
[/php]
Thank you Xinhuan, you're always very helpful :) (although it's still ugly :p).
Well, there isn't any other way with UIDropDownMenu. The function "ugly hack" employed is still very small as compared to say using a dropdown library.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Now, the problem is I want to set "info.keepShownOnClick = true" and find a way to refresh the checkmarks at the current menu level when an item is clicked.
Below is an ugly attempt to do this but it seems to conflict with the Blizzard's handling of checkmarks and only works half of the time.
[php]
local function SetOption(frame, var, val, checked)
config[var] = val or checked -- works with "radio" & "check"
-- ugly attempt to refresh checkmarks
local sub = strsub(frame:GetName(), 1, 19)
for i = 1, 5 do
local menuFrame = _G[ sub .. tostring(i) ]
local checkmark = _G[ sub .. tostring(i) .. "Check" ]
checkmark:SetTexture(menuFrame == frame and "Interface\\Buttons\\UI-CheckBox-Check" or "")
end
-- --> something to clear the menu lines
-- dropdown_init(nil, UIDROPDOWNMENU_MENU_LEVEL)
end
local options = {
{ text = format( "|cffffb366Ara|r Reputations (%s)", GetAddOnMetadata( "Ara_Broker_Reputations", "Version") ), isTitle = true },
{ text = "Block display", submenu = {
{ text = "ASCII Bar", var = "blockDisplay", type = "radio", val = "ascii", submenu = {
{ text = "Single Color", var = "asciiBar", type = "radio", val = "singleColor" },
{ text = "Dual Colors", var = "asciiBar", type = "radio", val = "dualColors" }, } },
{ text = "Text", var = "blockDisplay", type = "radio", val = "text", submenu = {
{ text = levels[6].." - 7500/12000 ", var = "textInfo", type = "radio", val = "standingValues" },
{ text = levels[6].." - 62%", var = "textInfo", type = "radio", val = "standingPerc" }, } } } },
{ text = "Tooltip bars", submenu = {
{ text = "Standard", var = "tipDisplay", type = "radio", val = "standard" },
{ text = "Double Wide", var = "tipDisplay", type = "radio", val = "doubleWide" } } },
{ text = "Hide Hints", var = "hideHints", type = "check" }
}
dropdown_init = function(self, level)
level = level or 1
for i, v in ipairs( level > 1 and UIDROPDOWNMENU_MENU_VALUE or options ) do
local info = UIDropDownMenu_CreateInfo()
info.text = v.text
info.isTitle = v.isTitle
if v.type == "radio" then
info.checked = config[v.var] == v.val
info.func, info.arg1, info.arg2 = SetOption, v.var, v.val
info.keepShownOnClick = true -- TRY
elseif v.type == "check" then
info.checked = config[v.var]
info.func, info.arg1 = SetOption, v.var
info.keepShownOnClick = true
end
info.hasArrow = v.submenu ~= nil
info.value = v.submenu
UIDropDownMenu_AddButton( info, level )
end
end
[/php]
Is there a way to clear the lines of the current menu level and call the dropdown init function to redraw the menu, or something clever ?
Sorry for my bad explanations. :(
wrap your function call with a local function that handles this stuff for you since it'll have access to all the local variables of your menu.
personally, i tend to avoid the dynamic init system unless my menus are truly dynamic.
Can you throw some code, or an addon where you're doing that ? :p
EDIT: I found that
works for most of the radio button menus. Unfortunatly it doesn't work if a radio button has a sub-menu as shown below:
i don't have any code in front of me, but you can look at lilsparky's workshop. i have a rudimentary dropdown menu registration system in that. handles radio buttons and submenus, but it's not a dynamic system -- you register everything once, then build your menu table and call easymenu to open your menu over and over. from there, the menus are self-sustaining (they check/uncheck, handle callbacks, etc).
I want that checking a menu entry:
- keep the menu entry shown (keepShownOnClick = true)
- uncheck the other menu entries of this level
There is no such way to do it.
You have to manually get the button name/object of the menu item and :Show() and :Hide() the checkmark. My addon WoWEquip does this on the options for "Select all the above" and "Unselect all the above" menu options in the filter options for the menu.
The function looks like this:
[php]
function WoWEquip.SetFilterOptionsSelectAll(dropdownbutton, arg1, arg2, checked)
-- arg1 is whether to select all or unselect all
local i, j = string.match(dropdownbutton:GetName(), "DropDownList(%d+)Button(%d+)")
_G[dropdownbutton:GetName().."Check"]:Hide()
dropdownbutton.checked = false
for k = 2, j-(arg1 and 1 or 2) do
if arg1 then
_G["DropDownList"..i.."Button"..k.."Check"]:Show()
else
_G["DropDownList"..i.."Button"..k.."Check"]:Hide()
end
local b = _G["DropDownList"..i.."Button"..k]
b.checked = arg1
WoWEquip.db.global.EquipFilters[b.arg1] = arg1
end
local inputBox = WoWEquip.EquipFrame.InputBox
inputBox:SetScript("OnUpdate", inputBox.OnUpdate)
inputBox.time = GetTime()
end
[/php]
Well, there isn't any other way with UIDropDownMenu. The function "ugly hack" employed is still very small as compared to say using a dropdown library.