From 819b1919dba9eb4bdd5a368cf70a4a0341c57491 Mon Sep 17 00:00:00 2001 From: Antonio Lobato Date: Sun, 25 Feb 2024 12:50:47 -0800 Subject: [PATCH] Section Drop and More (#242) * Fixed a small pawn bug with list view * Added the ability to click and drag items onto section names to recategorize items from the bag view * Fixed debug panel close button * Fixed a bug where bag slots weren't redrawing when purchasing bag slots * Fixed race condition on setting full refresh * Added proper reagent bag free slot tooltip * Free and release all free slot buttons when bag slot is shown --- .vscode/settings.json | 3 ++- annotations.lua | 1 + config/bags.lua | 13 +++++++----- config/classic/bags.lua | 13 +++++++----- config/itemlist.lua | 7 +++++-- data/categories.lua | 4 ++-- data/items.lua | 5 +++++ frames/bag.lua | 7 +++++++ frames/bagbutton.lua | 6 +++++- frames/bagslots.lua | 8 ++++--- frames/classic/bagslots.lua | 4 ++-- frames/classic/context.lua | 6 +++--- frames/context.lua | 6 +++--- frames/debug.lua | 7 +++++++ frames/section.lua | 42 +++++++++++++++++++++++++++++++------ integrations/pawn.lua | 2 ++ views/gridview.lua | 7 +++++++ views/listview.lua | 4 ++++ views/oneview.lua | 4 ++++ views/views.lua | 1 + 20 files changed, 117 insertions(+), 33 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3e24ef89..77a2eb14 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -98,7 +98,8 @@ "error", "type", "CreateColor", - "LE_FRAME_TUTORIAL_MOUNT_EQUIPMENT_SLOT_FRAME" + "LE_FRAME_TUTORIAL_MOUNT_EQUIPMENT_SLOT_FRAME", + "GetText" ], "Notes.notesLocation": ".notes", "Lua.diagnostics.ignoredFiles": "Disable", diff --git a/annotations.lua b/annotations.lua index 865fb095..ac054686 100644 --- a/annotations.lua +++ b/annotations.lua @@ -99,6 +99,7 @@ BagBarExpandToggle = {} ---@class ScrollingFlatPanelTemplate: Frame ---@field ScrollBox WowScrollBox ---@field ScrollBar MinimalScrollBar +---@field ClosePanelButton Button ---@class DLAPI DLAPI = {} diff --git a/config/bags.lua b/config/bags.lua index 4d74aab6..de942d77 100644 --- a/config/bags.lua +++ b/config/bags.lua @@ -19,6 +19,9 @@ local bucket = addon:GetModule('Bucket') ---@class Categories: AceModule local categories = addon:GetModule('Categories') +---@class Events: AceModule +local events = addon:GetModule('Events') + ---@class Items: AceModule local items = addon:GetModule('Items') @@ -54,7 +57,7 @@ function config:GetCustomCategoryOptions(kind) end, set = function(_, value) categories:SetCategoryState(kind, value, not categories:IsCategoryEnabled(kind, value)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = {} } @@ -92,7 +95,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetCategoryFilter(kind, value, not DB:GetCategoryFilter(kind, value)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = { ["RecentItems"] = L:G("Recent Items"), @@ -180,7 +183,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetItemLevelEnabled(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, }, color = { @@ -193,7 +196,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetItemLevelColorEnabled(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, }, } @@ -210,7 +213,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetBagView(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = { [const.BAG_VIEW.SECTION_GRID] = L:G("Section Grid"), diff --git a/config/classic/bags.lua b/config/classic/bags.lua index 6b9c2b0f..f473c63a 100644 --- a/config/classic/bags.lua +++ b/config/classic/bags.lua @@ -22,6 +22,9 @@ local categories = addon:GetModule('Categories') ---@class Items: AceModule local items = addon:GetModule('Items') +---@class Events: AceModule +local events = addon:GetModule('Events') + ---@class Config: AceModule local config = addon:GetModule('Config') @@ -54,7 +57,7 @@ function config:GetCustomCategoryOptions(kind) end, set = function(_, value) categories:SetCategoryState(kind, value, not categories:IsCategoryEnabled(kind, value)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = {} } @@ -92,7 +95,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetCategoryFilter(kind, value, not DB:GetCategoryFilter(kind, value)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = { ["RecentItems"] = L:G("Recent Items"), @@ -179,7 +182,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetItemLevelEnabled(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, }, color = { @@ -192,7 +195,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetItemLevelColorEnabled(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, }, } @@ -209,7 +212,7 @@ function config:GetBagOptions(kind) end, set = function(_, value) DB:SetBagView(kind, value) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end, values = { [const.BAG_VIEW.SECTION_GRID] = L:G("Section Grid"), diff --git a/config/itemlist.lua b/config/itemlist.lua index 156a84bd..2eb4b9a9 100644 --- a/config/itemlist.lua +++ b/config/itemlist.lua @@ -18,6 +18,9 @@ local items = addon:GetModule('Items') ---@class Constants: AceModule local const = addon:GetModule('Constants') +---@class Events: AceModule +local events = addon:GetModule('Events') + ---@class Context: AceModule local context = addon:GetModule('Context') @@ -65,7 +68,7 @@ local function SetList(self, values) local list = self:GetUserData("values") DB:SaveItemToCategory(itemid, list.name) self:SetList(DB:GetItemCategory(list.name)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end if #itemList == 0 then @@ -108,7 +111,7 @@ local function SetList(self, values) local list = self:GetUserData("values") DB:DeleteItemFromCategory(v.itemInfo.itemID, list.name) self:SetList(DB:GetItemCategory(list.name)) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end }}) end diff --git a/data/categories.lua b/data/categories.lua index 2b8508a4..afad1495 100644 --- a/data/categories.lua +++ b/data/categories.lua @@ -110,7 +110,7 @@ end function categories:DeleteCategory(category) database:DeleteItemCategory(category) events:SendMessage('categories/Changed') - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end -- GetCustomCategory returns the custom category for an item, or nil if it doesn't have one. @@ -177,5 +177,5 @@ end -- reprocessed and re-categorized. function categories:ReprocessAllItems() wipe(self.itemsWithNoCategory) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end diff --git a/data/items.lua b/data/items.lua index 2154ac15..713f9d6c 100644 --- a/data/items.lua +++ b/data/items.lua @@ -94,6 +94,10 @@ function items:OnEnable() table.insert(eventList, 'PLAYERREAGENTBANKSLOTS_CHANGED') end + events:RegisterMessage('bags/FullRefreshAll', function() + self:FullRefreshAll() + end) + events:GroupBucketEvent(eventList, {'bags/RefreshAll', 'bags/RefreshBackpack', 'bags/RefreshBank'}, function() self:DoRefreshAll() end) @@ -126,6 +130,7 @@ function items:RefreshAll() events:SendMessage('bags/RefreshAll') end +---@private -- FullRefreshAll will wipe the item cache and refresh all items in all bags. function items:FullRefreshAll() self.itemsByBagAndSlot = {} diff --git a/frames/bag.lua b/frames/bag.lua index aa3ddf24..9ae2704f 100644 --- a/frames/bag.lua +++ b/frames/bag.lua @@ -500,5 +500,12 @@ function bagFrame:Create(kind) b.frame:SetTitle(L:G(kind == const.BAG_KIND.BACKPACK and "Backpack" or "Bank")) end end) + + events:RegisterMessage('bags/FullRefreshAll', function() + if b.currentView then + b.currentView.fullRefresh = true + end + end) + return b end diff --git a/frames/bagbutton.lua b/frames/bagbutton.lua index 7403ec25..a98c5215 100644 --- a/frames/bagbutton.lua +++ b/frames/bagbutton.lua @@ -113,7 +113,11 @@ function BagButtonFrame.bagButtonProto:OnEnter() return elseif self.empty then GameTooltip:SetOwner(self.frame, "ANCHOR_LEFT") - GameTooltip:SetText(L:G("Empty Bag Slot"), 1, 1, 1) + if const.BACKPACK_ONLY_REAGENT_BAGS[self.bag] then + GameTooltip:SetText(L:G("Empty Reagent Bag Slot"), 1, 1, 1) + else + GameTooltip:SetText(L:G("Empty Bag Slot"), 1, 1, 1) + end GameTooltip:Show() return end diff --git a/frames/bagslots.lua b/frames/bagslots.lua index 8883472f..f467821d 100644 --- a/frames/bagslots.lua +++ b/frames/bagslots.lua @@ -48,6 +48,7 @@ function BagSlots.bagSlotProto:Draw() local w, h = self.content:Draw() self.frame:SetWidth(w + const.OFFSETS.BAG_LEFT_INSET + -const.OFFSETS.BAG_RIGHT_INSET + 4) self.frame:SetHeight(h + 42) + events:SendMessage('bags/FullRefreshAll') end function BagSlots.bagSlotProto:SetShown(shown) @@ -100,7 +101,7 @@ function BagSlots:CreatePanel(kind) b.fadeInGroup, b.fadeOutGroup = animations:AttachFadeAndSlideTop(b.frame) b.fadeInGroup:HookScript("OnFinished", function() - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') --[[ if b.kind == const.BAG_KIND.BACKPACK then addon.Bags.Backpack:Refresh() @@ -110,7 +111,7 @@ function BagSlots:CreatePanel(kind) ]]-- end) b.fadeOutGroup:HookScript("OnFinished", function() - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') --[[ if b.kind == const.BAG_KIND.BACKPACK and addon.Bags.Backpack then addon.Bags.Backpack:Refresh() @@ -119,7 +120,8 @@ function BagSlots:CreatePanel(kind) end ]]-- end) - events:RegisterEvent("BAG_CONTAINER_UPDATE", function() b:Draw() end) + events:RegisterEvent('BAG_CONTAINER_UPDATE', function() b:Draw() end) + events:RegisterEvent('PLAYERBANKBAGSLOTS_CHANGED', function() b:Draw() end) b.kind = kind b.frame:Hide() return b diff --git a/frames/classic/bagslots.lua b/frames/classic/bagslots.lua index 32d031b4..7abea7c4 100644 --- a/frames/classic/bagslots.lua +++ b/frames/classic/bagslots.lua @@ -66,10 +66,10 @@ function BagSlots:CreatePanel(kind) b.fadeInGroup, b.fadeOutGroup = animations:AttachFadeAndSlideTop(b.frame) b.fadeInGroup:HookScript("OnFinished", function() - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end) b.fadeOutGroup:HookScript("OnFinished", function() - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end) events:RegisterEvent("BAG_CONTAINER_UPDATE", function() b:Draw() end) b.kind = kind diff --git a/frames/classic/context.lua b/frames/classic/context.lua index c78cfb24..2c8e73af 100644 --- a/frames/classic/context.lua +++ b/frames/classic/context.lua @@ -133,7 +133,7 @@ function context:CreateContextMenu(bag) func = function() context:Hide() database:SetBagView(bag.kind, const.BAG_VIEW.ONE_BAG) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end }, { @@ -147,7 +147,7 @@ function context:CreateContextMenu(bag) database:SetBagView(bag.kind, const.BAG_VIEW.SECTION_GRID) bag.drawOnClose = true bag.currentItemCount = -1 - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end }, { @@ -159,7 +159,7 @@ function context:CreateContextMenu(bag) func = function() context:Hide() database:SetBagView(bag.kind, const.BAG_VIEW.LIST) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end } } diff --git a/frames/context.lua b/frames/context.lua index fdd3e141..b8f0d6d6 100644 --- a/frames/context.lua +++ b/frames/context.lua @@ -134,7 +134,7 @@ function context:CreateContextMenu(bag) func = function() context:Hide() database:SetBagView(bag.kind, const.BAG_VIEW.ONE_BAG) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end }, { @@ -146,7 +146,7 @@ function context:CreateContextMenu(bag) func = function() context:Hide() database:SetBagView(bag.kind, const.BAG_VIEW.SECTION_GRID) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end }, { @@ -158,7 +158,7 @@ function context:CreateContextMenu(bag) func = function() context:Hide() database:SetBagView(bag.kind, const.BAG_VIEW.LIST) - items:FullRefreshAll() + events:SendMessage('bags/FullRefreshAll') end } } diff --git a/frames/debug.lua b/frames/debug.lua index 2dc9bbf3..275e40dc 100644 --- a/frames/debug.lua +++ b/frames/debug.lua @@ -43,16 +43,23 @@ function debugWindow:Create() local view = CreateScrollBoxListLinearView() view:SetElementInitializer("BetterBagsDebugListButton", initDebugListItem) view:SetPadding(4,4,8,4,0) + view:SetExtent(20) ScrollUtil.InitScrollBoxListWithScrollBar(self.frame.ScrollBox, self.frame.ScrollBar, view) self.frame.ScrollBox:GetUpperShadowTexture():ClearAllPoints() self.frame.ScrollBox:GetLowerShadowTexture():ClearAllPoints() self.frame.ScrollBox:SetDataProvider(self.provider) + self.frame.ClosePanelButton:SetScript("OnClick", function() + database:SetDebugMode(false) + events:SendMessage('config/DebugMode', false) + end) + events:GroupBucketEvent({}, {'debug/LogAdded'}, function() self.provider:InsertTable(self.cells) wipe(self.cells) self.frame.ScrollBox:ScrollToEnd() end) + events:RegisterMessage('config/DebugMode', function(_, enabled) if enabled then self.frame:Show() diff --git a/frames/section.lua b/frames/section.lua index 038abdc8..b072ac1c 100644 --- a/frames/section.lua +++ b/frames/section.lua @@ -6,6 +6,12 @@ local addon = LibStub('AceAddon-3.0'):GetAddon(addonName) ---@class SectionFrame: AceModule local sectionFrame = addon:NewModule('SectionFrame') +---@class Categories: AceModule +local categories = addon:GetModule('Categories') + +---@class Events: AceModule +local events = addon:GetModule('Events') + ---@class Constants: AceModule local const = addon:GetModule('Constants') @@ -29,7 +35,7 @@ local grid = addon:GetModule('Grid') --- a list of icons, a list of rows, or a grid of icons. ---@class Section ---@field frame Frame The raw frame of the section. ----@field title FontString The title of the section. +---@field title Button The title of the section. ---@field private content Grid The main content frame of the section. ---@field private fillWidth boolean local sectionProto = {} @@ -159,6 +165,19 @@ function sectionFrame:_DoReset(f) f:Wipe() end +---@param section Section +local function onTitleClickOrDrop(section) + if not CursorHasItem() then return end + local cursorType, itemID = GetCursorInfo() + ---@cast cursorType string + ---@cast itemID number + if cursorType ~= "item" then return end + local category = section.title:GetText() + categories:AddItemToCategory(itemID, category) + ClearCursor() + events:SendMessage('bags/FullRefreshAll') +end + ---@return Section function sectionFrame:_DoCreate() ---@class Section @@ -169,14 +188,13 @@ function sectionFrame:_DoCreate() local f = CreateFrame("Frame", nil, nil, "BackdropTemplate") s.frame = f - --debug:DrawBorder(f, 1, 0, 0) - -- Create the section title. - local title = s.frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") + local title = CreateFrame("Button", nil, f) title:SetText("Not set") - title:SetFontObject("GameFontNormal") + title:SetNormalFontObject("GameFontNormal") title:SetHeight(18) - title:SetJustifyH("LEFT") + title:GetFontString():SetAllPoints() + title:GetFontString():SetJustifyH("LEFT") title:SetPoint("TOPLEFT", s.frame, "TOPLEFT", 6, 0) title:SetPoint("TOPRIGHT", s.frame, "TOPRIGHT", -6, 0) title:SetScript("OnEnter", function(t) @@ -187,11 +205,23 @@ function sectionFrame:_DoCreate() "Item Count: " .. #s.content.cells ) GameTooltip:AddLine(info, 1, 1, 1) + if CursorHasItem() then + local cursorType, _, itemLink = GetCursorInfo() + if cursorType == "item" then + GameTooltip:AddLine(" ", 1, 1, 1) + GameTooltip:AddLine("Click/drop here to add "..itemLink.." to "..title:GetText()..".", 1, 1, 1) + end + end GameTooltip:Show() end) + title:SetScript("OnLeave", function() GameTooltip:Hide() end) + + title:SetScript("OnClick", function() onTitleClickOrDrop(s) end) + title:SetScript("OnReceiveDrag", function() onTitleClickOrDrop(s) end) + s.title = title local content = grid:Create(s.frame) diff --git a/integrations/pawn.lua b/integrations/pawn.lua index f2fc0fa2..5bfdadab 100644 --- a/integrations/pawn.lua +++ b/integrations/pawn.lua @@ -11,6 +11,7 @@ local pawn = addon:NewModule('Pawn') ---@param item Item local function onItemUpdateRetail(item) + if not item.button.UpgradeIcon then return end local bagid, slotid = item.data.bagid, item.data.slotid if item.data.isItemEmpty or not bagid or not slotid then item.button.UpgradeIcon:SetShown(false) @@ -21,6 +22,7 @@ end ---@param item Item local function onItemUpdateClassic(item) + if not item.button.UpgradeIcon then return end if item.data.isItemEmpty or not item.data.slotid or not item.data.bagid then item.button.UpgradeIcon:SetShown(false) else diff --git a/views/gridview.lua b/views/gridview.lua index 7ffd6257..691b7109 100644 --- a/views/gridview.lua +++ b/views/gridview.lua @@ -59,6 +59,10 @@ end ---@param bag Bag ---@param dirtyItems ItemData[] local function GridView(view, bag, dirtyItems) + if view.fullRefresh then + view:Wipe() + view.fullRefresh = false + end local sizeInfo = database:GetBagSizeInfo(bag.kind, database:GetBagView(bag.kind)) local categoryChanged = false local extraSlotInfo = items:GetExtraSlotInfo(bag.kind) @@ -98,8 +102,11 @@ local function GridView(view, bag, dirtyItems) -- Special section for handling bag slots being shown. if bag.slots:IsShown() then local freeSlotsSection = view:GetOrCreateSection(L:G("Free Space")) + freeSlotsSection:ReleaseAllCells() freeSlotsSection:RemoveCell('freeSlot') freeSlotsSection:RemoveCell('freeReagentSlot') + view.freeSlot = nil + view.freeReagentSlot = nil for slotkey, itemButton in pairs(view.itemsByBagAndSlot) do local data = itemButton.data local name = C_Container.GetBagName(data.bagid) diff --git a/views/listview.lua b/views/listview.lua index 29529db5..731c417c 100644 --- a/views/listview.lua +++ b/views/listview.lua @@ -59,6 +59,10 @@ end ---@param bag Bag ---@param dirtyItems ItemData[] local function ListView(view, bag, dirtyItems) + if view.fullRefresh then + view:Wipe() + view.fullRefresh = false + end local freeSlotsData = {count = 0, bagid = 0, slotid = 0} local freeReagentSlotsData = {count = 0, bagid = 0, slotid = 0} view.content.compactStyle = const.GRID_COMPACT_STYLE.NONE diff --git a/views/oneview.lua b/views/oneview.lua index 19c326b9..e61be039 100644 --- a/views/oneview.lua +++ b/views/oneview.lua @@ -49,6 +49,10 @@ end ---@param bag Bag ---@param dirtyItems ItemData[] local function OneBagView(view, bag, dirtyItems) + if view.fullRefresh then + view:Wipe() + view.fullRefresh = false + end local sizeInfo = database:GetBagSizeInfo(bag.kind, database:GetBagView(bag.kind)) local extraSlotInfo = items:GetExtraSlotInfo(bag.kind) diff --git a/views/views.lua b/views/views.lua index a93cb7c1..b1cf9880 100644 --- a/views/views.lua +++ b/views/views.lua @@ -25,6 +25,7 @@ local itemFrame = addon:GetModule('ItemFrame') ---@field defer boolean ---@field itemCount number ---@field itemFrames Item[] +---@field fullRefresh boolean views.viewProto = {} ---@param bag Bag