Cycle through functions

Hello everyone,

I’m working on a customized UI using ElvUI and WeakAuras.

ElvUI includes a module called “DataBars”, which adds 4 individual DataBars for XP, Reputation, Honor and Azerite.

They are all controlled individually, so you can move them and adjust their width and height individually.

For my UI in particular, my goal is to have all 4 DataBars ‘stacked’ on top of each other, all 4 occupying the same space on the screen, in a single ‘unibar’ of sorts.

Since I may want to display Rep vs Azerite in some cases, I need to determine a way to display one of these DataBars, while also hiding the other 3, as to avoid one DataBar overlapping another which would hide the one I wish to see, due to all 4 of them occupying the same space on the screen.

I asked over on the ElvUI Discord, and did find out that there is a /run script that can be ran to hide and show each DataBar (as opposed to showing/hiding them via the ElvUI config menu)

This is what it looks like for the experience bar:

    if ElvUI[1].DataBars.db.experience.enable == true then 
        ElvUI[1].DataBars.db.experience.enable = false else 
        ElvUI[1].DataBars.db.experience.enable = true end; 
    ElvUI[1].DataBars:EnableDisable_ExperienceBar()

So if I just stick this in a /run, or even with an OnClick, it works fine, toggling the XP bar on each run.

And I was told to just plug in the info for the other 3 bars - honor, rep and azerite - to do the same.

What I need help with:

I want to have all 4 DataBars behind a run function (my plan is to stick it in behind a single button) that will cycle through all 4 DataBars.

So, first click will show the XP bar. Second click will hide the XP bar, and show the Rep bar. 3rd, show hide rep and show honor. 4th, hide honor and show azerite. And on the 5th, hide azerite and show xp.

And due to the toggle nature of the functions (as opposed to being individual functions for hiding and showing), it must check to see if others are show, and ensure they are hidden.

Thanks,
– K

I don’t know ElvUI so the names of the bars settings and their functions in the code below are made up based on the ones you provided. Change accordingly.

This assumes your addon is loading after ElvUI otherwise you will need to delay creation of the table.

local Next, Current = 0 

-- Table of ElvUI Bars and associated functions, initialise delayed until after entering world (see below)
local ElvBars

local function ToggleBars()
	Next = Next + 1 -- Get the next bar
	if Next > 4 then -- or first if we've gone too far
		Next = 1
	end
	if Current then -- Disable the current active bar
		ElvBars[Current].bar.enable = false
		ElvBars[Current].func()
	end
	ElvBars[Next].bar.enable = true -- Enable the next bar in the list
	ElvBars[Next].func()
	Current = Next -- Save for rinse and repeat.
end

-- A test button to run the toggle.
local f = CreateFrame("Button", "KompyBarsButton", UIParent, "UIPanelButtonTemplate")
f:SetSize(100, 35)
f:SetPoint("LEFT", 10, 0)
f:SetText("Kompy Bars")
f:SetScript("OnClick", ToggleBars)
f:SetScript("OnEvent", function(self) -- We hope ElvUI has done its initialisation before now
	self:UnregisterAllEvents()
	ElvBars = { -- You will need to find out the names of the bars/functons
		[1] = { bar=ElvUI[1].DataBars.db.experience, func=ElvUI[1].DataBars:EnableDisable_ExperienceBar },
		[2] = { bar=ElvUI[1].DataBars.db.reputation, func=ElvUI[1].DataBars:EnableDisable_ReputationBar },
		[3] = { bar=ElvUI[1].DataBars.db.honor, func=ElvUI[1].DataBars:EnableDisable_HonorBar },
		[4] = { bar=ElvUI[1].DataBars.db.azerite, func=ElvUI[1].DataBars:EnableDisable_AzeritBar },
	}
	for _,v in pairs(ElvBars) do -- Initialise bars to disabled when you login to a character.
		v.bar.enable = false -- You might want to do something different
		v.func() -- If you want to start with a bar showing you will need to intialise Next and Current as well
	end
end)
f:RegisterEvent("PLAYER_ENTERING_WORLD")

Cold coded so …

Edited to delay table initalisation (hopefully long enough).

Ty for the help! Someone else ended up reaching out to me with a similar but different solution.

Like so:

aura_env.region:SetScript("OnMouseDown", function() 
    local priority = {
        experience = "honor",
        honor = "reputation",
        reputation = "experience"
    }
    
    local defaultBar = "experience" -- Set default bar to activate if all set to false
    local currentBar = nil -- Gets set to toggle the next bar in sequence
    
    -- Disables all bars and captures current bar that was enabled
    
    for k, v in pairs( ElvUI[1].DataBars.db ) do
        if v.enable == true and currentBar == nil then
            currentBar = k -- Capture current bar shown, if more than one only captures the first
        end
        v.enable = false -- Disable bar
    end
    
    -- Uses defaultBar if no bars were enabled, otherwise activate next bar in list
    if ( currentBar ~= nil ) then
        ElvUI[1].DataBars.db[ priority[ currentBar ] ].enable = true
    else
        ElvUI[1].DataBars.db[ defaultBar ].enable = true
    end
    
    ElvUI[1].DataBars:EnableDisable_ExperienceBar()
    ElvUI[1].DataBars:EnableDisable_HonorBar()
    ElvUI[1].DataBars:EnableDisable_ReputationBar()
    ElvUI[1].DataBars:EnableDisable_AzeriteBar()
end)

This ended up working better as well, because I can reverse the order of the cycling of bars, and create ‘forward’ and ‘back’ buttons to cycle through the bars in a forward and backward fashion.