Thread Tools Display Modes
09-17-22, 10:03 AM   #1
GnomeIndustries
A Defias Bandit
Join Date: Sep 2022
Posts: 3
SecureActionButtonTemplate for bag slot prefers wearing over selling

I'm trying to create some custom bag slot buttons, but trying to avoid all the hassle of using ItemButton and stripping out everything Blizzard have done and replace it with what I actually want.

So I have something like:

Code:
local button = CreateFrame("Button", "GiTestButton", UIParent, "SecureActionButtonTemplate")
button:SetAttribute("type2", "item")
button:SetAttribute("item", "4_2")

-- Make it look pretty and put it somewhere, etc
Now if I have the merchant frame open and an item in slot 2 of bag 4 that cannot be worn by any class (e.g. junk item) then right clicking the button sells the item.

If, however, I have the merchant frame open and a piece of armour or a weapon in that slot then right clicking the button equips it! Which I dont want (it should behave like the standard Blizzard UI)

Note: This will sell potions and other items with an "On Use" that can't be equipped rather than trying to use them.

Has anyone else experienced this before? and is there any way around it to get the behaviour I want?

Or am I going to have to fall back to ItemButton and fighting off all the default stuff I don't want?
  Reply With Quote
09-17-22, 01:30 PM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
This is what the SecureActionButtonTemplate is doing.

Lua Code:
  1. SECURE_ACTIONS.item =
  2.     function (self, unit, button)
  3.         local item = SecureButton_GetModifiedAttribute(self, "item", button);
  4.         if ( not item ) then
  5.             -- Backwards compatibility code, deprecated but still handled for now.
  6.             local bag = SecureButton_GetModifiedAttribute(self, "bag", button);
  7.             local slot = SecureButton_GetModifiedAttribute(self, "slot", button);
  8.             if ( bag and slot ) then
  9.                 item = bag.." "..slot;
  10.             else
  11.                 item = slot;
  12.             end
  13.         end
  14.         if ( item ) then
  15.             local name, bag, slot = SecureCmdItemParse(item);
  16.             if ( IsEquippableItem(name) and not IsEquippedItem(name) ) then
  17.                 EquipItemByName(name);
  18.             else
  19.                 SecureCmdUseItem(name, bag, slot, unit);
  20.             end
  21.         end
  22.     end;
-FrameXML\SecureTemplates.lua:416

Lua Code:
  1. function SecureCmdUseItem(name, bag, slot, target)
  2.     if ( bag ) then
  3.         UseContainerItem(bag, slot, target);
  4.     elseif ( slot ) then
  5.         UseInventoryItem(slot, target);
  6.     else
  7.         UseItemByName(name, target);
  8.     end
  9. end
-FrameXML\ChatFrame.lua:1164

Both SecureActionButtonTemplate and ContainerFrameItemButton_OnClick() run UseContainerItem(), which is a protected function. Note SecureActionButtonTemplate does explicitly check and try to equip items.

To get around this protection, we have to manipulate the cursor instead:
Lua Code:
  1. function SellContainerItem(bag,slot)
  2.     ClearCursor();--    Make sure cursor isn't already holding anything
  3.     PickupContainerItem(bag,slot);--    Pickup Item
  4.     PickupMerchantItem(0);--    "Click" Merchant Slot (any will do, but zero is commonly used to sell items)
  5. end
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
09-23-22, 03:34 AM   #3
GnomeIndustries
A Defias Bandit
Join Date: Sep 2022
Posts: 3
Thanks for the reply.. can only get it to work for non-soulbound items. So figure I'm still doing something slightly wrong when hooking the script...

I'm doing (where self._view = CreateFrame("Button", "GiTestButton", UIParent, "SecureActionButtonTemplate")):

Code:
self._view:HookScript("OnClick", function(b, button, down) self:onClick(button) end)

onClick = function(self, button)
        print(button, MerchantFrame:IsShown(), MerchantFrame.selectedTab)
        if (button == "RightButton" and MerchantFrame:IsShown() and MerchantFrame.selectedTab ~= 2) then
            ClearCursor();--    Make sure cursor isn't already holding anything
            PickupContainerItem(self._slot.bagId, self._slot.slotId);--    Pickup Item
            PickupMerchantItem(0);--    "Click" Merchant Slot (any will do, but zero is commonly used to sell items)
            return
        end

        if (button ~= "LeftButton") then
            return
        end

        PickupContainerItem(self._slot.bagId, self._slot.slotId)
    end,
Any help would be appreciated
  Reply With Quote
09-23-22, 05:11 PM   #4
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
One of my personal bag management addons still calls UseContainerItem(). I had forgotten the list of exceptions to its protected status and selling to merchants was one of them.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » SecureActionButtonTemplate for bag slot prefers wearing over selling


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off