WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Clear Button Texture and Text LUA Help (https://www.wowinterface.com/forums/showthread.php?t=55351)

Dejablue 04-24-17 11:10 AM

Clear Button Texture and Text LUA Help
 
I am making an addon that creates buttons for the Sentinax beacons in your bags. I have it complete, except I cannot figure out how to iteratively clear and then refresh the button texture and text (for item count).

Maybe I am using the wrong template and or am missing something obvious. I always have trouble with refreshing text.

Here is code that works in game, you can copy/paste into a test addon, and it puts the buttons on your screen in the middle. Head to a vendor and sell a beacon, or go in the field and loot some. It will make new frames fine. But if the count changes it wont clear the previous text so there is, for example, a 2 on top of a 3 when you use it. The same is true for the textures.

Any help is appreciated.

Cheers!


Code:

--Beam Me Up Deja Initialization Frame
       
local Ecount
local Rcount
local Ucount

local BeamMeUpDejaInitFrame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
        BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_LOGIN")
        BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
        BeamMeUpDejaInitFrame:RegisterEvent("LOOT_OPENED")
        BeamMeUpDejaInitFrame:RegisterEvent("BAG_UPDATE")
       
        BeamMeUpDejaInitFrame:SetScript("OnEvent", function(self, event, ...)
                Ecount = 0
                Rcount = 0
                Ucount = 0       
                for bag = 0, 4, 1 do
                        for slot=1, GetContainerNumSlots(bag), 1 do
                                local name = GetContainerItemLink(bag,slot)
                                if name and string.find(name,"Sentinax Beacon") then
                                --if name and string.find(name,"Hearthstone") then
                                        --ddebug()
                                        local _, itemCount = GetContainerItemInfo(bag, slot)
                                        local itemName, itemLink, itemRarity,_,_,_,_,itemStackCount,_,itemTexture,_ = GetItemInfo(name)
                                                --print(name, itemName,itemStackCount)--Debugging
                                        local texture = select(10,GetItemInfo(name))
                                        local w = 36
                                        local h = 36
                                        local x
                                        local y = 0
                                        if itemRarity == 4 then
                                                --print("Ecount is "..Ecount)--Debugging
                                                x = (Ecount*w)*1.1
                                                y = h*2.1
                                                Ecount = Ecount+1
                                        end
                                        if itemRarity == 3 then
                                                --print("Rcount is "..Rcount)--Debugging
                                                x = (Rcount*w)*1.1
                                                y = h*1.1
                                                Rcount = Rcount+1
                                        end
                                        if itemRarity == 2 then
                                                --print("Ucount is "..Ucount)--Debugging
                                                x = (Ucount*w)*1.1
                                                Ucount = Ucount+1
                                        end
                                       
                                        BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
                                        _G["BMUDButton"..name] = BMUDButton

                                        BMUDButtonFS = BMUDButton:CreateFontString("FontString","OVERLAY","GameTooltipText")
                                        _G["BMUDButtonFS"..name] = BMUDButtonFS                                       

                                        if ((_G["BMUDButtonFS"..name])~=nil) then
                                                BMUDButton:SetNormalTexture(nil,"ARTWORK")
                                                BMUDButton:SetPushedTexture(nil,"ARTWORK")
                                                BMUDButton:SetHighlightTexture(nil,"ARTWORK")
                                                BMUDButtonFS:SetFormattedText("")
                                        end

                                                BMUDButton:RegisterForClicks("AnyUp", "AnyDown")
                                                BMUDButton:ClearAllPoints()
                                                BMUDButton:SetPoint("CENTER",x,y+32)
                                                BMUDButton:SetSize(w,h)
                                       
                                                BMUDButtonFS:SetPoint("BOTTOMRIGHT", BMUDButton)
                                                BMUDButtonFS:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
                                                --BMUDButtonFS:SetShadowOffset(1, -1)--Optional
                                                BMUDButtonFS:SetTextColor(1, 1, 1);
                                                --print(name, itemCount)--Debugging
                                                BMUDButton:SetAttribute("type","item")
                                                BMUDButton:SetAttribute("item",itemName)

                                                if event == "BAG_UPDATE" then
                                                        BMUDButtonFS:SetFormattedText("%.0f", itemCount)
                                                        BMUDButton:SetNormalTexture(itemTexture)
                                                        BMUDButton:SetPushedTexture(itemTexture)
                                                        BMUDButton:SetHighlightTexture(itemTexture)
                                                        print("Bag updated")
                                                end
                                        BMUDButton:HookScript("OnEnter", function(self)
                                                GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
                                                GameTooltip:SetHyperlink(name)
                                                GameTooltip:Show()
                                        end)
                                        BMUDButton:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
                                end
                        end
                end
        end)


Fizzlemizz 04-24-17 12:31 PM

I don't see where you check if a button already exists. Every OnEvent seems to trigger the creation of a new set of buttons for each specified item found.

syncrow 04-24-17 02:02 PM

You're code re-creates your buttons constantly, which would cause massive error junk when you loot beacons right in combat....

It would be much better to pre-create all necessary buttons and only handle the count text upon bag updates.

Here is a little example on how it would look like:
Lua Code:
  1. local buttonSize = 36
  2. local padding = 0;
  3. local beacons = {
  4.     -- rares
  5.     [146923] = ""-- petrification
  6.     [147355] = ""-- bloodstrike
  7.     [146922] = ""-- fel growth
  8.     [146915] = ""-- greater Torment
  9.     [146912] = ""-- greater carnage
  10.     [146914] = ""-- greater engineering
  11.     [146910] = ""-- greater dominance
  12.     [146913] = ""-- greater warbeasts
  13.     [146911] = "",  -- greater firestorm
  14.    
  15.     -- uncommons
  16.     [146906] = "",  -- carnage
  17.     [146907] = "",  -- warbeasts
  18.     [146909] = "",  -- torment
  19.     [146908] = "",  -- engineering
  20.     [146903] = "",  -- dominance
  21.     [146905] = ""-- firestorm
  22. }
  23.  
  24. local function CreateButtons()
  25.     local index = 1;
  26.    
  27.     for itemID in pairs(beacons) do
  28.         local itemName, itemLink = GetItemInfo(itemID)
  29.        
  30.         if itemName then
  31.             local texture = select(10, GetItemInfo(itemID));
  32.             local button = CreateFrame("Button", "BMUDButton"..index, UIParent, "SecureActionButtonTemplate")
  33.             local xPos = -300 + ( (buttonSize + padding) * (index-1))
  34.            
  35.             button:SetSize(buttonSize, buttonSize)
  36.             button:SetPoint("CENTER", xPos, 0)
  37.             button:RegisterForClicks("AnyUp", "AnyDown")
  38.             button:SetAttribute("type", "item")
  39.             button:SetAttribute("item", itemName)
  40.  
  41.             button.fs = button:CreateFontString(nil, "OVERLAY", "GameTooltipText")
  42.             button.fs:SetPoint("BOTTOMRIGHT")
  43.             button.fs:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
  44.             button.fs:SetTextColor(1, 1, 1)
  45.  
  46.             button:SetNormalTexture(texture)
  47.             button:SetPushedTexture(nil,"ARTWORK")
  48.             button:SetHighlightTexture(nil,"ARTWORK")
  49.            
  50.             button:HookScript("OnEnter", function(self)
  51.                 GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  52.                 GameTooltip:SetHyperlink(itemLink)
  53.                 GameTooltip:Show()
  54.             end)
  55.             button:HookScript("OnLeave", GameTooltip_Hide)
  56.            
  57.             -- overwrite empty string with the button as a reference here
  58.             beacons[itemID] = button;
  59.         end
  60.        
  61.         index = index + 1;
  62.     end    
  63. end
  64.  
  65. local function UpdateCount()
  66.     for itemID, button in pairs(beacons) do
  67.         local itemName = GetItemInfo(itemID);
  68.         local count = 0;
  69.        
  70.         for bag = 0, 4 do
  71.             for slot = 1, GetContainerNumSlots(bag) do
  72.                 local item = GetContainerItemID(bag, slot);
  73.                
  74.                 -- found a beacon in your bag
  75.                 if itemID == item then
  76.                     count = count + 1
  77.                 end
  78.             end
  79.         end
  80.        
  81.         -- handle display
  82.         if count > 0 then
  83.             button.fs:SetText(count);
  84.             button:GetNormalTexture():SetDesaturated(false);
  85.         else
  86.             button.fs:SetText("");
  87.             button:GetNormalTexture():SetDesaturated(true);
  88.         end
  89.     end
  90. end
  91.  
  92. local frame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
  93.  
  94. frame:RegisterEvent("PLAYER_LOGIN")
  95. frame:SetScript("OnEvent", function(self, event, ...)
  96.     if event == "PLAYER_LOGIN" then
  97.         CreateButtons()
  98.         UpdateCount()
  99.         self:RegisterEvent("BAG_UPDATE")
  100.     end
  101.    
  102.     if event == "BAG_UPDATE" then
  103.         UpdateCount()
  104.     end
  105. end)

The buttons in this example are static and do not hide / show themselves properly, but this is further secure wrapping....

PS: beacons are not stackable, as far as i'm aware

Dejablue 04-24-17 07:31 PM

Quote:

Originally Posted by syncrow (Post 323038)
You're code re-creates your buttons constantly, which would cause massive error junk when you loot beacons right in combat....

It would be much better to pre-create all necessary buttons and only handle the count text upon bag updates.

Here is a little example on how it would look like:
Lua Code:
  1. local buttonSize = 36
  2. local padding = 0;
  3. local beacons = {
  4.     -- rares
  5.     [146923] = ""-- petrification
  6.     [147355] = ""-- bloodstrike
  7.     [146922] = ""-- fel growth
  8.     [146915] = ""-- greater Torment
  9.     [146912] = ""-- greater carnage
  10.     [146914] = ""-- greater engineering
  11.     [146910] = ""-- greater dominance
  12.     [146913] = ""-- greater warbeasts
  13.     [146911] = "",  -- greater firestorm
  14.    
  15.     -- uncommons
  16.     [146906] = "",  -- carnage
  17.     [146907] = "",  -- warbeasts
  18.     [146909] = "",  -- torment
  19.     [146908] = "",  -- engineering
  20.     [146903] = "",  -- dominance
  21.     [146905] = ""-- firestorm
  22. }
  23.  
  24. .....
  25.            
  26.         ....

The buttons in this example are static and do not hide / show themselves properly, but this is further secure wrapping....

PS: beacons are not stackable, as far as i'm aware

My first inclination was to create a table listing them all, but I chose to try this method as a sort of exercise as well as wanting to create them dynamically as found in the bags without knowing their specific names. This would future proof it if Blizzard decided to make a beacon of Murlocs, for example. There are also epic boss ones and epic ones that you take to each broken shore game

This isn't the entire code. I am not trying to show or hide them in combat, there is an inCombat check for a button that shows or hides them all that does nothing in combat.

They do indeed stack.:) to 20 as per itemStackCount = GetItemInfo()

Thank you for taking the time. I appreciate it very much. Let me know if you have any ideas about creating them as a loop. Gah I really don;t want to make static tables for this ;/

Dejablue 04-24-17 07:44 PM

Quote:

Originally Posted by Fizzlemizz (Post 323035)
I don't see where you check if a button already exists. Every OnEvent seems to trigger the creation of a new set of buttons for each specified item found.

This is the latest attempt in the OP code:

Code:

    if ((_G["BMUDButtonFS"..name])~=nil) then
        BMUDButton:SetNormalTexture(nil,"ARTWORK")
        BMUDButton:SetPushedTexture(nil,"ARTWORK")
        BMUDButton:SetHighlightTexture(nil,"ARTWORK")
        BMUDButtonFS:SetFormattedText("")
    end


Yeah, BAG_UPDATE event fires a billion times and is more of a debugging event that i can use at a vendor to sell and rebuy my beacons to see if this works.

Thanks for taking the time. Let me know if you think of anything else :)

Fizzlemizz 04-24-17 08:42 PM

Quote:

Originally Posted by Dejablue (Post 323042)
This is the latest attempt in the OP code:

Code:

    if ((_G["BMUDButtonFS"..name])~=nil) then
        BMUDButton:SetNormalTexture(nil,"ARTWORK")
        BMUDButton:SetPushedTexture(nil,"ARTWORK")
        BMUDButton:SetHighlightTexture(nil,"ARTWORK")
        BMUDButtonFS:SetFormattedText("")
    end


Yeah, BAG_UPDATE event fires a billion times and is more of a debugging event that i can use at a vendor to sell and rebuy my beacons to see if this works.

Thanks for taking the time. Let me know if you think of anything else :)

That code doesn't actually do anything because you're checking if a Fontstring you've just created exists, and it always will because, you've just created a new one, along with a new parent button.

if BAG_UPDATE fires a billion times your code will have created a billion new buttons and fontstrings.

Rather than this, you need to check if a button of the same name exists before you create a new one:
Code:

local BMUDButton
if not _G["BMUDButton"..name] then
        BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
        -- Create the extra bits here
else
        BMUDButton = _G["BMUDButton"..name]
        -- reset the extra bits here
end


Dejablue 04-24-17 10:12 PM

Quote:

Originally Posted by Fizzlemizz (Post 323043)
That code doesn't actually do anything because you're checking if a Fontstring you've just created exists, and it always will because, you've just created a new one, along with a new parent button.

if BAG_UPDATE fires a billion times your code will have created a billion new buttons and fontstrings.

Rather than this, you need to check if a button of the same name exists before you create a new one:
Code:

local BMUDButton
if not _G["BMUDButton"..name] then
        BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
        -- Create the extra bits here
else
        BMUDButton = _G["BMUDButton"..name]
        -- reset the extra bits here
end


Wouldn't I want to check if a button exists and then clear it and if it doesn't then create it?

What do I do to reset the buttons? I have tried myriad solutions, none work.


Quote:

BMUDButton:SetNormalTexture(nil,"ARTWORK")
BMUDButton:SetPushedTexture(nil,"ARTWORK")
BMUDButton:SetHighlightTexture(nil,"ARTWORK")
BMUDButtonFS:SetFormattedText("")
or

Code:

_G["BMUDButton"..name]:SetNormalTexture(nil,"ARTWORK")
_G["BMUDButton"..name]:SetPushedTexture(nil,"ARTWORK")
_G["BMUDButton"..name]:SetHighlightTexture(nil,"ARTWORK")
_G["BMUDButton"..name]:SetFormattedText("")


Fizzlemizz 04-24-17 10:30 PM

Something like this:

Lua Code:
  1. --Beam Me Up Deja Initialization Frame
  2.    
  3. local Ecount
  4. local Rcount
  5. local Ucount
  6.  
  7. local BeamMeUpDejaInitFrame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
  8.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_LOGIN")
  9.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  10.     BeamMeUpDejaInitFrame:RegisterEvent("LOOT_OPENED")
  11.     BeamMeUpDejaInitFrame:RegisterEvent("BAG_UPDATE")
  12.    
  13.     BeamMeUpDejaInitFrame:SetScript("OnEvent", function(self, event, ...)
  14.         Ecount = 0
  15.         Rcount = 0
  16.         Ucount = 0 
  17.         for bag = 0, 4, 1 do
  18.             for slot=1, GetContainerNumSlots(bag), 1 do
  19.                 local name = GetContainerItemLink(bag,slot)
  20.                 if name and string.find(name,"Sentinax Beacon") then
  21.                 --if name and string.find(name,"Hearthstone") then
  22.                     --ddebug()
  23.                     local _, itemCount = GetContainerItemInfo(bag, slot)
  24.                     local itemName, itemLink, itemRarity,_,_,_,_,itemStackCount,_,itemTexture,_ = GetItemInfo(name)
  25.                         --print(name, itemName,itemStackCount)--Debugging
  26.                     local texture = select(10,GetItemInfo(name))
  27.                     local w = 36
  28.                     local h = 36
  29.                     local x
  30.                     local y = 0
  31.                     if itemRarity == 4 then
  32.                         --print("Ecount is "..Ecount)--Debugging
  33.                         x = (Ecount*w)*1.1
  34.                         y = h*2.1
  35.                         Ecount = Ecount+1
  36.                     end
  37.                     if itemRarity == 3 then
  38.                         --print("Rcount is "..Rcount)--Debugging
  39.                         x = (Rcount*w)*1.1
  40.                         y = h*1.1
  41.                         Rcount = Rcount+1
  42.                     end
  43.                     if itemRarity == 2 then
  44.                         --print("Ucount is "..Ucount)--Debugging
  45.                         x = (Ucount*w)*1.1
  46.                         Ucount = Ucount+1
  47.                     end
  48.                     local BMUDButton
  49.                     if not _G["BMUDButton"..name] then -- Button does not exist so create it
  50.                         BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  51.                         BMUDButton.Label = BMUDButton:CreateFontString("$parent_FontString","OVERLAY")
  52.                         BMUDButton:RegisterForClicks("AnyUp", "AnyDown")
  53.                         BMUDButton:SetPoint("CENTER",x,y+32)
  54.                         BMUDButton:SetSize(w,h)
  55.                         BMUDButton.Label:SetPoint("BOTTOMRIGHT", BMUDButton)
  56.                         BMUDButton.Label:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
  57.                         BMUDButton.Label:SetTextColor(1, 1, 1);
  58.                         BMUDButton:SetAttribute("type","item")
  59.                         BMUDButton:SetAttribute("item",itemName)
  60.                         BMUDButton:HookScript("OnEnter", function(self)
  61.                                 GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  62.                                 GameTooltip:SetHyperlink(name)
  63.                                 GameTooltip:Show()
  64.                             end)
  65.                         BMUDButton:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
  66.                     else -- Button exists so reset to default state
  67.                         BMUDButton = _G["BMUDButton"..name]
  68.                         BMUDButton:SetNormalTexture(nil)
  69.                         BMUDButton:SetPushedTexture(nil)
  70.                         BMUDButton:SetHighlightTexture(nil)
  71.                         BMUDButton.Label:SetText("")
  72.  
  73.                     end
  74.                     if event == "BAG_UPDATE" then -- only set textures and text for this event
  75.                         BMUDButton.Label:SetFormattedText("%.0f", itemCount)
  76.                         BMUDButton:SetNormalTexture(itemTexture)
  77.                         BMUDButton:SetPushedTexture(itemTexture)
  78.                         BMUDButton:SetHighlightTexture(itemTexture)
  79.                         print("Bag updated:", name)
  80.                     end
  81.                 end
  82.             end
  83.         end
  84.     end)

EDIT: If the textures aren't going to change for each button then you wouldn't need to set them to nil and then re-set them, just the text value.
This also doesn't cover buttons created for beacons you no longer have. This would require either keeping a table of buttons created or checking for buttons created for beacons you don't have.

Dejablue 04-24-17 10:57 PM

Quote:

Originally Posted by Fizzlemizz (Post 323045)
Something like this:

Lua Code:
  1. --Beam Me Up Deja Initialization Frame
  2.    
  3. local Ecount
  4. local Rcount
  5. local Ucount
  6.  
  7. local BeamMeUpDejaInitFrame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
  8.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_LOGIN")
  9.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  10.     BeamMeUpDejaInitFrame:RegisterEvent("LOOT_OPENED")
  11.     BeamMeUpDejaInitFrame:RegisterEvent("BAG_UPDATE")
  12.    
  13.     BeamMeUpDejaInitFrame:SetScript("OnEvent", function(self, event, ...)
  14.         Ecount = 0
  15.         Rcount = 0
  16.         Ucount = 0 
  17.         for bag = 0, 4, 1 do
  18.             for slot=1, GetContainerNumSlots(bag), 1 do
  19.                 local name = GetContainerItemLink(bag,slot)
  20.                 if name and string.find(name,"Sentinax Beacon") then
  21.                 --if name and string.find(name,"Hearthstone") then
  22.                     --ddebug()
  23.                     local _, itemCount = GetContainerItemInfo(bag, slot)
  24.                     local itemName, itemLink, itemRarity,_,_,_,_,itemStackCount,_,itemTexture,_ = GetItemInfo(name)
  25.                         --print(name, itemName,itemStackCount)--Debugging
  26.                     local texture = select(10,GetItemInfo(name))
  27.                     local w = 36
  28.                     local h = 36
  29.                     local x
  30.                     local y = 0
  31.                     if itemRarity == 4 then
  32.                         --print("Ecount is "..Ecount)--Debugging
  33.                         x = (Ecount*w)*1.1
  34.                         y = h*2.1
  35.                         Ecount = Ecount+1
  36.                     end
  37.                     if itemRarity == 3 then
  38.                         --print("Rcount is "..Rcount)--Debugging
  39.                         x = (Rcount*w)*1.1
  40.                         y = h*1.1
  41.                         Rcount = Rcount+1
  42.                     end
  43.                     if itemRarity == 2 then
  44.                         --print("Ucount is "..Ucount)--Debugging
  45.                         x = (Ucount*w)*1.1
  46.                         Ucount = Ucount+1
  47.                     end
  48.                     local BMUDButton
  49.                     if not _G["BMUDButton"..name] then -- Button does not exist so create it
  50.                         BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  51.                         BMUDButton.Label = BMUDButton:CreateFontString("$parent_FontString","OVERLAY")
  52.                         BMUDButton:RegisterForClicks("AnyUp", "AnyDown")
  53.                         BMUDButton:SetPoint("CENTER",x,y+32)
  54.                         BMUDButton:SetSize(w,h)
  55.                         BMUDButton.Label:SetPoint("BOTTOMRIGHT", BMUDButton)
  56.                         BMUDButton.Label:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
  57.                         BMUDButton.Label:SetTextColor(1, 1, 1);
  58.                         BMUDButton:SetAttribute("type","item")
  59.                         BMUDButton:SetAttribute("item",itemName)
  60.                         BMUDButton:HookScript("OnEnter", function(self)
  61.                                 GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  62.                                 GameTooltip:SetHyperlink(name)
  63.                                 GameTooltip:Show()
  64.                             end)
  65.                         BMUDButton:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
  66.                     else -- Button exists so reset to default state
  67.                         BMUDButton = _G["BMUDButton"..name]
  68.                         BMUDButton:SetNormalTexture(nil)
  69.                         BMUDButton:SetPushedTexture(nil)
  70.                         BMUDButton:SetHighlightTexture(nil)
  71.                         BMUDButton.Label:SetText("")
  72.  
  73.                     end
  74.                     if event == "BAG_UPDATE" then -- only set textures and text for this event
  75.                         BMUDButton.Label:SetFormattedText("%.0f", itemCount)
  76.                         BMUDButton:SetNormalTexture(itemTexture)
  77.                         BMUDButton:SetPushedTexture(itemTexture)
  78.                         BMUDButton:SetHighlightTexture(itemTexture)
  79.                         print("Bag updated:", name)
  80.                     end
  81.                 end
  82.             end
  83.         end
  84.     end)

EDIT: If the textures aren't going to change for each button then you wouldn't need to set them to nil and then re-set them, just the text value.

Have you tired this in game?

This does exactly what I have already tried. It does not reset the text or the textures after the first creation.

Fizzlemizz 04-24-17 11:13 PM

See the last edit in the last post.

Make sure you're seeing what event last happened so you know if the button should or should not be visible.
Change the bag code too:
Code:

if event == "BAG_UPDATE" then -- only set textures and text for this event
        BMUDButton.Label:SetFormattedText("%.0f", itemCount)
        BMUDButton:SetNormalTexture(itemTexture)
        BMUDButton:SetPushedTexture(itemTexture)
        BMUDButton:SetHighlightTexture(itemTexture)
        print("Bag Updated", name)
else
        print("Other Registered event", name)
end

With this, after a /reload will not show the button because a non BAG_UPDATE event is posted last when entering the world.

Fizzlemizz 04-24-17 11:30 PM

Just as a note, the code will only show the number of beacons of a type in the last bag slot with that type inspected. I haven't really played 7.2 so if you can only hold one beacon in a slot or you can have more than one slot with one type of beacon, then you will only ever see one or the quantity in the last slot checked holding the item.

Dejablue 04-24-17 11:48 PM

Quote:

Originally Posted by Fizzlemizz (Post 323045)
Something like this:

Lua Code:
  1. --Beam Me Up Deja Initialization Frame
  2.    
  3. local Ecount
  4. local Rcount
  5. local Ucount
  6.  
  7. local BeamMeUpDejaInitFrame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
  8.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_LOGIN")
  9.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  10.     BeamMeUpDejaInitFrame:RegisterEvent("LOOT_OPENED")
  11.     BeamMeUpDejaInitFrame:RegisterEvent("BAG_UPDATE")
  12.    
  13.     BeamMeUpDejaInitFrame:SetScript("OnEvent", function(self, event, ...)
  14.         Ecount = 0
  15.         Rcount = 0
  16.         Ucount = 0 
  17.         for bag = 0, 4, 1 do
  18.             for slot=1, GetContainerNumSlots(bag), 1 do
  19.                 local name = GetContainerItemLink(bag,slot)
  20.                 if name and string.find(name,"Sentinax Beacon") then
  21.                 --if name and string.find(name,"Hearthstone") then
  22.                     --ddebug()
  23.                     local _, itemCount = GetContainerItemInfo(bag, slot)
  24.                     local itemName, itemLink, itemRarity,_,_,_,_,itemStackCount,_,itemTexture,_ = GetItemInfo(name)
  25.                         --print(name, itemName,itemStackCount)--Debugging
  26.                     local texture = select(10,GetItemInfo(name))
  27.                     local w = 36
  28.                     local h = 36
  29.                     local x
  30.                     local y = 0
  31.                     if itemRarity == 4 then
  32.                         --print("Ecount is "..Ecount)--Debugging
  33.                         x = (Ecount*w)*1.1
  34.                         y = h*2.1
  35.                         Ecount = Ecount+1
  36.                     end
  37.                     if itemRarity == 3 then
  38.                         --print("Rcount is "..Rcount)--Debugging
  39.                         x = (Rcount*w)*1.1
  40.                         y = h*1.1
  41.                         Rcount = Rcount+1
  42.                     end
  43.                     if itemRarity == 2 then
  44.                         --print("Ucount is "..Ucount)--Debugging
  45.                         x = (Ucount*w)*1.1
  46.                         Ucount = Ucount+1
  47.                     end
  48.                     local BMUDButton
  49.                     if not _G["BMUDButton"..name] then -- Button does not exist so create it
  50.                         BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  51.                         BMUDButton.Label = BMUDButton:CreateFontString("$parent_FontString","OVERLAY")
  52.                         BMUDButton:RegisterForClicks("AnyUp", "AnyDown")
  53.                         BMUDButton:SetPoint("CENTER",x,y+32)
  54.                         BMUDButton:SetSize(w,h)
  55.                         BMUDButton.Label:SetPoint("BOTTOMRIGHT", BMUDButton)
  56.                         BMUDButton.Label:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
  57.                         BMUDButton.Label:SetTextColor(1, 1, 1);
  58.                         BMUDButton:SetAttribute("type","item")
  59.                         BMUDButton:SetAttribute("item",itemName)
  60.                         BMUDButton:HookScript("OnEnter", function(self)
  61.                                 GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  62.                                 GameTooltip:SetHyperlink(name)
  63.                                 GameTooltip:Show()
  64.                             end)
  65.                         BMUDButton:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
  66.                     else -- Button exists so reset to default state
  67.                         BMUDButton = _G["BMUDButton"..name]
  68.                         BMUDButton:SetNormalTexture(nil)
  69.                         BMUDButton:SetPushedTexture(nil)
  70.                         BMUDButton:SetHighlightTexture(nil)
  71.                         BMUDButton.Label:SetText("")
  72.  
  73.                     end
  74.                     if event == "BAG_UPDATE" then -- only set textures and text for this event
  75.                         BMUDButton.Label:SetFormattedText("%.0f", itemCount)
  76.                         BMUDButton:SetNormalTexture(itemTexture)
  77.                         BMUDButton:SetPushedTexture(itemTexture)
  78.                         BMUDButton:SetHighlightTexture(itemTexture)
  79.                         print("Bag updated:", name)
  80.                     end
  81.                 end
  82.             end
  83.         end
  84.     end)

EDIT: If the textures aren't going to change for each button then you wouldn't need to set them to nil and then re-set them, just the text value.
This also doesn't cover buttons created for beacons you no longer have. This would require either keeping a table of buttons created or checking for buttons created for beacons you don't have.

Quote:

Originally Posted by Fizzlemizz (Post 323048)
Just as a note, the code will only show the number of beacons of a type in the last bag slot with that type inspected. I haven't really played 7.2 so if you can only hold one beacon in a slot or you can have more than one slot with one type of beacon, then you will only ever see one or the quantity in the last slot checked holding the item.

Making headway. The text does update.

Now to work on getting the textures to update after BAG_UPDATE like they do with a UI reload.

Thanks for the help. Any ideas on textures? Is that not possible becasue frames persist until reload? Any way to recycle the frames? Hmmm.

syncrow 04-24-17 11:51 PM

As beacons do not stack and consume an inventory slot each, you don't have to care about stackCount at all.
So you can raise your beacon count by 1 every time that particular beacon is found.

Why do you want to update the textures at all?
The buttons are named by the beacons name, so they are not be recycled anyway.

And a beacon's icon is static and doesn't get changed by blizzard.

Fizzlemizz 04-24-17 11:54 PM

Quote:

Originally Posted by Dejablue (Post 323049)
Any way to recycle the frames? Hmmm.

That's what we're doing.

You may also be having trouble with positioning. If you /fstack over the buttons you'll probably find you have a bunch of "BMUDButton"..xxx buttons positioned over the top of each other.

Edit: Thanks syncrow. You will need to keep a tally rather than just using the last itemCount value for the text.

The recycle code

Lua Code:
  1. local BMUDButton
  2. if not _G["BMUDButton"..name] then -- Button does not exist so create it
  3.     BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  4.     -- BMUDButton points to a shiney new button
  5. else
  6.     BMUDButton = _G["BMUDButton"..name]
  7.     -- BMUDButton points to the previously created button
  8. end

Dejablue 04-25-17 12:56 AM

Quote:

Originally Posted by syncrow (Post 323050)
As beacons do not stack and consume an inventory slot each, you don't have to care about stackCount at all.
So you can raise your beacon count by 1 every time that particular beacon is found.

Why do you want to update the textures at all?
The buttons are named by the beacons name, so they are not be recycled anyway.

And a beacon's icon is static and doesn't get changed by blizzard.

They do stack: http://i.imgur.com/46uZkI1.jpg

I want to completely hide the button and have them collapse so that you do not have spaces where you do not have beacons.

If I have two beacons I want to show them, If I then use one I want it to disappear. Then if I get a third one I want it to appear next to the one I still have, not leave a space and appear two or three icon spaces next to it, leaving empty space.

Dejablue 04-25-17 12:58 AM

Quote:

Originally Posted by Fizzlemizz (Post 323051)
That's what we're doing.

You may also be having trouble with positioning. If you /fstack over the buttons you'll probably find you have a bunch of "BMUDButton"..xxx buttons positioned over the top of each other.

Edit: Thanks syncrow. You will need to keep a tally rather than just using the last itemCount value for the text.

The recycle code

Lua Code:
  1. local BMUDButton
  2. if not _G["BMUDButton"..name] then -- Button does not exist so create it
  3.     BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  4.     -- BMUDButton points to a shiney new button
  5. else
  6.     BMUDButton = _G["BMUDButton"..name]
  7.     -- BMUDButton points to the previously created button
  8. end

I understand this. however I do not understand what you put in place of :

-- BMUDButton points to a shiney new button

or

-- BMUDButton points to the previously created button

I get the concept.

What the hell is the syntax?

What you have so far works great. But once I have a button and use it and no longer have the beacons, the button persists. No event will remove it. Any ideas?

Fizzlemizz 04-25-17 01:16 AM

This is what I pointed out previously, in edit admittedly so you may have missed it.

One idea.
Keep a table of buttons as they are created (no pre-determined, fixed table needed), hide them all at the start of the event and only show the ones that actually have a count on any given pass.

One idea, there may be better and it probably need refining.

Dejablue 04-25-17 01:39 AM

Quote:

Originally Posted by Fizzlemizz (Post 323055)
This is what I pointed out previously, in edit admittedly so you may have missed it.

One idea.
Keep a table of buttons as they are created (no pre-determined, fixed table needed), hide them all at the start of the event and only show the ones that actually have a count on any given pass.

One idea, there may be better and it probably need refining.

Cool idea. I'll play with that and see what I come up with. Thanks :)

Fizzlemizz 04-25-17 01:41 AM

This should handle hiding/showing (admitedly untested), collapsing/expanding would still have to be handled:
Lua Code:
  1. --Beam Me Up Deja Initialization Frame
  2.    
  3. local Ecount
  4. local Rcount
  5. local Ucount
  6. local Tally
  7.  
  8. local BeamMeUpDejaInitFrame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", BeamMeUpDejaDragFrame)
  9.     BeamMeUpDejaInitFrame.Beacons = ()
  10.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_LOGIN")
  11.     BeamMeUpDejaInitFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  12.     BeamMeUpDejaInitFrame:RegisterEvent("LOOT_OPENED")
  13.     BeamMeUpDejaInitFrame:RegisterEvent("BAG_UPDATE")
  14.    
  15.     BeamMeUpDejaInitFrame:SetScript("OnEvent", function(self, event, ...)
  16.         for k,v in pairs(self.Beacons) do
  17.             v:Hide()
  18.         end
  19.         Ecount = 0
  20.         Rcount = 0
  21.         Ucount = 0 
  22.         Tally = 0
  23.         for bag = 0, 4, 1 do
  24.             for slot=1, GetContainerNumSlots(bag), 1 do
  25.                 local name = GetContainerItemLink(bag,slot)
  26.                 if name and string.find(name,"Sentinax Beacon") then
  27. --              if name and string.find(name,"Hearthstone") then
  28.                     --ddebug()
  29.                     local _, itemCount = GetContainerItemInfo(bag, slot)
  30.                     Tally = Tally + itemCount
  31.                     local itemName, itemLink, itemRarity,_,_,_,_,itemStackCount,_,itemTexture,_ = GetItemInfo(name)
  32.                         --print(name, itemName,itemStackCount)--Debugging
  33.                     local texture = select(10,GetItemInfo(name))
  34.                     local w = 36
  35.                     local h = 36
  36.                     local x
  37.                     local y = 0
  38.                     if itemRarity == 4 then
  39.                         --print("Ecount is "..Ecount)--Debugging
  40.                         x = (Ecount*w)*1.1
  41.                         y = h*2.1
  42.                         Ecount = Ecount+1
  43.                     end
  44.                     if itemRarity == 3 then
  45.                         --print("Rcount is "..Rcount)--Debugging
  46.                         x = (Rcount*w)*1.1
  47.                         y = h*1.1
  48.                         Rcount = Rcount+1
  49.                     end
  50.                     if itemRarity == 2 then
  51.                         --print("Ucount is "..Ucount)--Debugging
  52.                         x = (Ucount*w)*1.1
  53.                         Ucount = Ucount+1
  54.                     end
  55.                     local BMUDButton
  56.                     if not _G["BMUDButton"..name] then -- Button does not exist so create it
  57.                         BMUDButton = CreateFrame("Button", "BMUDButton"..name, UIParent, "SecureActionButtonTemplate");
  58.                         self.Beacons["BMUDButton"..name] = BMUDButton
  59.                         BMUDButton.Label = BMUDButton:CreateFontString("$parent_FontString","OVERLAY")
  60.                         BMUDButton:RegisterForClicks("AnyUp", "AnyDown")
  61.                         BMUDButton:SetPoint("CENTER",x,y+32)
  62.                         BMUDButton:SetSize(w,h)
  63.                         BMUDButton.Label:SetPoint("BOTTOMRIGHT", BMUDButton)
  64.                         BMUDButton.Label:SetFont("Fonts\\FRIZQT__.TTF", 14, "THINOUTLINE")
  65.                         BMUDButton.Label:SetTextColor(1, 1, 1);
  66.                         BMUDButton:SetAttribute("type","item")
  67.                         BMUDButton:SetAttribute("item",itemName)
  68.                         BMUDButton:HookScript("OnEnter", function(self)
  69.                                 GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  70.                                 GameTooltip:SetHyperlink(name)
  71.                                 GameTooltip:Show()
  72.                             end)
  73.                         BMUDButton:HookScript("OnLeave", function(self) GameTooltip:Hide() end)
  74.                     else -- Button exists so reset to default state
  75.                         BMUDButton = _G["BMUDButton"..name]
  76.                         BMUDButton:SetNormalTexture(nil,"ARTWORK")
  77.                         BMUDButton:SetPushedTexture(nil,"ARTWORK")
  78.                         BMUDButton:SetHighlightTexture(nil,"ARTWORK")
  79.                         BMUDButton.Label:SetFormattedText("")
  80.  
  81.                     end
  82.                     if event == "BAG_UPDATE" then -- only set textures and text for this event
  83.                         BMUDButton.Label:SetFormattedText("%.0f", Tally)
  84.                         BMUDButton:SetNormalTexture(itemTexture)
  85.                         BMUDButton:SetPushedTexture(itemTexture)
  86.                         BMUDButton:SetHighlightTexture(itemTexture)
  87.                         BMUDButton:Show()
  88.                         print("Bag Updated", name, BMUDButton.Label:GetText())
  89.                     else
  90.                         print("Other event", event, name)
  91.                     end
  92.                 end
  93.             end
  94.         end
  95.     end)

There is now code that is surplus to requirements ;)

syncrow 04-25-17 01:48 AM

you could use "ContainerFrameItemButtonTemplate" instead of "SecureActionButtonTemplate".

pros:
  • clickability to use items
  • non secure (prevents taint)
  • can handle show / hide / positioning even while in combat

cons:
  • you have to create a header for each button (but thats fairly easy to achieve)

Edit: I'm going to prepare some code and explanation for you later... currently at work!^^

Dejablue 04-25-17 02:27 AM

Quote:

Originally Posted by syncrow (Post 323058)
you could use "ContainerFrameItemButtonTemplate" instead of "SecureActionButtonTemplate".

pros:
  • clickability to use items
  • non secure (prevents taint)
  • can handle show / hide / positioning even while in combat

cons:
  • you have to create a header for each button (but thats fairly easy to achieve)

Edit: I'm going to prepare some code and explanation for you later... currently at work!^^

Thank you so much ;) I look forward to it. Gonna play with ContainerFrameItemButtonTemplate for a while see what i can see. Maybe combine that with table.insert as buttons are created as per Fizzlemizz's suggestion, so we make tables like you suggested, and we may have something.

Cheers!

syncrow 04-25-17 01:35 PM

ok here is the code: (everything is tested, and should be properly debugged)

Lua Code:
  1. local buttonSize = 36;
  2. local padding = 2;
  3. local perRow = 6;
  4.  
  5. local function CreateButton(parent)
  6.     local button = CreateFrame("Frame", nil, parent)
  7.     local index = #parent.beacons + 1 or 1
  8.    
  9.     button:SetSize(buttonSize, buttonSize);
  10.     button.access = {}
  11.    
  12.     button.slot = CreateFrame("Button", nil, button, "ContainerFrameItemButtonTemplate")
  13.     button.slot:SetSize(buttonSize, buttonSize)
  14.     button.slot:SetPoint("CENTER")
  15.     button.slot:SetScript("OnEnter", function()
  16.         local bag = button:GetID()
  17.         local slot = button.slot:GetID()
  18.        
  19.         GameTooltip:SetOwner(button, "ANCHOR_CURSOR")
  20.         GameTooltip:SetBagItem(bag, slot);
  21.         GameTooltip:Show()
  22.     end)
  23.     button.slot:SetScript("OnLeave", GameTooltip_Hide)
  24.     button.slot:Show()
  25.    
  26.     button.slot.icon:SetTexCoord(0.075, 0.925, 0.075, 0.925);
  27.     button.slot.BattlepayItemTexture:Hide()
  28.    
  29.     return button
  30. end
  31.  
  32. local function UpdateButton(button)
  33.  
  34.     -- no access found: reset button
  35.     if #button.access == 0 then
  36.         button:Hide()
  37.         button.slot.Count:SetText("")
  38.         button.slot:SetNormalTexture("")
  39.         return
  40.     end
  41.  
  42.     local totalCount = 0;
  43.     local texture, bagID, slotID;
  44.    
  45.     for info, values in pairs(button.access) do
  46.         local bag, slot = unpack(values)
  47.         local icon, count = GetContainerItemInfo(bag, slot)
  48.        
  49.         if count then
  50.             totalCount = totalCount + count
  51.         end
  52.        
  53.         -- get the first possible identification for access later
  54.         if not bagID or not slotID or not tex then
  55.             texture = icon
  56.             bagID = bag
  57.             slotID = slot
  58.         end
  59.     end
  60.    
  61.     -- we do not need to show a count there is only 1 item existing
  62.     if totalCount == 1 then
  63.         totalCount = ""
  64.     end
  65.  
  66.     -- update count & texture
  67.     button.slot.Count:SetText(totalCount)
  68.     button.slot.icon:SetTexture(texture)
  69.        
  70.     -- update access
  71.     button:SetID(bagID)
  72.     button.slot:SetID(slotID)
  73.     button:Show()
  74. end
  75.  
  76. local function ResetButtons(self)
  77.     local table = self.beacons
  78.    
  79.     for _, button in pairs(table) do
  80.         button:Hide();
  81.         button.access = {}
  82.     end
  83. end
  84.  
  85. local function CacheAccess(self)
  86.     local table = self.beacons
  87.    
  88.     for bag = 0, 4 do
  89.         for slot = 1, GetContainerNumSlots(bag) do
  90.             local itemID = GetContainerItemID(bag, slot)
  91.            
  92.             if itemID then
  93.                 local name = GetItemInfo(itemID)
  94.                
  95.                 -- beacon found!!!
  96.                 if name and name:find("Sentinax Beacon") then
  97.                     local button = table[name]
  98.                    
  99.                     -- no button found: create it
  100.                     if not button then
  101.                         button = CreateButton(self)
  102.                         table[name] = button
  103.                     end
  104.                    
  105.                     -- store access
  106.                     if button then
  107.                         tinsert(button.access, {bag, slot})
  108.                     end
  109.                 end
  110.             end
  111.         end
  112.     end
  113. end
  114.  
  115. local function UpdateAllButtons(self)
  116.     local table = self.beacons
  117.     local index = 1;
  118.    
  119.     for _, button in pairs(table) do
  120.         if button then
  121.             UpdateButton(button)
  122.            
  123.             if button:IsShown() then
  124.                 local row = math.ceil( index / perRow)
  125.                 local col = (index-1) % perRow + 1
  126.                 local x = (buttonSize * (col-1) ) + ( padding * (col-1) )
  127.                 local y = (buttonSize * (row-1) ) + ( padding * (row-1) )
  128.                
  129.                 button:SetPoint("TOPLEFT", self, 0 + x, 0 - y)
  130.                
  131.                 index = index + 1
  132.             end
  133.         end
  134.     end
  135. end
  136.  
  137. local function UpdateFrameSize(self)
  138.     local table = self.beacons
  139.     local width, height, numRows, numCols
  140.     local shownBtns = 0
  141.    
  142.     for _, button in pairs(table) do
  143.         if button:IsShown() then
  144.             shownBtns = shownBtns + 1
  145.         end
  146.     end
  147.    
  148.     numRows = math.ceil( shownBtns / perRow )
  149.     numCols = (shownBtns < perRow) and shownBtns or perRow
  150.     width = (buttonSize * numCols) + (padding * (numCols - 1) )
  151.     height = numRows * buttonSize + (padding * (numRows - 1) )
  152.    
  153.     self:SetSize(width, height)
  154. end
  155.  
  156. local frame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", UIParent)
  157.  
  158. frame.beacons = {}
  159. frame:SetPoint("CENTER");
  160. frame:RegisterEvent("PLAYER_LOGIN")
  161. frame:SetScript("OnEvent", function(self, event, ...)
  162.     if event == "PLAYER_LOGIN" then
  163.         self:RegisterEvent("BAG_UPDATE")
  164.        
  165.         -- pre call the event for initialization
  166.         ResetButtons(self)
  167.         CacheAccess(self)
  168.         UpdateAllButtons(self)
  169.         UpdateFrameSize(self)
  170.        
  171.         return
  172.     end
  173.  
  174.     ResetButtons(self)
  175.     CacheAccess(self)
  176.     UpdateAllButtons(self)
  177.     UpdateFrameSize(self)
  178. end)

Note:
- Buttons are ordered from left to right, and from top to bottom
(can be changed on line 129 - switch math operators for x / y)

Dejablue 04-26-17 09:04 AM

Quote:

Originally Posted by syncrow (Post 323071)
ok here is the code: (everything is tested, and should be properly debugged)

Lua Code:
  1. local buttonSize = 36;
  2. local padding = 2;
  3. local perRow = 6;
  4.  
  5. local function CreateButton(parent)
  6.     local button = CreateFrame("Frame", nil, parent)
  7.     local index = #parent.beacons + 1 or 1
  8.    
  9.     button:SetSize(buttonSize, buttonSize);
  10.     button.access = {}
  11.    
  12.     button.slot = CreateFrame("Button", nil, button, "ContainerFrameItemButtonTemplate")
  13.     button.slot:SetSize(buttonSize, buttonSize)
  14.     button.slot:SetPoint("CENTER")
  15.     button.slot:SetScript("OnEnter", function()
  16.         local bag = button:GetID()
  17.         local slot = button.slot:GetID()
  18.        
  19.         GameTooltip:SetOwner(button, "ANCHOR_CURSOR")
  20.         GameTooltip:SetBagItem(bag, slot);
  21.         GameTooltip:Show()
  22.     end)
  23.     button.slot:SetScript("OnLeave", GameTooltip_Hide)
  24.     button.slot:Show()
  25.    
  26.     button.slot.icon:SetTexCoord(0.075, 0.925, 0.075, 0.925);
  27.     button.slot.BattlepayItemTexture:Hide()
  28.    
  29.     return button
  30. end
  31.  
  32. local function UpdateButton(button)
  33.  
  34.     -- no access found: reset button
  35.     if #button.access == 0 then
  36.         button:Hide()
  37.         button.slot.Count:SetText("")
  38.         button.slot:SetNormalTexture("")
  39.         return
  40.     end
  41.  
  42.     local totalCount = 0;
  43.     local texture, bagID, slotID;
  44.    
  45.     for info, values in pairs(button.access) do
  46.         local bag, slot = unpack(values)
  47.         local icon, count = GetContainerItemInfo(bag, slot)
  48.        
  49.         if count then
  50.             totalCount = totalCount + count
  51.         end
  52.        
  53.         -- get the first possible identification for access later
  54.         if not bagID or not slotID or not tex then
  55.             texture = icon
  56.             bagID = bag
  57.             slotID = slot
  58.         end
  59.     end
  60.    
  61.     -- we do not need to show a count there is only 1 item existing
  62.     if totalCount == 1 then
  63.         totalCount = ""
  64.     end
  65.  
  66.     -- update count & texture
  67.     button.slot.Count:SetText(totalCount)
  68.     button.slot.icon:SetTexture(texture)
  69.        
  70.     -- update access
  71.     button:SetID(bagID)
  72.     button.slot:SetID(slotID)
  73.     button:Show()
  74. end
  75.  
  76. local function ResetButtons(self)
  77.     local table = self.beacons
  78.    
  79.     for _, button in pairs(table) do
  80.         button:Hide();
  81.         button.access = {}
  82.     end
  83. end
  84.  
  85. local function CacheAccess(self)
  86.     local table = self.beacons
  87.    
  88.     for bag = 0, 4 do
  89.         for slot = 1, GetContainerNumSlots(bag) do
  90.             local itemID = GetContainerItemID(bag, slot)
  91.            
  92.             if itemID then
  93.                 local name = GetItemInfo(itemID)
  94.                
  95.                 -- beacon found!!!
  96.                 if name and name:find("Sentinax Beacon") then
  97.                     local button = table[name]
  98.                    
  99.                     -- no button found: create it
  100.                     if not button then
  101.                         button = CreateButton(self)
  102.                         table[name] = button
  103.                     end
  104.                    
  105.                     -- store access
  106.                     if button then
  107.                         tinsert(button.access, {bag, slot})
  108.                     end
  109.                 end
  110.             end
  111.         end
  112.     end
  113. end
  114.  
  115. local function UpdateAllButtons(self)
  116.     local table = self.beacons
  117.     local index = 1;
  118.    
  119.     for _, button in pairs(table) do
  120.         if button then
  121.             UpdateButton(button)
  122.            
  123.             if button:IsShown() then
  124.                 local row = math.ceil( index / perRow)
  125.                 local col = (index-1) % perRow + 1
  126.                 local x = (buttonSize * (col-1) ) + ( padding * (col-1) )
  127.                 local y = (buttonSize * (row-1) ) + ( padding * (row-1) )
  128.                
  129.                 button:SetPoint("TOPLEFT", self, 0 + x, 0 - y)
  130.                
  131.                 index = index + 1
  132.             end
  133.         end
  134.     end
  135. end
  136.  
  137. local function UpdateFrameSize(self)
  138.     local table = self.beacons
  139.     local width, height, numRows, numCols
  140.     local shownBtns = 0
  141.    
  142.     for _, button in pairs(table) do
  143.         if button:IsShown() then
  144.             shownBtns = shownBtns + 1
  145.         end
  146.     end
  147.    
  148.     numRows = math.ceil( shownBtns / perRow )
  149.     numCols = (shownBtns < perRow) and shownBtns or perRow
  150.     width = (buttonSize * numCols) + (padding * (numCols - 1) )
  151.     height = numRows * buttonSize + (padding * (numRows - 1) )
  152.    
  153.     self:SetSize(width, height)
  154. end
  155.  
  156. local frame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", UIParent)
  157.  
  158. frame.beacons = {}
  159. frame:SetPoint("CENTER");
  160. frame:RegisterEvent("PLAYER_LOGIN")
  161. frame:SetScript("OnEvent", function(self, event, ...)
  162.     if event == "PLAYER_LOGIN" then
  163.         self:RegisterEvent("BAG_UPDATE")
  164.        
  165.         -- pre call the event for initialization
  166.         ResetButtons(self)
  167.         CacheAccess(self)
  168.         UpdateAllButtons(self)
  169.         UpdateFrameSize(self)
  170.        
  171.         return
  172.     end
  173.  
  174.     ResetButtons(self)
  175.     CacheAccess(self)
  176.     UpdateAllButtons(self)
  177.     UpdateFrameSize(self)
  178. end)

Note:
- Buttons are ordered from left to right, and from top to bottom
(can be changed on line 129 - switch math operators for x / y)

Thanks Syn. I added you and Fizz as contributors and pushed it out to release. Found a couple bugs since. Text still doesn't update, but much headway has been made. Thank you for all of your help. Feel free to reply here or on Curse or PM me here or on Curse if you have suggestions, fixes, questions, etc. This is far from over, only just beginning.

https://mods.curse.com/addons/wow/265345-beammeupdeja

Cheers!

jeruku 04-26-17 03:39 PM

For this particular use, since you are scanning the bag anyway, I would recommend using the event BAG_UPDATE_DELAYED instead of BAG_UPDATE.

Dejablue 04-27-17 12:12 AM

Quote:

Originally Posted by jeruku (Post 323097)
For this particular use, since you are scanning the bag anyway, I would recommend using the event BAG_UPDATE_DELAYED instead of BAG_UPDATE.

Yeah, good call. I'll have to play with the events when I get a chance. Thanks :)

Kakjens 04-27-17 02:21 AM

Quote:

Originally Posted by syncrow (Post 323071)
ok here is the code: (everything is tested, and should be properly debugged)

Lua Code:
  1. local buttonSize = 36;
  2. local padding = 2;
  3. local perRow = 6;
  4.  
  5. local function CreateButton(parent)
  6.     local button = CreateFrame("Frame", nil, parent)
  7.     local index = #parent.beacons + 1 or 1
  8.    
  9.     button:SetSize(buttonSize, buttonSize);
  10.     button.access = {}
  11.    
  12.     button.slot = CreateFrame("Button", nil, button, "ContainerFrameItemButtonTemplate")
  13.     button.slot:SetSize(buttonSize, buttonSize)
  14.     button.slot:SetPoint("CENTER")
  15.     button.slot:SetScript("OnEnter", function()
  16.         local bag = button:GetID()
  17.         local slot = button.slot:GetID()
  18.        
  19.         GameTooltip:SetOwner(button, "ANCHOR_CURSOR")
  20.         GameTooltip:SetBagItem(bag, slot);
  21.         GameTooltip:Show()
  22.     end)
  23.     button.slot:SetScript("OnLeave", GameTooltip_Hide)
  24.     button.slot:Show()
  25.    
  26.     button.slot.icon:SetTexCoord(0.075, 0.925, 0.075, 0.925);
  27.     button.slot.BattlepayItemTexture:Hide()
  28.    
  29.     return button
  30. end
  31.  
  32. local function UpdateButton(button)
  33.  
  34.     -- no access found: reset button
  35.     if #button.access == 0 then
  36.         button:Hide()
  37.         button.slot.Count:SetText("")
  38.         button.slot:SetNormalTexture("")
  39.         return
  40.     end
  41.  
  42.     local totalCount = 0;
  43.     local texture, bagID, slotID;
  44.    
  45.     for info, values in pairs(button.access) do
  46.         local bag, slot = unpack(values)
  47.         local icon, count = GetContainerItemInfo(bag, slot)
  48.        
  49.         if count then
  50.             totalCount = totalCount + count
  51.         end
  52.        
  53.         -- get the first possible identification for access later
  54.         if not bagID or not slotID or not tex then
  55.             texture = icon
  56.             bagID = bag
  57.             slotID = slot
  58.         end
  59.     end
  60.    
  61.     -- we do not need to show a count there is only 1 item existing
  62.     if totalCount == 1 then
  63.         totalCount = ""
  64.     end
  65.  
  66.     -- update count & texture
  67.     button.slot.Count:SetText(totalCount)
  68.     button.slot.icon:SetTexture(texture)
  69.        
  70.     -- update access
  71.     button:SetID(bagID)
  72.     button.slot:SetID(slotID)
  73.     button:Show()
  74. end
  75.  
  76. local function ResetButtons(self)
  77.     local table = self.beacons
  78.    
  79.     for _, button in pairs(table) do
  80.         button:Hide();
  81.         button.access = {}
  82.     end
  83. end
  84.  
  85. local function CacheAccess(self)
  86.     local table = self.beacons
  87.    
  88.     for bag = 0, 4 do
  89.         for slot = 1, GetContainerNumSlots(bag) do
  90.             local itemID = GetContainerItemID(bag, slot)
  91.            
  92.             if itemID then
  93.                 local name = GetItemInfo(itemID)
  94.                
  95.                 -- beacon found!!!
  96.                 if name and name:find("Sentinax Beacon") then
  97.                     local button = table[name]
  98.                    
  99.                     -- no button found: create it
  100.                     if not button then
  101.                         button = CreateButton(self)
  102.                         table[name] = button
  103.                     end
  104.                    
  105.                     -- store access
  106.                     if button then
  107.                         tinsert(button.access, {bag, slot})
  108.                     end
  109.                 end
  110.             end
  111.         end
  112.     end
  113. end
  114.  
  115. local function UpdateAllButtons(self)
  116.     local table = self.beacons
  117.     local index = 1;
  118.    
  119.     for _, button in pairs(table) do
  120.         if button then
  121.             UpdateButton(button)
  122.            
  123.             if button:IsShown() then
  124.                 local row = math.ceil( index / perRow)
  125.                 local col = (index-1) % perRow + 1
  126.                 local x = (buttonSize * (col-1) ) + ( padding * (col-1) )
  127.                 local y = (buttonSize * (row-1) ) + ( padding * (row-1) )
  128.                
  129.                 button:SetPoint("TOPLEFT", self, 0 + x, 0 - y)
  130.                
  131.                 index = index + 1
  132.             end
  133.         end
  134.     end
  135. end
  136.  
  137. local function UpdateFrameSize(self)
  138.     local table = self.beacons
  139.     local width, height, numRows, numCols
  140.     local shownBtns = 0
  141.    
  142.     for _, button in pairs(table) do
  143.         if button:IsShown() then
  144.             shownBtns = shownBtns + 1
  145.         end
  146.     end
  147.    
  148.     numRows = math.ceil( shownBtns / perRow )
  149.     numCols = (shownBtns < perRow) and shownBtns or perRow
  150.     width = (buttonSize * numCols) + (padding * (numCols - 1) )
  151.     height = numRows * buttonSize + (padding * (numRows - 1) )
  152.    
  153.     self:SetSize(width, height)
  154. end
  155.  
  156. local frame = CreateFrame("Frame", "BeamMeUpDejaInitFrame", UIParent)
  157.  
  158. frame.beacons = {}
  159. frame:SetPoint("CENTER");
  160. frame:RegisterEvent("PLAYER_LOGIN")
  161. frame:SetScript("OnEvent", function(self, event, ...)
  162.     if event == "PLAYER_LOGIN" then
  163.         self:RegisterEvent("BAG_UPDATE")
  164.        
  165.         -- pre call the event for initialization
  166.         ResetButtons(self)
  167.         CacheAccess(self)
  168.         UpdateAllButtons(self)
  169.         UpdateFrameSize(self)
  170.        
  171.         return
  172.     end
  173.  
  174.     ResetButtons(self)
  175.     CacheAccess(self)
  176.     UpdateAllButtons(self)
  177.     UpdateFrameSize(self)
  178. end)

Note:
- Buttons are ordered from left to right, and from top to bottom
(can be changed on line 129 - switch math operators for x / y)

Didn't test in-game but seems like creation of button.slot.Count after line 27 is missing.

syncrow 04-27-17 02:27 AM

Quote:

Originally Posted by Kakjens (Post 323105)
Didn't test in-game but seems like creation of button.slot.Count after line 27 is missing.

button.slot inherits from "ContainerFrameItemButtonTemplate" which inherits from "ItemButtonTemplate" that has the childkey .Count as a font string


Edit:
@Deja, i would also recomment, using my code seperately instead of calling it inside a OnEvent function, the created frame was simply renamed by me but should be used as your initFrame...

Kakjens 04-27-17 02:34 AM

Thanks, after posting thought something similar, and found in ItemButtonTemplate.xml that it's indeed defined.

syncrow 04-27-17 02:50 AM

I'm going to hard test the complete addon on Friday.

Should I upload a new beta version on curse once debugged and changes made?

Dejablue 04-27-17 03:10 AM

Quote:

Originally Posted by syncrow (Post 323108)
I'm going to hard test the complete addon on Friday.

Should I upload a new beta version on curse once debugged and changes made?

Sure I will give you access.

Kakjens 04-27-17 11:24 AM

In line 54 probably a typo: instead of variable "texture" non-existant "tex" was used.
Removed external BeamMeUpDejaInitFrame. Don't know why but for item count updates to work, had to use CreateFontString in CreateButton.
Modified version sent to Deja.
Probably there's still much to fix/improve.

syncrow 04-27-17 01:12 PM

Begun fixing the beacon bar part:
  • Count display (fixed)
  • Disabled "LeftClick" to prevent some annoying ContainerFrameItemButtonTemplate stuff working (we only want the click to use part here)
  • Beacons are now sorted based on Quality > Count > Name
  • Merged some functions together to make the code cleaner

By the way, searching for names rather than using predefined itemIDs like mentions in my first solution, will be an issue for non english clients
Except we want to handle each localization manually...

Dejablue 04-27-17 11:01 PM

Quote:

Originally Posted by syncrow (Post 323116)
Begun fixing the beacon bar part:
  • Count display (fixed)
  • Disabled "LeftClick" to prevent some annoying ContainerFrameItemButtonTemplate stuff working (we only want the click to use part here)
  • Beacons are now sorted based on Quality > Count > Name
  • Merged some functions together to make the code cleaner

By the way, searching for names rather than using predefined itemIDs like mentions in my first solution, will be an issue for non english clients
Except we want to handle each localization manually...

For localization we will ahve to do something like:

Code:

if name and name:find("Sentinax Beacon" or "Netherchunck") then

We also need to query other items, like nether shards and boss summon stones. This is going to require tables... bleh.

As for localization, we could simply search for local names, making our list, ostensibly, smaller, adding them to the table for Chinese, Russian, Portuguese, etc.

But you are correct that we wont have to worry about localization if we use item IDs.

syncrow 04-27-17 11:47 PM

Quote:

Originally Posted by Dejablue (Post 323122)
For localization we will ahve to do something like:

Code:

if name and name:find("Sentinax Beacon" or "Netherchunck") then

We also need to query other items, like nether shards and boss summon stones. This is going to require tables... bleh.

As for localization, we could simply search for local names, making our list, ostensibly, smaller, adding them to the table for Chinese, Russian, Portuguese, etc.

But you are correct that we wont have to worry about localization if we use item IDs.

tracking nethershards and legion fall resources is quite easy:
simply loop through the currency list and get your information

I don't know what really speaks against a table that we want to use for tracking
- localization friendly
- can be maintained updated super easily by just adding / removing itemIDs
- we can throw updates without touching anything besides the itemID table for new items to track...

Dejablue 04-28-17 01:15 AM

Quote:

Originally Posted by syncrow (Post 323123)
tracking nethershards and legion fall resources is quite easy:
simply loop through the currency list and get your information

I don't know what really speaks against a table that we want to use for tracking
- localization friendly
- can be maintained updated super easily by just adding / removing itemIDs
- we can throw updates without touching anything besides the itemID table for new items to track...

Correct. I had not considered localizations. We should change to a table with the items we wish to track as you originally suggested. As for what speaks against a table; reduced/no maintenance in the future should Blizzard change things (like create Sentinax Beacon of the Murloc) we won't have to add it specifically, name search will add it which is particularly beneficial if none of us are playing the game and keeping up with it. My original goal was to execute this with string search functions, for the sake of it. It is doable, but with localization concerns I don't think it is worth it, especially if we simply make a list of localized strings to look for.

So the project went from looking for three names to looking for 33 names across 11 locales.

May as well just look for IDs instead.

syncrow 04-28-17 03:22 AM

Deja,

how do you want the beacon bar to be displayed exactly?
  • each quality in a seperate row?
  • dynamic with a specific sorting?
  • something else maybe


[Rare Beacons]
[Uncommen Beacons]
[Other Items]


Static layout:
[X][X][X][X][X][X][X][X][X]
[X][X][X][X][X][X]
[X][X][X]


dynamic: (#15 - live)
[X][X][X][X][X][X]
[X][X][X][X][X][X]
[X][X][X][X][X][X]


mixed 1:
[X][X][X][X][X][X]
[X][X][X][X][X][X]
[X][X][X][X][X][X]


mixed 2:
[X][X][X][X][X]
[X][X][X][X][X]
[X][X][X][X][X]
[X][X][X]

Kakjens 04-28-17 09:33 AM

I think ability to detect new Sentinax Beacons is interesting. Requirement to localize the search string - not so much. Therefore maybe some fuzzy detector whether or not this item is Sentinax Beacon can be written. Using currently known Sentinax Beacons a common string with maximal length could be calculated and used for searching.
Previously thought of more exotic ways of creation of the search string but currently think this is more or less plausible compared to others.

syncrow 04-28-17 09:45 AM

broken shore stuff would be a thing till 7.3 then everything will to argus, so could bet that no new beacon or any new broken shore grind related item will be added after 7.2.5 launch

and even when...add 2 spellIDs throw update, fix and everything is happy.
You simply cant prevent addons to be updated from time to time, but that is just my standpoint

Kakjens 04-28-17 11:16 AM

Indeed, in this specific example creation of search string through combinatorics is overkill. I was just surprised by possibility of automation of creation of feature extractor, as an input using few items.
But really, adding of few itemIDs after discovery of the new elusive Sentinax Beacons would be much easier.

Dejablue 04-28-17 12:31 PM

I want the layout to be static rarity rows that are dynamically created, i.e. collapse as created for each rarity per row.

[X][X][X] -- Netherchunk and Zone portals(see below)
[X][X] -- Epic
[X][X] -- Crafting Rare
[X][X][X][X] -- Rare
[X][X][X][X][X][X] -- Uncommon



__________________________________________

Netherchunk and Zone portals(see below)

Epic:
[146921] = "", -- Illisthyndria
[146920] = "", -- Fel Obliterator
[146919] = "", -- An'thyna:An'thyna
[146918] = "", -- Force-Commander Xillious
[146917] = "", -- Skulguloth
[146916] = "", -- Than'otalion

Crafting Rare:
[147355] = "", -- bloodstrike
[146923] = "", -- petrification
[146922] = "", -- fel growth

Rare:
[146915] = "", -- greater torment
[146914] = "", -- greater engineering
[146913] = "", -- greater warbeasts
[146912] = "", -- greater carnage
[146911] = "", -- greater firestorm
[146910] = "", -- greater dominance

Uncommon:
[146909] = "", -- torment
[146908] = "", -- engineering
[146907] = "", -- warbeasts
[146906] = "", -- carnage
[146905] = "", -- firestorm
[146903] = "", -- dominance
_____________________

Zone portals are rare(IIRC they are Epic). They open a portal in a zone, like Skyhorn in Highmountain. You go there, click it and a portal opens with aq miniboss. You kill it and loot exactly 300 Nethershards. I have had 2 drop, went and did them, but have not seen any since. Others can help you kill the boss but they do not get loot AFAIK. That being said, I forget what their name is and my google/WoWHead - fu has failed me to bring up their names.

At any rate, the very top row should be consumable you want to use right away, like Netherchunk and these zone portals.

Dejablue 05-01-17 08:06 AM

Hey Syncrow, any progress? If you are crunched for time, I can work on rewriting for tables, I just need help figuring out resetting the text.

Cheers!

syncrow 05-05-17 07:27 AM

Pretty much no time these days, sry

Dejablue 05-05-17 12:13 PM

Quote:

Originally Posted by syncrow (Post 323235)
Pretty much no time these days, sry

We worked it out man, np. I would have liked to have seen your solutions. Feel free to pop in with any suggestions or PM me.

Here is the project on WoWInterface and on Curse in case you missed it.

Cheers!


All times are GMT -6. The time now is 01:52 PM.

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