WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Show/Hide Custom Frame in Combat Lockdown (https://www.wowinterface.com/forums/showthread.php?t=58808)

henbe 06-25-21 02:39 AM

Show/Hide Custom Frame in Combat Lockdown
 
Hello everyone, Henbe here. I am quite inexperienced in lua and coding in general, please help me understand how to show/hide frames in secured enviroment. I have a little piece of code that creates a frame with texture and shows/hides on toggling bags. Outside of combat it works just fine, but I get an error while in combat.

Lua Code:
  1. -- Button
  2. local BB = CreateFrame("Button","FBags_BagButton",UIParent,"SecureActionButtonTemplate")
  3. BB:SetPoint("CENTER", UIParent, "CENTER",0,500)
  4. BB:SetSize(50, 50)
  5. local ButtonTexture = BB:CreateTexture("ButtonTexture", "BACKGROUND")
  6. ButtonTexture:SetTexture("Interface\\Buttons\\Button-Backpack-Up")
  7. ButtonTexture:SetPoint("CENTER","FBags_BagButton","CENTER")
  8. ButtonTexture:SetSize(50, 50)
  9. BB:SetScript("OnClick", function(self)
  10.     FB:SetShown(not FB:IsShown())
  11.     print("Bag Clicked")
  12. end)
  13. BB:RegisterEvent("PLAYER_ENTERING_WORLD")
  14.  
  15.  
  16.  
  17. FB = CreateFrame("Button","FBags",UIParent, "ActionButtonTemplate")
  18. FB:SetFrameStrata("BACKGROUND")
  19. FB:SetPoint("CENTER", UIParent, "CENTER",-400,300)
  20. FB:SetSize(50, 50)
  21. FB:Hide()
  22.  
  23.     -- Bag Layout
  24. for bagid = 0,4 do
  25.     for bagslot = 1,GetContainerNumSlots(bagid) do
  26.         local icon, itemCount, locked,  ContItemQuality, readable, lootable, ContItemLink, isFiltered, noValue, ContItemID = GetContainerItemInfo(bagid, bagslot)
  27.         local SlotFrame = CreateFrame("Button", "Bag"..bagid.."Slot"..bagslot, FB,"SecureActionButtonTemplate, ActionButtonTemplate",100*bagid+bagslot)
  28.        
  29.         SlotFrame:SetSize(40,40)
  30.         SlotFrame:SetPoint("TOP",FB,"BOTTOM",40*bagslot,-40*bagid)
  31.        
  32.         SlotFrame:RegisterEvent("BAG_UPDATE")
  33.         SlotFrame:RegisterEvent("ITEM_LOCKED")
  34.         SlotFrame:RegisterEvent("ITEM_UNLOCKED")
  35.         SlotFrame:RegisterForClicks("AnyUp")
  36.        
  37.             -- to use items
  38.         SlotFrame:SetAttribute("type2", "item")
  39.         SlotFrame:SetAttribute("bag", bagid)
  40.         SlotFrame:SetAttribute("slot", bagslot)
  41.  
  42.  
  43.             -- adding a texture, text, cooldown
  44.         local texture = SlotFrame:CreateTexture("Bag"..bagid.."Slot"..bagslot.."Texture", "BACKGROUND")
  45.         local text = SlotFrame:CreateFontString("Bag"..bagid.."Slot"..bagslot.."Text", "OVERLAY")
  46.         text:SetFont("Fonts\\FRIZQT___CYR.TTF", 12, "OUTLINE")
  47.         text:SetPoint("BOTTOMRIGHT",SlotFrame,"BOTTOMRIGHT")
  48.         local cooldown = CreateFrame("Cooldown", "Bag"..bagid.."Slot"..bagslot.."Cooldown", SlotFrame, "CooldownFrameTemplate")
  49.         cooldown:SetAllPoints()
  50.  
  51.             -- widget scripts
  52.                 -- Tooltip
  53.         SlotFrame:SetScript("OnEnter", function()
  54.             GameTooltip:SetOwner(SlotFrame, "ANCHOR_CURSOR")
  55.             GameTooltip:SetBagItem(bagid, bagslot); -- SetBagItem(bagid, bagslot)
  56.             GameTooltip:Show()
  57.         end)
  58.        
  59.         SlotFrame:SetScript("OnLeave", function()
  60.             GameTooltip:Hide()
  61.         end)
  62.  
  63.                 -- Item moving
  64.         SlotFrame:SetScript("OnMouseUp", function(self, button)
  65.             local CursorItem, CursorItemID, CursorItemLink = GetCursorInfo()
  66.             local x = GetMouseFocus():GetID()
  67.             local b = (x-x%100)/100
  68.             local s = x%100
  69.             local icon1, itemCount1, locked1, quality1, readable1, lootable1, itemLink1, isFiltered1, noValue1, ContItemID1 = GetContainerItemInfo(b, s)
  70.             if not (b == 0 and s == 0) then
  71.                 if button == "LeftButton" then
  72.                     if GetContainerItemInfo(b, s) and not GetCursorInfo() then
  73.                         PickupContainerItem(b, s)
  74.                         print("Picking up bag "..b.." slot "..s.." using "..button)
  75.                     elseif GetCursorInfo() and not GetContainerItemInfo(b, s) then
  76.                         PickupContainerItem(b, s)
  77.                         print("Putting down bag "..b.." slot "..s.." using "..button)
  78.                     elseif not GetCursorInfo() and not GetContainerItemInfo(b, s) then
  79.                         print("Nothing to pick up")
  80.                     elseif ContItemID1 == 82800 then
  81.                         PickupContainerItem(b, s)
  82.                         print("Putting down bag "..b.." slot "..s.." using "..button)
  83.                     elseif CursorItemID == ContItemID1 then
  84.                         ClearCursor()
  85.                         print("Same cell, putting down")
  86.                     elseif CursorItemID ~= ContItemID1 then
  87.                         PickupContainerItem(b, s)
  88.                         print("Filled cell, swapping")
  89.                     end
  90.                 end
  91.             end
  92.         end)
  93.  
  94.  
  95.             -- Bag Update, cooldowns, icons
  96.         local function eventHandler(self, event, ...)
  97.             local icon, itemCount, locked, quality, readable, lootable, itemLink, isFiltered, noValue, itemID = GetContainerItemInfo(bagid, bagslot)
  98.             local startTime, duration, isEnabled = GetContainerItemCooldown(bagid, bagslot)
  99.             if event == "BAG_UPDATE" then
  100.                 if GetContainerItemInfo(bagid, bagslot) then
  101.                     if duration>0 then
  102.                         cooldown:SetCooldown(startTime,duration)
  103.                         print("cooldown started in "..bagid.." "..bagslot)
  104.                     else
  105.                         cooldown:SetCooldown(0,0)
  106.                     end
  107.                     texture:SetTexture(icon)
  108.                     texture:SetPoint("CENTER","Bag"..bagid.."Slot"..bagslot,"CENTER")
  109.                     texture:SetSize(40, 40)
  110.                     if itemCount>1 then
  111.                         text:SetText(itemCount)
  112.                     else
  113.                         text:SetText(nil)
  114.                     end
  115.                 else
  116.                     texture:SetTexture("Interface\\BUTTONS\\UI-Slot-Background.blp")
  117.                     texture:SetPoint("CENTER","Bag"..bagid.."Slot"..bagslot,"CENTER",11,-10)
  118.                     texture:SetSize(60, 60)
  119.                     text:SetText()
  120.                     cooldown:SetCooldown(0,0)
  121.                 end
  122.             end
  123.         end
  124.         SlotFrame:SetScript("OnEvent", eventHandler);
  125.     end
  126. end
  127.  
  128.  
  129. -- "OpenBackpack" "CloseBackpack" "ToggleBackpack" "CloseAllBags" "OpenAllBags" "ToggleAllBags"
  130. -- hook functions
  131.  
  132. hooksecurefunc(
  133.     "CloseAllBags",function()
  134.         if FB:IsShown() then
  135.             FB:Hide()
  136.         end
  137.         print("CloseAllBags hookedfunction fired")
  138.     end
  139. )
  140.  
  141. hooksecurefunc(
  142.     "ToggleAllBags",function()
  143.         FB:SetShown(not FB:IsShown())
  144.         print("ToggleAllBags hookedfunction fired")
  145.     end
  146. )

Xrystal 06-25-21 03:05 AM

I handle user interaction using the pre and post combat events.

PLAYER_REGEN_DISABLED
PLAYER_REGEN_ENABLED

When the event DISABLED is triggered this means you are about to initiate combat so do what you need to stop people from using your frames during this time. Either disable buttons or hide the frame etc.

When the event ENABLED is triggered combat is finished and you can now allow them to interact with the frames. Enable buttons or show the frame etc.

henbe 06-25-21 03:27 AM

Got it, but how do I show/hide this frame during combat? If I do it, let's say, to create bags layout, I might want to open bags in combat and use potion I forgot to put on action bars.

Xrystal 06-25-21 05:40 AM

This is how nUI handles clicking a button during combat ( it switches display panels linked to the button ), I only maintain the addon so not all elements of the addon are fully understandable to me but I have dabbled with secure frames to fix action button issues so some of this does make some element of sense to me now. Hopefully, reading through it will give you something to help you with your own button.

Lua Code:
  1. local frame      = CreateFrame( "Frame", "nUI_InfoPanelSelector", background, "SecureFrameTemplate" );
  2. frame.button     = CreateFrame( "Button", "$parent_Button", frame, "SecureHandlerClickTemplate" );
  3.  
  4. frame.button:SetAttribute(
  5.     "_onclick",
  6.     [[
  7.         if not IsAltKeyDown() or not IsControlKeyDown() or IsShiftKeyDown() then
  8.                
  9.             if button == "LeftButton" then 
  10.                 if CurrentPanel == #PanelList then
  11.                     CurrentPanel = 1;
  12.                 else
  13.                     CurrentPanel = CurrentPanel+1;
  14.                 end
  15.             elseif button == "RightButton" then
  16.                 if CurrentPanel == 1 then
  17.                     CurrentPanel = #PanelList;
  18.                 else
  19.                     CurrentPanel = CurrentPanel-1;
  20.                 end
  21.             end
  22.        
  23.             for i=1,#PanelList do
  24.                 local frame = self:GetFrameRef( PanelList[i] );
  25.                
  26.                 if i == CurrentPanel then
  27.                     frame:Show();
  28.                 else
  29.                     frame:Hide();
  30.                 end
  31.             end
  32.         end
  33.     ]]
  34. );
  35. frame.button:SetAllPoints( frame );
  36. frame:SetAttribute( "addchild", frame.button );


Elsewhere in the code the panel list is also setup in secure mode
Lua Code:
  1. for item in pairs( rotation ) do       
  2.             local name = rotation[item].name;          
  3.             frame.button:SetAttribute( "nUI_InfoPanel"..item, name );
  4.             frame.button:SetFrameRef( name, rotation[item].frame );
  5.         end
  6.  
  7.         frame.button:Execute(
  8.             [[
  9.                 local i = 1;
  10.                
  11.                 PanelList = newtable();
  12.                
  13.                 while true do
  14.                    
  15.                     local panel_name = self:GetAttribute( "nUI_InfoPanel"..i );
  16.                    
  17.                     if not panel_name then
  18.                         break;
  19.                     end
  20.                    
  21.                     PanelList[i] = panel_name;
  22.                     i = i+1;
  23.                    
  24.                 end
  25.                
  26.                 CurrentPanel = self:GetAttribute( "state" ) or 1;
  27.             ]]
  28.         );

Xrystal 06-25-21 05:42 AM

But, seeing as you are attempting to deal with custom bag management, you might want to take a look at some of the others out there as they may have added secure frame management in their code.

One that sounds plausible ( I haven't checked the code ) is : https://www.wowinterface.com/downloa...agsNivaya.html

Seerah 06-26-21 02:55 PM

Wait, is your FB2 frame just showing a texture? Why are you creating it as a secure frame? It doesn't do anything, it's just an image, right? Take that out and everything should be fine.

Xrystal 06-26-21 05:00 PM

Quote:

Originally Posted by Seerah (Post 339468)
Wait, is your FB2 frame just showing a texture? Why are you creating it as a secure frame? It doesn't do anything, it's just an image, right? Take that out and everything should be fine.

Can you show/hide regular frames during combat ? I thought that was the idea of using secure frames because of the in combat uses.

Fizzlemizz 06-26-21 06:29 PM

If the frame isn't trying to perform a secure action requiring a secure template then you can do what you like (protected actions not withstanding) with it.

Without the secure template, the OP could just parent the frame to ContainerFrame1 and leave out the hook altogether.

Xrystal 06-26-21 07:01 PM

Hmm .. I'm sure it was something that was said at one point or other but maybe a misunderstanding ... the secure system was mystical in my early addon days and alot of the old info has stuck in my brain :) Thanks .. learning something new every day.

wowpedia does have a note about buttons ( which isn't the issue henbe would have as the button hides/shows another frame )
'Protected function
I found that Frames of type Button can't call this method if the player is in combat.'
https://wowpedia.fandom.com/wiki/API_Region_Show

Fizzlemizz 06-26-21 07:06 PM

A quick example if anyone wants to try.
Code:

local f = CreateFrame("Button", "Fizz_TargetDummy", UIParent, "SecureUnitButtonTemplate")
f:SetSize(65, 30)
f:SetPoint("CENTER", -400, 0)
f:SetAttribute("unit", "target")
RegisterUnitWatch(f)
f.t = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") -- non secure frame to toggle
f.t:SetAllPoints()
f.t:SetText("And Me!")
f.t:SetScript("OnClick", function(self)
        print("Clicked!")
end)

local b = CreateFrame("Button", nil, UIParent, "UIPanelButtonTemplate")
b:SetSize(140, 30)
b:SetPoint("RIGHT", f, "LEFT", -2, 0)
b:SetText("Click Me In Combat!")
b:SetScript("OnClick", function(self)
        f.t:SetShown(not f.t:IsShown()) -- toggle non secure frame
end)

The non secure button frame can be shown/hidden and clicked in combat.

Edit: Silly VM wouldn't update the code section.

Seerah 06-27-21 11:57 AM

Yep, so long as the button isn't doing anything secure.

But the OP only had a regular frame with a texture object.

henbe 06-28-21 04:14 AM

Sorry for a long reply delay. My poor knowledge let me down, because I don't know a whole lot about secure actions, templates and taint.

I am making bags layout and actually it does perform secured action on inventory slots(use consumables, hearthstones, etc). It is not as fancy as super-indepth addons, but does a trick, except a few things and showing/hiding in combat is one of them.

I have edited an original post with full code.

Dealing with combat lockdown is main priority but any tip will be very appreciated.

Sorry for a very misleading OP.

Fizzlemizz 06-28-21 01:08 PM

I not sure what the intended final outcome is over and above what can be achieved with the regular bags or, whether part of what you are doing is because you're figuring things out so, this is a guess at a possibilty of what you might be looking for (all your code included with bits commented out. Based on Default UI bags no bag addons).

Lua Code:
  1. -- Button
  2. --[[
  3. local BB = CreateFrame("Button","FBags_BagButton",UIParent,"SecureActionButtonTemplate")
  4. BB:SetPoint("CENTER", UIParent, "CENTER",0,500)
  5. BB:SetSize(50, 50)
  6. local ButtonTexture = BB:CreateTexture("ButtonTexture", "BACKGROUND")
  7. ButtonTexture:SetTexture("Interface\\Buttons\\Button-Backpack-Up")
  8. ButtonTexture:SetPoint("CENTER","FBags_BagButton","CENTER")
  9. ButtonTexture:SetSize(50, 50)
  10. BB:SetScript("OnClick", function(self)
  11.     FB:SetShown(not FB:IsShown())
  12.     print("Bag Clicked")
  13. end)
  14. BB:RegisterEvent("PLAYER_ENTERING_WORLD")
  15. ]]--
  16.  
  17.  
  18. FB = CreateFrame("Button","FBags",ContainerFrame1, "ActionButtonTemplate")
  19. FB:SetFrameStrata("BACKGROUND")
  20. FB:SetPoint("CENTER", UIParent, "CENTER",-400,300)
  21. FB:SetSize(50, 50)
  22. --FB:Hide() -- Parenting will do the show/hide
  23. FB:RegisterEvent("PLAYER_ENTERING_WORLD")
  24. FB:SetScript("OnEvent", function(self)
  25.     self:UnregisterEvent("PLAYER_ENTERING_WORLD")
  26.     -- Bag Layout
  27.     for bagid = 1,4 do
  28.         for bagslot = 1,GetContainerNumSlots(bagid) do
  29.         local icon, itemCount, locked,  ContItemQuality, readable, lootable, ContItemLink, isFiltered, noValue, ContItemID = GetContainerItemInfo(bagid, bagslot)
  30.         local SlotFrame = CreateFrame("Button", "Bag"..bagid.."Slot"..bagslot, FB,"SecureActionButtonTemplate, ActionButtonTemplate",100*bagid+bagslot)
  31.  
  32.         SlotFrame:SetSize(40,40)
  33.         SlotFrame:SetPoint("TOP",FB,"BOTTOM",40*bagslot,-40*bagid)
  34.  
  35.         SlotFrame:RegisterEvent("BAG_UPDATE")
  36.         SlotFrame:RegisterEvent("ITEM_LOCKED")
  37.         SlotFrame:RegisterEvent("ITEM_UNLOCKED")
  38.         SlotFrame:RegisterForClicks("AnyUp")
  39.  
  40.             -- to use items
  41.         SlotFrame:SetAttribute("type2", "item")
  42.         SlotFrame:SetAttribute("bag", bagid)
  43.         SlotFrame:SetAttribute("slot", bagslot)
  44.  
  45.  
  46.             -- adding a texture, text, cooldown
  47.         local texture = SlotFrame:CreateTexture("Bag"..bagid.."Slot"..bagslot.."Texture", "BACKGROUND")
  48.         local text = SlotFrame:CreateFontString("Bag"..bagid.."Slot"..bagslot.."Text", "OVERLAY")
  49.         text:SetFont("Fonts\\FRIZQT___CYR.TTF", 12, "OUTLINE")
  50.         text:SetPoint("BOTTOMRIGHT",SlotFrame,"BOTTOMRIGHT")
  51.         local cooldown = CreateFrame("Cooldown", "Bag"..bagid.."Slot"..bagslot.."Cooldown", SlotFrame, "CooldownFrameTemplate")
  52.         cooldown:SetAllPoints()
  53.  
  54.             -- widget scripts
  55.             -- Tooltip
  56.         SlotFrame:SetScript("OnEnter", function()
  57.             GameTooltip:SetOwner(SlotFrame, "ANCHOR_CURSOR")
  58.             GameTooltip:SetBagItem(bagid, bagslot); -- SetBagItem(bagid, bagslot)
  59.             GameTooltip:Show()
  60.         end)
  61.  
  62.         SlotFrame:SetScript("OnLeave", function()
  63.             GameTooltip:Hide()
  64.         end)
  65.  
  66.             -- Item moving
  67.         SlotFrame:SetScript("OnMouseUp", function(self, button)
  68.             local CursorItem, CursorItemID, CursorItemLink = GetCursorInfo()
  69.             local x = GetMouseFocus():GetID()
  70.             local b = (x-x%100)/100
  71.             local s = x%100
  72.             local icon1, itemCount1, locked1, quality1, readable1, lootable1, itemLink1, isFiltered1, noValue1, ContItemID1 = GetContainerItemInfo(b, s)
  73.             if not (b == 0 and s == 0) then
  74.             if button == "LeftButton" then
  75.                 if GetContainerItemInfo(b, s) and not GetCursorInfo() then
  76.                 PickupContainerItem(b, s)
  77.                 print("Picking up bag "..b.." slot "..s.." using "..button)
  78.                 elseif GetCursorInfo() and not GetContainerItemInfo(b, s) then
  79.                 PickupContainerItem(b, s)
  80.                 print("Putting down bag "..b.." slot "..s.." using "..button)
  81.                 elseif not GetCursorInfo() and not GetContainerItemInfo(b, s) then
  82.                 print("Nothing to pick up")
  83.                 elseif ContItemID1 == 82800 then
  84.                 PickupContainerItem(b, s)
  85.                 print("Putting down bag "..b.." slot "..s.." using "..button)
  86.                 elseif CursorItemID == ContItemID1 then
  87.                 ClearCursor()
  88.                 print("Same cell, putting down")
  89.                 elseif CursorItemID ~= ContItemID1 then
  90.                 PickupContainerItem(b, s)
  91.                 print("Filled cell, swapping")
  92.                 end
  93.             end
  94.             end
  95.         end)
  96.  
  97.  
  98.             -- Bag Update, cooldowns, icons
  99.         local function eventHandler(self, event, ...)
  100.             local icon, itemCount, locked, quality, readable, lootable, itemLink, isFiltered, noValue, itemID = GetContainerItemInfo(bagid, bagslot)
  101.             local startTime, duration, isEnabled = GetContainerItemCooldown(bagid, bagslot)
  102.             if event == "BAG_UPDATE" then
  103.             if GetContainerItemInfo(bagid, bagslot) then
  104.                 if duration>0 then
  105.                 cooldown:SetCooldown(startTime,duration)
  106.                 print("cooldown started in "..bagid.." "..bagslot)
  107.                 else
  108.                 cooldown:SetCooldown(0,0)
  109.                 end
  110.                 texture:SetTexture(icon)
  111.                 texture:SetPoint("CENTER","Bag"..bagid.."Slot"..bagslot,"CENTER")
  112.                 texture:SetSize(40, 40)
  113.                 if itemCount>1 then
  114.                 text:SetText(itemCount)
  115.                 else
  116.                 text:SetText(nil)
  117.                 end
  118.             else
  119.                 texture:SetTexture("Interface\\BUTTONS\\UI-Slot-Background.blp")
  120.                 texture:SetPoint("CENTER","Bag"..bagid.."Slot"..bagslot,"CENTER",11,-10)
  121.                 texture:SetSize(60, 60)
  122.                 text:SetText()
  123.                 cooldown:SetCooldown(0,0)
  124.             end
  125.             end
  126.         end
  127.         SlotFrame:SetScript("OnEvent", eventHandler);
  128.         end
  129.     end
  130. end)
  131.  
  132. -- "OpenBackpack" "CloseBackpack" "ToggleBackpack" "CloseAllBags" "OpenAllBags" "ToggleAllBags"
  133. -- hook functions
  134. --[[
  135. hooksecurefunc(  -- Parenting will do th show/hide
  136.     "CloseAllBags",function()
  137.         if FB:IsShown() then
  138.             FB:Hide()
  139.         end
  140.         print("CloseAllBags hookedfunction fired")
  141.     end
  142. )
  143.  
  144. hooksecurefunc(
  145.     "ToggleAllBags",function()
  146.         FB:SetShown(not FB:IsShown())
  147.         print("ToggleAllBags hookedfunction fired")
  148.     end
  149. )
  150. ]]--

Edit: Maybe you're looking to do somthing similar to AutoBar?

DahkCeles 06-28-21 10:25 PM

Quote:

Originally Posted by Xrystal (Post 339471)
wowpedia does have a note about buttonshttps://wowpedia.fandom.com/wiki/API_Region_Show

I'll review that page. The remark in question was written in May 2009 and the page hasn't really been updated since.


All times are GMT -6. The time now is 03:16 PM.

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