View Single Post
06-18-09, 04:46 AM   #18
Luzzifus
A Warpwood Thunder Caller
 
Luzzifus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 94
Ok, now what comes to my attention is that you don't call ClearAllPoints in the parents OnHide() function. And if I understand your code correctly this should be there, since you always re-set the points on hiding/showing.

----------

What I am doing has a pretty similar effect to what you are doing, though I'm doing it different. You could simply expand your code to hide empty bags by simply expanding your conditions to hide bags.

Hiding empty bags with parent anchoring

The idea was to save anchoring information in every frame. This is not information about which one the frame is anchored to but rather which frames are anchored to the current one (mainly for performance reasons). So when I'm spawning the bags, it looks like this:

Code:
-----------------------------------------------
-- Store the anchoring order:
-- read: "tar" is anchored to "src" in the direction denoted by "dir".
-----------------------------------------------
local function CreateAnchorInfo(src,tar,dir)
    tar.AnchorTo = src
    tar.AnchorDir = dir
    if src then
        if not src.AnchorTargets then src.AnchorTargets = {} end
        src.AnchorTargets[tar] = true
    end
end

-- Main Anchors:
-- Note that you still have to set points for those!
CreateAnchorInfo(nil, cB_Bags.main, "Bottom")
CreateAnchorInfo(nil, cB_Bags.bank, "Bottom")

cB_Bags.main:SetPoint("BOTTOMRIGHT", -20, 150)
cB_Bags.bank:SetPoint("LEFT", 15, 0)    
    
-- Bank Anchors:
CreateAnchorInfo(cB_Bags.bank, cB_Bags.bankArmor, "Right")
CreateAnchorInfo(cB_Bags.bankArmor, cB_Bags.bankTrade, "Bottom")

-- more CreateAnchorInfos --
As already said, this does nothing more than storing the information about the hierarchy. I'm not setting any other points except those for the two main bags at the time of spawning. The "main bags" are obviously those which are anchored to UIParent.

Now you need this little fella in your code:

Code:
function cargBags_Nivaya:UpdateAnchors(self)
    if not self.AnchorTargets then return end
    for v,_ in pairs(self.AnchorTargets) do
        local t, u = v.AnchorTo, v.AnchorDir
        if t then
            local h = cB_BagHidden[t.Name]
            v:ClearAllPoints()
            if      not h   and u == "Top"      then v:SetPoint("BOTTOM", t, "TOP", 0, 15)
            elseif  h       and u == "Top"      then v:SetPoint("BOTTOM", t, "BOTTOM")
            elseif  not h   and u == "Bottom"   then v:SetPoint("TOP", t, "BOTTOM", 0, -15)
            elseif  h       and u == "Bottom"   then v:SetPoint("TOP", t, "TOP")
            elseif u == "Left" then v:SetPoint("BOTTOMRIGHT", t, "BOTTOMLEFT", -15, 0)
            elseif u == "Right" then v:SetPoint("TOPLEFT", t, "TOPRIGHT", 15, 0) end
        end
    end
end
This function is responsible for actually setting the points. Not all directions are covered, only those I currently need. But I hope you get the point.

The last thing you have to do is bind the anchoring update to an event. So just add something like the following to your UpdateButtonPositions handler. At the same time I'm checking for empty bags:
Code:
local tName = self.Name 
local isEmpty = true

for _,v in ipairs(buttons) do
    ...
    isEmpty = false
end
cB_BagHidden[tName] = (not t) and isEmpty or false

cargBags_Nivaya:UpdateAnchors(self)
cB_BagHidden saves information about which bags should be hidden, which equals to the empty state for me. "t" is for exceptions, if you have them (see below).

Now it basically should work. There's two things you still have to do. First is to apply the check for empty bags to you OpenCargBags() function, I'm doing it like this:

Code:
local function ShowBag(bag) if not cB_BagHidden[bag.Name] then bag:Show() end end

function OpenCargBags()
    cB_Bags.main:Show()
    ShowBag(cB_Bags.armor)
    ShowBag(cB_Bags.bagNew)
    ShowBag(cB_Bags.bagItemSets)
    ShowBag(cB_Bags.quest)
    ...
end
The second thing you might wanna do is handle exceptions. So basically you usually don't want to hide the main bags when they're empty. This is also done in UpdateButtonPositions, for my layout it looks kinda messy though:

Code:
local tName = self.Name    
local tBankBags = string.find(tName, "cBniv_Bank%a+")
local tBank = tBankBags or (tName == "cBniv_Bank")

local t = (tName == "cBniv_Bag") or (tName == "cBniv_Bank") or (tName == "cBniv_Keyring") 
local tAS = (tName == "cBniv_Ammo") or (tName == "cBniv_Soulshards")
if (not tBankBags and cB_Bags.main:IsShown() and not (t or tAS)) or (tBankBags and cB_Bags.bank:IsShown()) then 
    if isEmpty then self:Hide() else self:Show() end 
end
"t" excludes the main bags and the keyring, that's all the bags I never want to be automatically hidden or shown. The rest of the code handles automatic hiding and showing based on some conditions (appropriate main bag is opened and it's not one of the "locked" bags).

After typing all that I realize how complex my solution is..
Hope it helps anyways.

Last edited by Luzzifus : 06-18-09 at 05:00 AM.
  Reply With Quote