WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   oUF (Otravi Unit Frames) (https://www.wowinterface.com/forums/forumdisplay.php?f=87)
-   -   Reliably referencing the player frame (https://www.wowinterface.com/forums/showthread.php?t=22635)

Luzzifus 04-21-09 10:42 AM

Reliably referencing the player frame
 
Hi,

this is an issue I've run into a few times now, so the code I'm posting here is only an example. So as an example, in my layouts config I am building some dynamic option frames to adjust the unit names for different units. That looks something like this:

Code:

local optUnitNames = function(order, unit)
        return {       
                type = 'group', name = "Unit Name Settings", order = order, dialogHidden = true, dialogInline = true,
                args = {
                        playerPos        = {
                                type = 'select',
                                order = 8,
                                name = unit,
                                width = "half",
                                values = { ["Top"] = "Top", ["Bottom"] = "Bottom", },
                                get = function(info) return
                                        nivcfgDB.names[unit].pos
                                end,
                                set = function(info, value)       
                                        nivcfgDB.names[unit].pos = value
                                        oUF_Nivaya:UpdateNamePos(oUF.units[unit], unit)
                                end, },
                       
                        ...
                },
        }
end

function oUF_Nivaya:UpdateNamePos(self, unit)
        ...
end

The important line is the red one. This function needs the stated parameters in order to apply the given settings to a specific frame. That architecture perfectly works as long as I am not in a party or a raid.

In a party or a raid, my layout also shows the player as a unit button in the raidframes. When the above update function is now called for the player frame, I'm getting an error about unit being nil in UpdateNamePos(). For some reason, oUF references the unit button in the raidframes instead of the actual player frame via oUF.units['player'].

I managed to work around that via adding global references to the spawned frames, like this:
Code:

oUF_Nivaya:UpdateNamePos(oUF_player, 'player')
Nedless to say that I need to call that for every unit everytime since I cannot restrict the call to a specific unit via the unit parameter. As a result this is destroying my dynamic architecture of the options table.

So, is there a way to reliably reference the player frame via a units parameter and without using a global reference?

Thanks in advance,
Luzzifus.

haste 04-21-09 11:06 AM

You could always iterate over oUF.objects and check if the unit is player, and run your code if it is. oUF.units is really just meant for quick unreliable indexing.

Luzzifus 04-21-09 11:19 AM

Iterating through all units for every call doesn't look too efficient, does it?

There's something else crossing my mind given my global reference, how about this:

Code:

local v = _G['oUF_'..unit]
if v then oUF_Nivaya:UpdateNamePos(v, unit) end

It's still global but it would at least allow me to use the unit parameter.

**edit:
Btw. what's the exact difference between oUF.units, oUF.objects and oUF.elements?

haste 04-21-09 12:05 PM

The iterators in Lua aren't exactly slow, and you are most likely not calling them all the time anyway. You can ofc. use a global, it's all up to you really :).

oUF.objects - Contains every frame touched by oUF.
oUF.units - Contains all the units that oUF knows about. The list is created by watching what gets sent to :SetAttribute('unit', ...).
oUF.elements - Doesn't exist. You might be thinking of the __elements table that exists on oUF objets however. This table just contains all the active elements on a frame.

Luzzifus 04-21-09 02:29 PM

Thanks alot, that will help. :)

jadakren 04-21-09 07:59 PM

i got around this by creating a units table on my addon object.
http://github.com/airtonix/oufsmee2/...e.lua#L966-988

oUF_Smee2.units is a table built off my settings table. This way i can interate over the exact frames i create.

I do the same thing in my raid layout :
Code:

        local raidSettings = db.frames.raid
        local raidFrame = CreateFrame('Frame', 'oufraid', UIParent)
                                raidFrame.groups = {}
                                raidFrame:SetBackdrop(db.textures.backdrop)
                                raidFrame:SetBackdropColor(unpack(db.colors.backdropColors))
                                raidFrame:EnableMouse(true)


        self.units.raid = raidFrame
        self.units.raid.groups={}
        for index,data in pairs(raidSettings.group) do
                if(data.visible) then
                        local group = oUF:Spawn('header', 'oufraid'..index)
                        group:SetManyAttributes(
                        "template",                        "oUF_Smee2_Groups_Raid",
                        "groupFilter",                index,
                        "showRaid",                true,
                        "showPlayer",                true,
                        "yOffSet",                        raidSettings.unit.yOffSet,
                        "xOffSet",                        raidSettings.unit.xOffSet,
                        "point",                        raidSettings.unit.anchorFromPoint,
                        "initial-height",                  raidSettings.unit.height,
                        "initial-width",                raidSettings.unit.width,
                        "showPlayer",                true)

                       
                        group.groupType = 'raid'
                        group:SetPoint(data.anchorFromPoint,
                                        self.units.raid.groups[data.anchorTo] or self.units.raid,
                                        data.anchorToPoint,
                                        data.anchorX,
                                        data.columnSpacing)                       
                        group:SetFrameLevel(0)
                        group:SetParent(raidFrame)
                        self.units.raid.groups[index] = group
                end
        end
        raidFrame:SetFrameLevel(1)
        raidFrame:SetPoint(
                raidSettings.anchorFromPoint,
                UIParent,
                raidSettings.anchorToPoint,
                raidSettings.anchorX,
                raidSettings.anchorY)



All times are GMT -6. The time now is 11:53 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI