Thread Tools Display Modes
05-12-22, 07:08 AM   #1
nonexistentx_x
A Murloc Raider
 
nonexistentx_x's Avatar
Join Date: Mar 2019
Posts: 8
dropdown list layer

Hello. I found a nasty thing with my custom dropdown list in config element:
If dropdown list is shown, it is inferior to the next elements in terms of visibility priority (but not by frame strata):


But, if change list position to top, its shows fine:


I dont understand why this happens, I changed FrameStrata, FrameLevel, some frame parents, but no results...

create list:
Lua Code:
  1. -- create dropdown list
  2. local count = 0
  3. local function create_list(dropdown)
  4.     if dropdown.list then
  5.         return dropdown.list
  6.     end
  7.    
  8.     count = count + 1
  9.    
  10.     local name = parent..'_list'
  11.     local list = CreateFrame("Button", name .. count, dropdown)
  12.     list:SetFrameStrata("FULLSCREEN_DIALOG")
  13.     list:SetToplevel(true)
  14.     list:Raise()
  15.     list:Hide()
  16.    
  17.     list:set_point('TOPLEFT', dropdown, 'BOTTOMLEFT', 0, 75)
  18.     list:SetScript("OnShow", update_list)
  19.  
  20.     list.text = list:CreateFontString()
  21.     list.text:SetFont((GameFontNormal:GetFont()), UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT + 2)
  22.    
  23.     -- categories
  24.     list.buttons = setmetatable({}, { __index = function(t, i)
  25.         local bg = CreateFrame('Frame', nil, list)
  26.         bg:set_backdrop()
  27.        
  28.         local button = CreateFrame('Button', nil, list)
  29.         button:height(UIDROPDOWNMENU_BUTTON_HEIGHT)
  30.         -- button:set_backdrop()
  31.         if i > 1 then
  32.             button:SetPoint('TOPLEFT', t[i-1], 'BOTTOMLEFT', 0, -2)
  33.         else
  34.             button:SetPoint('TOPLEFT', 5, -5)
  35.         end
  36.         t[i] = button
  37.        
  38.         bg:SetAllPoints(button)
  39.        
  40.         local label = button:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
  41.         label:SetPoint('LEFT', button, 2, 0)
  42.         label:SetJustifyH('LEFT', button)
  43.         button:SetFontString(label)
  44.         button.label = label -- DEPRECATED
  45.  
  46.         local check = button:CreateTexture(nil, 'ARTWORK')
  47.         check:size(24, 24)
  48.         check:SetAllPoints()
  49.         check:SetTexture(media.flat)
  50.         check:SetVertexColor(unpack(media.active))
  51.         button.check = check
  52.  
  53.         local highlight = button:CreateTexture(nil, 'HIGHLIGHT')
  54.         highlight:SetAllPoints(button)
  55.         highlight:SetTexture(1, 1, 1, .04)
  56.         highlight:Hide()
  57.         button:SetHighlightTexture(highlight)
  58.  
  59.         button:SetScript('OnClick', ListButton_OnClick)
  60.        
  61.         return button
  62.     end })
  63.  
  64.     -- create scroll
  65.     list.scrollFrame = CreateFrame('ScrollFrame', list:GetName()..'ScrollFrame', list, 'FauxScrollFrameTemplate')
  66.     list.scrollFrame:SetPoint('TOPLEFT', 6, 2)
  67.     list.scrollFrame:SetPoint('BOTTOMRIGHT', -24, -2)
  68.     list.scrollFrame:SetScript('OnVerticalScroll', function(self, delta)
  69.         FauxScrollFrame_OnVerticalScroll(self, delta, UIDROPDOWNMENU_BUTTON_HEIGHT, function()
  70.             update_list(list)
  71.         end)
  72.     end)
  73.  
  74.     skin(list)
  75.  
  76.     table.insert(lib.list, list)
  77.     dropdown.list = list
  78.    
  79.     return list
  80. end

full code:
Lua Code:
  1. local parent, ns = ...
  2. local lib = ns.chern_config
  3.  
  4. lib.list = lib.list or {}
  5.  
  6. local media = lib.media
  7. UIDROPDOWNMENU_BUTTON_HEIGHT = lib.widget.select_items
  8.  
  9. -- methods
  10. local methods = {
  11.     -- set value to profile[key]
  12.     ['set'] = function(self, value, text)
  13.         self.save = self.module:get_save()
  14.  
  15.         if (not value) then value = self:get() end
  16.         self.save[self.key] = value
  17.         self.callback(self.dropdown)
  18.        
  19.         self.selected = value
  20.     end,
  21.    
  22.     -- return value from profile[key]
  23.     ['get'] = function(self)
  24.         self.save = self.module:get_save()
  25.         return self.save[self.key] or self.selected
  26.     end,
  27.    
  28.     ['setvalue'] = function(self)
  29.         if not text and self.items and type(self.items[1]) == 'table' then
  30.             for i=1, #self.items do
  31.                 if self.items[i].value == value then
  32.                     text = self.items[i].text
  33.                     break
  34.                 end
  35.             end
  36.         end
  37.         self.dropdown.value:SetText(value)
  38.     end,
  39.    
  40.     -- table list
  41.     ['setlist'] = function(self, list)
  42.         if type(list) ~= 'table' then list = nil end
  43.         self.items = list
  44.     end,
  45.    
  46.     -- dropdown click
  47.     ['onenter'] = function(self)
  48.         if self.OnEnter then
  49.             self:OnEnter()
  50.         elseif self.tooltipText then
  51.             GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
  52.             GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true)
  53.             GameTooltip:Show()
  54.         end
  55.     end,
  56.    
  57.     ['onleave'] = function(self)
  58.         if self.OnLeave then
  59.             self:OnLeave()
  60.         else
  61.             GameTooltip:Hide()
  62.         end
  63.     end,
  64.    
  65.     ['onhide'] = function(self)
  66.         if self.list then
  67.             self.list:Hide()
  68.         end
  69.     end
  70. }
  71.  
  72. -- list hide function
  73. local function CloseDropdowns(_,_,dropDownFrame,_,_,_,_,clickedButton)
  74.     for i=1, #lib.list do
  75.         lib.list[i]:set_fade_out(.2, 0)
  76.         lib.list[i].fadeInfo.finishedFunc = function()
  77.             lib.list[i]:Hide()
  78.         end
  79.     end
  80. end
  81. hooksecurefunc('CloseDropDownMenus', CloseDropdowns)
  82. hooksecurefunc('ToggleDropDownMenu', CloseDropdowns) -- WIP
  83.  
  84. -- onclick action
  85. local function ListButton_OnClick(self)
  86.     local dropdown = self:GetParent():GetParent()
  87.     dropdown.selected = self.value
  88.  
  89.     dropdown.list:set_fade_out(.2, 0)
  90.     dropdown.list.fadeInfo.finishedFunc = function()
  91.         dropdown.list:Hide()
  92.     end
  93.     dropdown.value:SetText(self:GetText() or self.value)
  94.     -- dropdown.button:SetNormalTexture(dropdown.button.normal)
  95.  
  96.     local callback = dropdown.callback
  97.     if callback then
  98.         callback(dropdown, self.value, self:GetText())
  99.     end
  100.  
  101.     PlaySoundFile(media.gui_out, 'Master')
  102. end
  103.  
  104. -- if list is empty
  105. local is_empty = {
  106.     { text = GRAY_FONT_COLOR_CODE..EMPTY, value = EMPTY, disabled = true, empty = true }
  107. }
  108.  
  109. local function update_list(self)
  110.     local buttons = self.buttons
  111.     local dropdown = self:GetParent()
  112.  
  113.     local items = dropdown.items
  114.     if #items == 0 then items = is_empty end
  115.  
  116.     local listSize = min(#items, lib.widget.select_maxlist)
  117.     local scrollFrame = self.scrollFrame
  118.     local offset = scrollFrame.offset
  119.     FauxScrollFrame_Update(scrollFrame, #items, listSize, UIDROPDOWNMENU_BUTTON_HEIGHT)
  120.  
  121.     local selected = dropdown.selected
  122.     local width = 0
  123.     local spec_width = scrollFrame:IsShown() and 42 or 52
  124.     for i = 1, #items do
  125.         local item = items[i]
  126.         if type(item) == 'table' then
  127.             self.text:SetText(item.text or item.value)
  128.         else
  129.             self.text:SetText(item)
  130.         end
  131.         width = max(width, spec_width * 2)
  132.     end
  133.  
  134.     local EXTRA_WIDTH = scrollFrame:IsShown() and 50 or 30
  135.     width = max(width + 27 + EXTRA_WIDTH, dropdown:GetWidth() - lib.get_pixel)
  136.     self:width(dropdown:GetWidth())
  137.     width = width - EXTRA_WIDTH
  138.     self:height((listSize * UIDROPDOWNMENU_BUTTON_HEIGHT) + (UIDROPDOWNMENU_BORDER_HEIGHT * 1.5))
  139.  
  140.     for i = 1, listSize do
  141.         local index = i + offset
  142.         local button = buttons[i]
  143.         local item = items[index]
  144.         if item then
  145.             button.value = item
  146.             button.label:SetText(item)
  147.  
  148.             if item == selected then
  149.                 button.check:Show()
  150.             else
  151.                 button.check:Hide()
  152.             end
  153.            
  154.             if item.disabled then
  155.                 button.label:SetTextColor(GameFontDisable:GetTextColor())
  156.             else
  157.                 button.label:SetTextColor(GameFontHighlight:GetTextColor())
  158.             end
  159.  
  160.             button:SetWidth(width)
  161.             button:Show()
  162.         else
  163.             button.value = nil
  164.             button.label:SetText()
  165.             button.label:SetTextColor(GameFontHighlight:GetTextColor())
  166.             button.check:Hide()
  167.             button:Hide()
  168.         end
  169.     end
  170.  
  171.     for i = listSize + 1, #buttons do
  172.         buttons[i]:Hide()
  173.     end
  174. end
  175.  
  176. local skin = function(frame)
  177.     local pixel = lib.get_pixel
  178.  
  179.     -- frame:SetFrameLevel(frame:GetFrameLevel() + 54)
  180.     frame:set_backdrop('Transparent')
  181.     frame:set_blur()
  182.     -- frame.Backdrop:SetFrameLevel(frame:GetFrameLevel() + 54)
  183.     frame.Backdrop:SetBackdropColor(.015, .015, .015, 0.45)
  184.     frame.Backdrop:SetBackdropBorderColor(.03, .03, .03, 1)
  185.  
  186.     -- local overlay = CreateFrame('Frame', nil, frame)
  187.     -- overlay:SetAllPoints(frame)
  188.     -- overlay:set_backdrop('Transparent')
  189.     -- overlay.Backdrop:SetPoint('TOPLEFT', overlay, 'TOPLEFT', 4, -4)
  190.     -- overlay.Backdrop:SetPoint('BOTTOMRIGHT', overlay, 'BOTTOMRIGHT', -4, 4)
  191.     -- overlay.Backdrop:setbordercolor(unpack(media.active))
  192.  
  193.     local scrollbar = _G[frame.scrollFrame:GetName().."ScrollBar"]
  194.     local thumb = _G[frame.scrollFrame:GetName()..'ScrollBarThumbTexture']
  195.     local button_up = _G[frame.scrollFrame:GetName()..'ScrollBarScrollUpButton']
  196.     local button_down = _G[frame.scrollFrame:GetName()..'ScrollBarScrollDownButton']
  197.     button_up:strip_textures()
  198.     button_down:strip_textures()
  199.  
  200.     scrollbar:size(6, 28)
  201.     scrollbar:set_backdrop()
  202.     scrollbar.Backdrop:SetBackdropColor(.015, .015, .015, .95)
  203.     scrollbar.Backdrop:setbordercolor(.21, .21, .21, 1)
  204.  
  205.     thumb:width(6)
  206.     thumb:SetTexture(media.flat)
  207.     thumb:SetVertexColor(unpack(media.active))
  208. end
  209.  
  210. -- create dropdown list
  211. local count = 0
  212. local function create_list(dropdown)
  213.     if dropdown.list then
  214.         return dropdown.list
  215.     end
  216.    
  217.     count = count + 1
  218.    
  219.     local name = parent..'_list'
  220.     local list = CreateFrame("Button", name .. count, dropdown)
  221.     list:SetFrameStrata("FULLSCREEN_DIALOG")
  222.     list:SetToplevel(true)
  223.     list:Raise()
  224.     list:Hide()
  225.    
  226.     list:set_point('TOPLEFT', dropdown, 'BOTTOMLEFT', 0, 75)
  227.     list:SetScript("OnShow", update_list)
  228.  
  229.     list.text = list:CreateFontString()
  230.     list.text:SetFont((GameFontNormal:GetFont()), UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT + 2)
  231.    
  232.     -- categories
  233.     list.buttons = setmetatable({}, { __index = function(t, i)
  234.         local bg = CreateFrame('Frame', nil, list)
  235.         bg:set_backdrop()
  236.        
  237.         local button = CreateFrame('Button', nil, list)
  238.         button:height(UIDROPDOWNMENU_BUTTON_HEIGHT)
  239.         -- button:set_backdrop()
  240.         if i > 1 then
  241.             button:SetPoint('TOPLEFT', t[i-1], 'BOTTOMLEFT', 0, -2)
  242.         else
  243.             button:SetPoint('TOPLEFT', 5, -5)
  244.         end
  245.         t[i] = button
  246.        
  247.         bg:SetAllPoints(button)
  248.        
  249.         local label = button:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
  250.         label:SetPoint('LEFT', button, 2, 0)
  251.         label:SetJustifyH('LEFT', button)
  252.         button:SetFontString(label)
  253.         button.label = label -- DEPRECATED
  254.  
  255.         local check = button:CreateTexture(nil, 'ARTWORK')
  256.         check:size(24, 24)
  257.         check:SetAllPoints()
  258.         check:SetTexture(media.flat)
  259.         check:SetVertexColor(unpack(media.active))
  260.         button.check = check
  261.  
  262.         local highlight = button:CreateTexture(nil, 'HIGHLIGHT')
  263.         highlight:SetAllPoints(button)
  264.         highlight:SetTexture(1, 1, 1, .04)
  265.         highlight:Hide()
  266.         button:SetHighlightTexture(highlight)
  267.  
  268.         button:SetScript('OnClick', ListButton_OnClick)
  269.        
  270.         return button
  271.     end })
  272.  
  273.     -- create scroll
  274.     list.scrollFrame = CreateFrame('ScrollFrame', list:GetName()..'ScrollFrame', list, 'FauxScrollFrameTemplate')
  275.     list.scrollFrame:SetPoint('TOPLEFT', 6, 2)
  276.     list.scrollFrame:SetPoint('BOTTOMRIGHT', -24, -2)
  277.     list.scrollFrame:SetScript('OnVerticalScroll', function(self, delta)
  278.         FauxScrollFrame_OnVerticalScroll(self, delta, UIDROPDOWNMENU_BUTTON_HEIGHT, function()
  279.             update_list(list)
  280.         end)
  281.     end)
  282.  
  283.     skin(list)
  284.  
  285.     table.insert(lib.list, list)
  286.     dropdown.list = list
  287.    
  288.     return list
  289. end
  290.  
  291. local function button_OnClick(self)
  292.     PlaySoundFile(media.gui_info)
  293.  
  294.     local dropdown = self:GetParent()
  295.     local list = dropdown.list
  296.     if(not list) then
  297.         list = create_list(dropdown)
  298.         dropdown.list = list
  299.     end
  300.  
  301.     local show = not list:IsShown()
  302.     CloseDropDownMenus()
  303.     if show then
  304.         list:Raise()
  305.         list:Show()
  306.         list:set_fade_in(.2, 1)
  307.         local selectedIndex
  308.         local items, selected = dropdown.items, dropdown.selected
  309.         for i=1, #items do
  310.             if items[i] == selected then
  311.                 selectedIndex = i
  312.                 break
  313.             end
  314.         end
  315.         if selectedIndex then
  316.             local scrollbar = _G[list.scrollFrame:GetName().."ScrollBar"]
  317.             local _, maxScroll = scrollbar:GetMinMaxValues()
  318.             scrollbar:SetValue((maxScroll / (#items - 15)) * (selectedIndex - 5))
  319.         end
  320.     end
  321. end
  322.  
  323. -- spawn elements
  324. local function create(options, parent)
  325.     options.size = options.size or 'half'
  326.     local container = lib:create_container(options, parent, 48)
  327.     local name = options.name..'_'..options.key
  328.    
  329.     -- objects
  330.     local dropdown = CreateFrame('Frame', name, container)
  331.     dropdown:size(142, 26)
  332.     dropdown:SetPoint('TOPLEFT', 11, -22)
  333.     dropdown:set_border(false, true)
  334.     dropdown:EnableMouse(true)
  335.     dropdown:SetScript('OnEnter', function() container:onenter() end)
  336.     dropdown:SetScript('OnLeave', function() container:onleave() end)
  337.     dropdown:SetScript('OnHide', function() container:onhide() end)
  338.    
  339.     local label = dropdown:CreateFontString(nil, 'ARTWORK', 'GameFontNormal')
  340.     label:SetPoint("TOPLEFT", 5, 20)
  341.     label:SetPoint("TOPRIGHT", -5, 20)
  342.     label:SetJustifyH("LEFT")
  343.     label:SetText(options.label)
  344.     label:SetAlpha(media.muted)
  345.    
  346.     -- value text
  347.     local valueText = dropdown:CreateFontString(nil, "ARTWORK", 'GameFontHighlightSmall')
  348.     valueText:SetPoint('LEFT', 6, -2)
  349.     -- dropdown.value:SetAlpha(media.muted)
  350.     dropdown.value = valueText
  351.  
  352.     -- arrow
  353.     local BUTTONSIZE = lib.widget.select_button
  354.     local button = CreateFrame('Button', nil, dropdown)
  355.     button:size(BUTTONSIZE, BUTTONSIZE)
  356.     button:SetPoint('TOPLEFT', dropdown, 2, -2)
  357.     button:SetPoint('TOPRIGHT', dropdown, 2, -2)
  358.    
  359.     local normal = button:CreateTexture(nil, 'BORDER')
  360.     normal:size(18, 18)
  361.     normal:SetPoint('RIGHT', -8, 2)
  362.     normal:SetTexture(media.arrow_down)
  363.     button:SetNormalTexture(normal)
  364.  
  365.     local disabled = button:CreateTexture(nil, 'BORDER')
  366.     disabled:size(18, 18)
  367.     disabled:SetPoint('RIGHT', -8, 2)
  368.     disabled:SetTexture(media.arrow_down)
  369.     button:SetDisabledTexture(disabled)
  370.  
  371.     local highlight = button:CreateTexture(nil, 'HIGHLIGHT')
  372.     highlight:size(14, 14)
  373.     highlight:SetPoint('RIGHT', -10, 0)
  374.     highlight:SetVertexColor(unpack(media.class))
  375.     highlight:SetBlendMode('ADD')
  376.     button:SetHighlightTexture(highlight)
  377.  
  378.     function button:OnEnter()
  379.         return container:onenter(dropdown)
  380.     end
  381.  
  382.     function button:OnLeave()
  383.         return container:onleave(dropdown)
  384.     end
  385.  
  386.     button:SetScript('OnEnter', button.OnEnter)
  387.     button:SetScript('OnLeave', button.OnLeave)
  388.     button:SetScript('OnClick', button_OnClick)
  389.    
  390.     -- Mixin methods, reference variables
  391.     container.save = options.save
  392.     container.key = options.key
  393.     container.module = options.module
  394.     container.dropdown = dropdown
  395.     container.callback = options.callback
  396.     container.module = options.module
  397.    
  398.     Mixin(container, methods)
  399.    
  400.     -- callback
  401.     local get_value = container:get()
  402.     dropdown.callback = function(self)
  403.         local value = self.value:GetText() or options.value
  404.         container:set(value)
  405.     end
  406.    
  407.     -- hook into actions for updates
  408.     if (options.action) then
  409.         lib:add_action(options.action, function(value)
  410.             local results = options.lookup()
  411.             options.options = results
  412.         end)
  413.     end
  414.    
  415.     -- default variables
  416.     dropdown.items = items or options.options
  417.     dropdown.value:SetText(get_value or options.value)
  418.     dropdown.button = button
  419.     dropdown.button.normal = normal
  420.     dropdown.selected = get_value or options.value
  421.     dropdown.tooltipText = tooltipText
  422.  
  423.     return container
  424. end
  425.  
  426. lib:register_element('select', create)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » dropdown list layer

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off