Feature Request: onSelect #463


  • Enhancement
Open
  • Vexxilus created this issue Aug 25, 2018

    I would like to request the following changes:

     

    In AceConfigRegistry-3.0.lua add the following table entry:

    typedkeys.group.onSelect=optmethod

     

    In AceConfigDialog-3.0.lua change the GroupSelected function to:

    local function GroupSelected(widget, event, uniquevalue)
    	local user = widget:GetUserDataTable()
    	local options = user.options
    	local path = user.path
    
    	local feedpath = new()
    	for i = 1, #path do
    		feedpath[i] = path[i]
    	end
    	BuildPath(feedpath, ("\001"):split(uniquevalue))
    
    	widget:ReleaseChildren()
    	if user.option.onSelect then
    		GetOptionsMemberValue("onSelect", user.option, options, feedpath, user.appName)
    	end
    	AceConfigDialog:FeedGroup(user.appName, options, widget, user.rootframe, feedpath)
    
    	del(feedpath)
    end

    This would allow for a simpler method of detecting when a user has switched which sub-group they are in so I can update which options should be displayed efficiently.  Otherwise I have to either use a "hidden" function that get evaluated every time an options is changed or my alternate solution.  Currently I have placed a fake option in each tab with a "hidden" function that evaluates when there is a tab change and then triggers an OnUpdate script that updates which options should be seen and then has to FeedOptions the whole thing again.

     

    Basically these changes would allow me to reduce a page of ugly hackish code into an eight-line function that drastically reduces processing time.  I'm using these changes on my local copy and it makes a noticeable difference.  Imagine two tabs, one with all spells, talents,  and a bunch of items, and another with filters to select which of those are shown.  The list of spells, talents, and items only needs to be updated once when switching from the filter tab to the list tab.

     

    If this request is denied then at least remove this bit from the current version of GroupSelected:

    	local group = options
    	for i = 1, #feedpath do
    		group = GetSubOption(group, feedpath[i])
    	end
    

    The variable "group" is not used so that loop is not needed.

  • Vexxilus added a tag Enhancement Aug 25, 2018
  • nevcairiel posted a comment Aug 25, 2018

    The way the options tables are designed is to define them completely and let the framework figure out which need to be currently displayed.

    Trying to somehow detect which page you are on and then figuring out in your addon which options should be visible goes against that design, so I'm not sure what exactly that would gain us.

  • Vexxilus posted a comment Aug 25, 2018

    It may  not be useful to everyone but I don't like the current work around I'm using and I can't do it the way it was intended because it creates a brief but noticeable pause every time an option is changed.  It is a very minor change that may be a severe edge case but it does have a use.

     

    Just to test I limited the spells and talents to the current player's class and used the "hidden" function to determine visibility.  Limiting the number of entries did get rid of the pause (at a loss of functionality) but introduces a new problem.  There are two filter modes, inclusive and exclusive.  When using the exclusive mode and changing a spell's options it could result in it being hidden on you.  To circumvent that I need to keep track of the current spell which is basically what I was doing but with tabs. My initial suggested change results in cleaner more efficient code for what I want to achieve.

     

    This is what it looks like in practice:

    local overrideTab
    	
    local overrideOptions = {
    	type = 'group', childGroups = 'tab',
    	onSelect = function(info)
    		local tab = info[#info]
    		if tab == overrideTab then return end
    		overrideTab = tab
    		if tab == "actions" then
    			UpdateOverrideEntries()
    		elseif tab == "filter" then
    			UpdateAvailableFilters()
    		end
    	end,
    	args = {
    

     

    Vs either this (which is run for potentially a 80 or more entries every time an option is changed and requires saving currentEntry in each "set" function):

    local currentEntry
    	
    local function ShouldHideEntry(info)
    	local actionID = info[#info]
    	if actionID == currentEntry then return end
    
    	local settings = addon.db.profile.override
    	local filter = settings.filter
    
    	-- Inclusive (OR)
    	if settings.filterMode == 2 then
    		for tag, actions in pairs(actionTag) do
    			if filter[tag] and actions[actionID] then
    				return false
    			end
    		end
    		return true
    	end
    
    	-- Exclusive (AND)
    	for tag, actions in pairs(actionTag) do
    		if filter[tag] and not actions[actionID] then
    			return true
    		end
    	end
    	return false
    end
    

     

    Or this (which also requires me to preserve, restore and otherwise work around hackElement in several functions including UpdateOverrideEntries and UpdateAvailableFilters):

    local frame, overrideTab = CreateFrame('Frame', nil, UIParent)
    frame:Hide()
    
    frame:SetScript('OnUpdate', function(self)
    	self:Hide()
    	if overrideTab == "actions" then
    		UpdateOverrideEntries()
    	elseif overrideTab == "filter" then
    		UpdateAvailableFilters()
    	end
    	addon.config[1]:Refresh()
    end)
    
    local hackElement = {
    	type = 'toggle',
    	name = "H_A_C_K",
    	hidden = function(info)
    		local tab = info[#info - 1]
    		if tab ~= overrideTab then
    			overrideTab = tab
    			frame:Show()
    		end
    		return true
    	end
    }
    
    overrideOptions.args.actions.args.H_A_C_K = hackElement
    overrideOptions.args.filter.args.H_A_C_K = hackElement
    

To post a comment, please login or register a new account.