/Tukui/modules/bags/bags.lua

http://github.com/Asphyxia/Tukui · Lua · 1492 lines · 1167 code · 269 blank · 56 comment · 273 complexity · 2bda14fc143267015c5b465bed2fe999 MD5 · raw file

  1. local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales
  2. --[[
  3. A featureless, 'pure' version of Stuffing.
  4. This version should work on absolutely everything,
  5. but I've removed pretty much all of the options.
  6. All credits of this bags script is by Stuffing and his author Hungtar.
  7. Special Thank's to Hungtar to allow me to use his bag mod for T.
  8. --]]
  9. if not C["bags"].enable == true then return end
  10. local bags_BACKPACK = {0, 1, 2, 3, 4}
  11. local bags_BANK = {-1, 5, 6, 7, 8, 9, 10, 11}
  12. local ST_NORMAL = 1
  13. local ST_FISHBAG = 2
  14. local ST_SPECIAL = 3
  15. local bag_bars = 0
  16. -- hide bags options in default interface
  17. InterfaceOptionsDisplayPanelShowFreeBagSpace:Hide()
  18. Stuffing = CreateFrame ("Frame", nil, UIParent)
  19. Stuffing:RegisterEvent("ADDON_LOADED")
  20. Stuffing:RegisterEvent("PLAYER_ENTERING_WORLD")
  21. Stuffing:SetScript("OnEvent", function(this, event, ...)
  22. Stuffing[event](this, ...)
  23. end)
  24. -- stub for localization.
  25. local Loc = setmetatable({}, {
  26. __index = function (t, v)
  27. t[v] = v
  28. return v
  29. end
  30. })
  31. local function Print (x)
  32. DEFAULT_CHAT_FRAME:AddMessage("|cffC495DDTukui:|r " .. x)
  33. end
  34. local function Stuffing_Sort(args)
  35. if not args then
  36. args = ""
  37. end
  38. Stuffing.itmax = 0
  39. Stuffing:SetBagsForSorting(args)
  40. Stuffing:SortBags()
  41. end
  42. local function Stuffing_OnShow()
  43. Stuffing:PLAYERBANKSLOTS_CHANGED(29) -- XXX: hack to force bag frame update
  44. Stuffing:Layout()
  45. Stuffing:SearchReset()
  46. end
  47. local function StuffingBank_OnHide()
  48. CloseBankFrame()
  49. if Stuffing.frame:IsShown() then
  50. Stuffing.frame:Hide()
  51. end
  52. end
  53. local function Stuffing_OnHide()
  54. if Stuffing.bankFrame and Stuffing.bankFrame:IsShown() then
  55. Stuffing.bankFrame:Hide()
  56. end
  57. end
  58. local function Stuffing_Open()
  59. Stuffing.frame:Show()
  60. end
  61. local function Stuffing_Close()
  62. Stuffing.frame:Hide()
  63. end
  64. local function Stuffing_Toggle()
  65. if Stuffing.frame:IsShown() then
  66. Stuffing.frame:Hide()
  67. if ContainerFrame1:IsShown() then
  68. ToggleKeyRing() -- we want keyring to close when we close bags :)
  69. end
  70. else
  71. Stuffing.frame:Show()
  72. end
  73. end
  74. local function Stuffing_ToggleBag(id)
  75. if id == -2 then
  76. ToggleKeyRing()
  77. return
  78. end
  79. Stuffing_Toggle()
  80. end
  81. --
  82. -- bag slot stuff
  83. --
  84. local trashParent = CreateFrame("Frame", nil, UIParent)
  85. local trashButton = {}
  86. local trashBag = {}
  87. -- for the tooltip frame used to scan item tooltips
  88. local StuffingTT = nil
  89. -- mostly from carg.bags_Aurora
  90. local QUEST_ITEM_STRING = nil
  91. function Stuffing:SlotUpdate(b)
  92. if not TukuiBags:IsShown() then return end -- don't do any slot update if bags are not show
  93. local texture, count, locked = GetContainerItemInfo (b.bag, b.slot)
  94. local clink = GetContainerItemLink(b.bag, b.slot)
  95. -- set all slot color to default tukui on update
  96. if not b.frame.lock then
  97. b.frame:SetBackdropBorderColor(unpack(C.media.bordercolor))
  98. end
  99. if b.Cooldown then
  100. local cd_start, cd_finish, cd_enable = GetContainerItemCooldown(b.bag, b.slot)
  101. CooldownFrame_SetTimer(b.Cooldown, cd_start, cd_finish, cd_enable)
  102. end
  103. if(clink) then
  104. local iType
  105. b.name, _, b.rarity, _, _, iType = GetItemInfo(clink)
  106. -- color slot according to item quality
  107. if not b.frame.lock and b.rarity and b.rarity > 1 then
  108. b.frame:SetBackdropBorderColor(GetItemQualityColor(b.rarity))
  109. end
  110. if not StuffingTT then
  111. StuffingTT = CreateFrame("GameTooltip", "StuffingTT", nil, "GameTooltipTemplate")
  112. StuffingTT:Hide()
  113. end
  114. if QUEST_ITEM_STRING == nil then
  115. -- GetItemInfo returns a localized item type.
  116. -- this is to figure out what that string is.
  117. local t = {GetAuctionItemClasses()}
  118. QUEST_ITEM_STRING = t[#t] -- #t == 12
  119. end
  120. -- load tooltip, check if ITEM_BIND_QUEST ("Quest Item") is in it.
  121. -- If the tooltip says its a quest item, we assume it is a quest item
  122. -- and ignore the item type from GetItemInfo.
  123. StuffingTT:SetOwner(WorldFrame, "ANCHOR_NONE")
  124. StuffingTT:ClearLines()
  125. StuffingTT:SetBagItem(b.bag, b.slot)
  126. for i = 1, StuffingTT:NumLines() do
  127. local txt = getglobal("StuffingTTTextLeft" .. i)
  128. if txt then
  129. local text = txt:GetText()
  130. if string.find (txt:GetText(), ITEM_BIND_QUEST) then
  131. iType = QUEST_ITEM_STRING
  132. end
  133. end
  134. end
  135. if iType and iType == QUEST_ITEM_STRING then
  136. b.qitem = true
  137. -- color quest item red
  138. if not b.frame.lock then b.frame:SetBackdropBorderColor(1.0, 0.3, 0.3) end
  139. else
  140. b.qitem = nil
  141. end
  142. else
  143. b.name, b.rarity, b.qitem = nil, nil, nil
  144. end
  145. SetItemButtonTexture(b.frame, texture)
  146. SetItemButtonCount(b.frame, count)
  147. SetItemButtonDesaturated(b.frame, locked, 0.5, 0.5, 0.5)
  148. local scount = _G[b.frame:GetName() .. "Count"]
  149. scount:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
  150. scount:Point("BOTTOMRIGHT", 0, 2)
  151. b.scount = scount
  152. b.frame:Show()
  153. end
  154. function Stuffing:BagSlotUpdate(bag)
  155. if not self.buttons then
  156. return
  157. end
  158. for _, v in ipairs (self.buttons) do
  159. if v.bag == bag then
  160. self:SlotUpdate(v)
  161. end
  162. end
  163. end
  164. function Stuffing:BagFrameSlotNew (slot, p)
  165. for _, v in ipairs(self.bagframe_buttons) do
  166. if v.slot == slot then
  167. --print ("found " .. slot)
  168. return v, false
  169. end
  170. end
  171. --print ("new " .. slot)
  172. local ret = {}
  173. local tpl
  174. if slot > 3 then
  175. ret.slot = slot
  176. slot = slot - 4
  177. tpl = "BankItemButtonBagTemplate"
  178. ret.frame = CreateFrame("CheckButton", "StuffingBBag" .. slot, p, tpl)
  179. ret.frame:SetID(slot + 4)
  180. ret.frame:SetNormalTexture("")
  181. ret.frame:SetPushedTexture("")
  182. ret.frame:SetHeight(30)
  183. ret.frame:SetWidth(30)
  184. table.insert(self.bagframe_buttons, ret)
  185. BankFrameItemButton_Update(ret.frame)
  186. BankFrameItemButton_UpdateLocked(ret.frame)
  187. if not ret.frame.tooltipText then
  188. ret.frame.tooltipText = ""
  189. end
  190. else
  191. tpl = "BagSlotButtonTemplate"
  192. ret.frame = CreateFrame("CheckButton", "StuffingFBag" .. slot .. "Slot", p, tpl)
  193. ret.frame:SetNormalTexture("")
  194. ret.frame:SetPushedTexture("")
  195. ret.frame:SetHeight(30)
  196. ret.frame:SetWidth(30)
  197. ret.slot = slot
  198. table.insert(self.bagframe_buttons, ret)
  199. end
  200. return ret
  201. end
  202. function Stuffing:SlotNew (bag, slot)
  203. for _, v in ipairs(self.buttons) do
  204. if v.bag == bag and v.slot == slot then
  205. return v, false
  206. end
  207. end
  208. local tpl = "ContainerFrameItemButtonTemplate"
  209. if bag == -1 then
  210. tpl = "BankItemButtonGenericTemplate"
  211. end
  212. local ret = {}
  213. if #trashButton > 0 then
  214. local f = -1
  215. for i, v in ipairs(trashButton) do
  216. local b, s = v:GetName():match("(%d+)_(%d+)")
  217. b = tonumber(b)
  218. s = tonumber(s)
  219. --print (b .. " " .. s)
  220. if b == bag and s == slot then
  221. f = i
  222. break
  223. end
  224. end
  225. if f ~= -1 then
  226. --print("found it")
  227. ret.frame = trashButton[f]
  228. table.remove(trashButton, f)
  229. end
  230. end
  231. if not ret.frame then
  232. ret.frame = CreateFrame("Button", "StuffingBag" .. bag .. "_" .. slot, self.bags[bag], tpl)
  233. end
  234. ret.bag = bag
  235. ret.slot = slot
  236. ret.frame:SetID(slot)
  237. ret.Cooldown = _G[ret.frame:GetName() .. "Cooldown"]
  238. ret.Cooldown:Show()
  239. self:SlotUpdate (ret)
  240. return ret, true
  241. end
  242. -- from OneBag
  243. local BAGTYPE_PROFESSION = 0x0008 + 0x0010 + 0x0020 + 0x0040 + 0x0080 + 0x0200 + 0x0400
  244. local BAGTYPE_FISHING = 32768
  245. function Stuffing:BagType(bag)
  246. local bagType = select(2, GetContainerNumFreeSlots(bag))
  247. if bit.band(bagType, BAGTYPE_FISHING) > 0 then
  248. return ST_FISHBAG
  249. elseif bit.band(bagType, BAGTYPE_PROFESSION) > 0 then
  250. return ST_SPECIAL
  251. end
  252. return ST_NORMAL
  253. end
  254. function Stuffing:BagNew (bag, f)
  255. for i, v in pairs(self.bags) do
  256. if v:GetID() == bag then
  257. v.bagType = self:BagType(bag)
  258. return v
  259. end
  260. end
  261. local ret
  262. if #trashBag > 0 then
  263. local f = -1
  264. for i, v in pairs(trashBag) do
  265. if v:GetID() == bag then
  266. f = i
  267. break
  268. end
  269. end
  270. if f ~= -1 then
  271. --print("found bag " .. bag)
  272. ret = trashBag[f]
  273. table.remove(trashBag, f)
  274. ret:Show()
  275. ret.bagType = self:BagType(bag)
  276. return ret
  277. end
  278. end
  279. --print("new bag " .. bag)
  280. ret = CreateFrame("Frame", "StuffingBag" .. bag, f)
  281. ret.bagType = self:BagType(bag)
  282. ret:SetID(bag)
  283. return ret
  284. end
  285. function Stuffing:SearchUpdate(str)
  286. str = string.lower(str)
  287. for _, b in ipairs(self.buttons) do
  288. if b.frame and not b.name then
  289. b.frame:SetAlpha(.2)
  290. end
  291. if b.name then
  292. if not string.find (string.lower(b.name), str, 1, true) then
  293. SetItemButtonDesaturated(b.frame, 1, 1, 1, 1)
  294. b.frame:SetAlpha(.2)
  295. else
  296. SetItemButtonDesaturated(b.frame, 0, 1, 1, 1)
  297. b.frame:SetAlpha(1)
  298. end
  299. end
  300. end
  301. end
  302. function Stuffing:SearchReset()
  303. for _, b in ipairs(self.buttons) do
  304. b.frame:SetAlpha(1)
  305. SetItemButtonDesaturated(b.frame, 0, 1, 1, 1)
  306. end
  307. end
  308. -- drop down menu stuff from Postal
  309. local Stuffing_DDMenu = CreateFrame("Frame", "Stuffing_DropDownMenu")
  310. Stuffing_DDMenu.displayMode = "MENU"
  311. Stuffing_DDMenu.info = {}
  312. Stuffing_DDMenu.HideMenu = function()
  313. if UIDROPDOWNMENU_OPEN_MENU == Stuffing_DDMenu then
  314. CloseDropDownMenus()
  315. end
  316. end
  317. function Stuffing:CreateBagFrame(w)
  318. local n = "Tukui" .. w
  319. local f = CreateFrame ("Frame", n, UIParent)
  320. f:SetTemplate("Transparent")
  321. f:CreateShadow("Default")
  322. f:CreateBorder(true, true)
  323. f:EnableMouse(1)
  324. f:SetMovable(1)
  325. f:SetToplevel(1)
  326. f:SetFrameStrata("HIGH")
  327. f:SetFrameLevel(20)
  328. local function bagUpdate(f, ...)
  329. if w == "Bank" then
  330. if not C["chat"].background then
  331. f:SetPoint("BOTTOMLEFT", TukuiInfoLeft, "TOPLEFT", 0, 3)
  332. else
  333. f:SetPoint("BOTTOMLEFT", TukuiChatBackgroundLeft, "TOPLEFT", 0, 3)
  334. end
  335. else
  336. if not C["actionbar"].enable then
  337. if not C["chat"].background then
  338. f:SetPoint("BOTTOMLEFT", TukuiInfoRight, "TOPLEFT", 0, 3)
  339. else
  340. f:SetPoint("BOTTOMRIGHT", TukuiChatBackgroundRight, "TOPRIGHT", 0, 3)
  341. end
  342. else
  343. if not C["chat"].background then
  344. f:SetPoint("BOTTOMLEFT", TukuiInfoRight, "TOPLEFT", 0, 3)
  345. elseif HasPetUI() then
  346. if C["actionbar"].vertical_rightbars then
  347. f:SetPoint("BOTTOMRIGHT", TukuiChatBackgroundRight, "TOPRIGHT", 0, 3)
  348. else
  349. f:SetPoint("BOTTOM", TukuiPetBar, "TOP", 0, 3)
  350. end
  351. elseif UnitHasVehicleUI("player") then
  352. f:SetPoint("BOTTOMRIGHT", TukuiChatBackgroundRight, "TOPRIGHT", 0, 3)
  353. else
  354. if C["actionbar"].vertical_rightbars then
  355. f:SetPoint("BOTTOMRIGHT", TukuiChatBackgroundRight, "TOPRIGHT", 0, 3)
  356. else
  357. if TukuiSaved.rightbars >= 1 then
  358. f:SetPoint("BOTTOMRIGHT", TukuiRightBar, "TOPRIGHT", 0, 3)
  359. else
  360. f:SetPoint("BOTTOMRIGHT", TukuiChatBackgroundRight, "TOPRIGHT", 0, 3)
  361. end
  362. end
  363. end
  364. end
  365. end
  366. end
  367. f:HookScript("OnUpdate", bagUpdate)
  368. -- CLOSE BUTTON
  369. local function ModifiedBackdrop(self)
  370. local color = RAID_CLASS_COLORS[T.myclass]
  371. self:SetBackdropColor(unpack(C["media"].backdropcolor))
  372. self:SetBackdropBorderColor(color.r, color.g, color.b)
  373. end
  374. local function OriginalBackdrop(self)
  375. self:SetBackdropColor(unpack(C["media"].backdropcolor))
  376. self:SetBackdropBorderColor(unpack(C["media"].bordercolor))
  377. end
  378. f.b_close = CreateFrame("Button", "Stuffing_CloseButton" .. w, f)
  379. f.b_close:Width(50)
  380. f.b_close:Height(20)
  381. f.b_close:Point("TOPRIGHT", -3, -3)
  382. f.b_close:SetScript("OnClick", function(self, btn)
  383. if self:GetParent():GetName() == "TukuiBags" and btn == "RightButton" then
  384. if Stuffing_DDMenu.initialize ~= Stuffing.Menu then
  385. CloseDropDownMenus()
  386. Stuffing_DDMenu.initialize = Stuffing.Menu
  387. end
  388. ToggleDropDownMenu(1, nil, Stuffing_DDMenu, self:GetName(), 0, 0)
  389. return
  390. end
  391. self:GetParent():Hide()
  392. end)
  393. f.b_close:RegisterForClicks("AnyUp")
  394. f.b_close:SetTemplate("Default")
  395. f.b_close:SetFrameStrata("HIGH")
  396. f.b_text = f.b_close:CreateFontString(nil, "OVERLAY")
  397. f.b_text:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
  398. f.b_text:SetPoint("CENTER", 0, 0)
  399. f.b_text:SetText(T.datacolor.."Close")
  400. f.b_close:CreateOverlay(f.b_close)
  401. f.b_close:SetWidth(f.b_text:GetWidth() + 20)
  402. f.b_close:HookScript("OnEnter", ModifiedBackdrop)
  403. f.b_close:HookScript("OnLeave", OriginalBackdrop)
  404. -- create the bags frame
  405. local fb = CreateFrame ("Frame", n .. "BagsFrame", f)
  406. fb:Point("BOTTOMLEFT", f, "TOPLEFT", 0, 3)
  407. fb:SetFrameStrata("HIGH")
  408. fb:SetTemplate("Transparent")
  409. fb:CreateShadow("Default")
  410. fb:CreateBorder(true, true)
  411. f.bags_frame = fb
  412. return f
  413. end
  414. function Stuffing:InitBank()
  415. if self.bankFrame then
  416. return
  417. end
  418. local f = self:CreateBagFrame("Bank")
  419. f:SetScript("OnHide", StuffingBank_OnHide)
  420. self.bankFrame = f
  421. end
  422. local parent_startmoving = function(self)
  423. StartMoving(self:GetParent())
  424. end
  425. local parent_stopmovingorsizing = function (self)
  426. StopMoving(self:GetParent())
  427. end
  428. function Stuffing:InitBags()
  429. if self.frame then
  430. return
  431. end
  432. self.buttons = {}
  433. self.bags = {}
  434. self.bagframe_buttons = {}
  435. local f = self:CreateBagFrame("Bags")
  436. f:SetScript("OnShow", Stuffing_OnShow)
  437. f:SetScript("OnHide", Stuffing_OnHide)
  438. -- search editbox (tekKonfigAboutPanel.lua)
  439. local editbox = CreateFrame("EditBox", nil, f)
  440. editbox:Hide()
  441. editbox:SetAutoFocus(true)
  442. editbox:Height(32)
  443. editbox:SetTemplate("Default")
  444. local resetAndClear = function (self)
  445. self:GetParent().detail:Show()
  446. self:GetParent().gold:Show()
  447. self:ClearFocus()
  448. Stuffing:SearchReset()
  449. end
  450. local updateSearch = function(self, t)
  451. if t == true then
  452. Stuffing:SearchUpdate(self:GetText())
  453. end
  454. end
  455. editbox:SetScript("OnEscapePressed", resetAndClear)
  456. editbox:SetScript("OnEnterPressed", resetAndClear)
  457. editbox:SetScript("OnEditFocusLost", editbox.Hide)
  458. editbox:SetScript("OnEditFocusGained", editbox.HighlightText)
  459. editbox:SetScript("OnTextChanged", updateSearch)
  460. editbox:SetText(L.bags_search)
  461. local detail = f:CreateFontString(nil, "ARTWORK", "GameFontHighlightLarge")
  462. detail:Point("TOPLEFT", f, 12, -10)
  463. detail:Point("RIGHT",-(16 + 24), 0)
  464. detail:SetJustifyH("LEFT")
  465. detail:SetText("|cff9999ff" .. "Search")
  466. editbox:SetAllPoints(detail)
  467. local gold = f:CreateFontString(nil, "ARTWORK", "GameFontHighlightLarge")
  468. gold:SetJustifyH("RIGHT")
  469. gold:Point("RIGHT", f.b_close, "LEFT", -20, 0)
  470. f:SetScript("OnEvent", function (self, e)
  471. self.gold:SetText(GetMoneyString(GetMoney(), 12))
  472. end)
  473. f:RegisterEvent("PLAYER_MONEY")
  474. f:RegisterEvent("PLAYER_LOGIN")
  475. f:RegisterEvent("PLAYER_TRADE_MONEY")
  476. f:RegisterEvent("TRADE_MONEY_CHANGED")
  477. local OpenEditbox = function(self)
  478. self:GetParent().detail:Hide()
  479. self:GetParent().gold:Hide()
  480. self:GetParent().editbox:Show()
  481. self:GetParent().editbox:HighlightText()
  482. end
  483. local button = CreateFrame("Button", nil, f)
  484. button:EnableMouse(1)
  485. button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
  486. button:SetAllPoints(detail)
  487. button:SetScript("OnClick", function(self, btn)
  488. if btn == "RightButton" then
  489. OpenEditbox(self)
  490. else
  491. if self:GetParent().editbox:IsShown() then
  492. self:GetParent().editbox:Hide()
  493. self:GetParent().editbox:ClearFocus()
  494. self:GetParent().detail:Show()
  495. self:GetParent().gold:Show()
  496. Stuffing:SearchReset()
  497. end
  498. end
  499. end)
  500. local tooltip_hide = function()
  501. GameTooltip:Hide()
  502. end
  503. local tooltip_show = function (self)
  504. GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
  505. GameTooltip:ClearLines()
  506. GameTooltip:SetText(L.bags_rightclick_search)
  507. end
  508. button:SetScript("OnEnter", tooltip_show)
  509. button:SetScript("OnLeave", tooltip_hide)
  510. f.editbox = editbox
  511. f.detail = detail
  512. f.button = button
  513. f.gold = gold
  514. self.frame = f
  515. f:Hide()
  516. end
  517. function Stuffing:Layout(lb)
  518. local slots = 0
  519. local rows = 0
  520. local off = 26
  521. local cols
  522. local f
  523. local bs
  524. local bgvalue = 0
  525. if not C["chat"].background then
  526. bgvalue = 10
  527. end
  528. if lb then
  529. bs = bags_BANK
  530. cols = (floor((T.InfoLeftRightWidth - bgvalue)/370 * 10) + 1)
  531. f = self.bankFrame
  532. else
  533. bs = bags_BACKPACK
  534. cols = (floor((T.InfoLeftRightWidth - bgvalue)/370 * 10) + 1)
  535. f = self.frame
  536. f.gold:SetText(GetMoneyString(GetMoney(), 12))
  537. f.editbox:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
  538. f.detail:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
  539. f.gold:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
  540. f.detail:ClearAllPoints()
  541. f.detail:Point("TOPLEFT", f, 12, -10)
  542. f.detail:Point("RIGHT", -(16 + 24), 0)
  543. end
  544. f:SetClampedToScreen(1)
  545. -- bag frame stuff
  546. local fb = f.bags_frame
  547. if bag_bars == 1 then
  548. fb:SetClampedToScreen(1)
  549. local bsize = 24
  550. if lb then bsize = 23.3 end
  551. local w = 2 * 12
  552. w = w + ((#bs - 1) * bsize)
  553. w = w + (12 * (#bs - 2))
  554. fb:Height(2 * 12 + bsize)
  555. fb:Width(w)
  556. fb:Show()
  557. else
  558. fb:Hide()
  559. end
  560. local idx = 0
  561. for _, v in ipairs(bs) do
  562. if (not lb and v <= 3 ) or (lb and v ~= -1) then
  563. local bsize = 30
  564. if lb then bsize = 30 end
  565. local b = self:BagFrameSlotNew(v, fb)
  566. local xoff = 12
  567. xoff = xoff + (idx * bsize) -- 31)
  568. xoff = xoff + (idx * 4)
  569. b.frame:ClearAllPoints()
  570. b.frame:Point("LEFT", fb, "LEFT", xoff, 0)
  571. b.frame:Show()
  572. -- this is for the bagbar icons
  573. local iconTex = _G[b.frame:GetName() .. "IconTexture"]
  574. iconTex:SetTexCoord(.09, .91, .09, .91)
  575. iconTex:Point("TOPLEFT", b.frame, 2, -2)
  576. iconTex:Point("BOTTOMRIGHT", b.frame, -2, 2)
  577. iconTex:Show()
  578. b.iconTex = iconTex
  579. b.frame:SetTemplate("Default")
  580. b.frame:SetBackdropColor(0,0,0)
  581. b.frame:StyleButton()
  582. idx = idx + 1
  583. end
  584. end
  585. for _, i in ipairs(bs) do
  586. local x = GetContainerNumSlots(i)
  587. if x > 0 then
  588. if not self.bags[i] then
  589. self.bags[i] = self:BagNew(i, f)
  590. end
  591. slots = slots + GetContainerNumSlots(i)
  592. end
  593. end
  594. rows = floor (slots / cols)
  595. if (slots % cols) ~= 0 then
  596. rows = rows + 1
  597. end
  598. --f:Width(T.InfoLeftRightWidth + 8 - bgvalue)
  599. f:Width(C["chat"].width - bgvalue)
  600. f:Height(rows * 30 + (rows - 1) * 2 + off + 12 * 2)
  601. local sf = CreateFrame("Frame", "SlotFrame", f)
  602. sf:Width((31 + 1) * cols)
  603. sf:Height(f:GetHeight() - (6))
  604. sf:Point("BOTTOM", f, "BOTTOM")
  605. local idx = 0
  606. for _, i in ipairs(bs) do
  607. local bag_cnt = GetContainerNumSlots(i)
  608. if bag_cnt > 0 then
  609. self.bags[i] = self:BagNew(i, f)
  610. local bagType = self.bags[i].bagType
  611. self.bags[i]:Show()
  612. for j = 1, bag_cnt do
  613. local b, isnew = self:SlotNew (i, j)
  614. local xoff
  615. local yoff
  616. local x = (idx % cols)
  617. local y = floor(idx / cols)
  618. if isnew then
  619. table.insert(self.buttons, idx + 1, b)
  620. end
  621. xoff = (x * 31) + (x * 1)
  622. yoff = off + 12 + (y * 30) + ((y - 1) * 2)
  623. yoff = yoff * -1
  624. b.frame:ClearAllPoints()
  625. b.frame:Point("TOPLEFT", sf, "TOPLEFT", xoff, yoff)
  626. b.frame:Height(29)
  627. b.frame:Width(29)
  628. b.frame:SetPushedTexture("")
  629. b.frame:SetNormalTexture("")
  630. b.frame:Show()
  631. b.frame:SetTemplate("Default")
  632. b.frame:SetBackdropColor(0,0,0)
  633. b.frame:StyleButton()
  634. -- color fish bag border slot to red
  635. if bagType == ST_FISHBAG then b.frame:SetBackdropBorderColor(1, 0, 0) b.frame.lock = true end
  636. -- color profession bag slot border ~yellow
  637. if bagType == ST_SPECIAL then b.frame:SetBackdropBorderColor(255/255, 243/255, 82/255) b.frame.lock = true end
  638. self:SlotUpdate(b)
  639. local iconTex = _G[b.frame:GetName() .. "IconTexture"]
  640. iconTex:SetTexCoord(.09, .91, .09, .91)
  641. iconTex:Point("TOPLEFT", b.frame, 2, -2)
  642. iconTex:Point("BOTTOMRIGHT", b.frame, -2, 2)
  643. iconTex:Show()
  644. b.iconTex = iconTex
  645. idx = idx + 1
  646. end
  647. end
  648. end
  649. end
  650. function Stuffing:SetBagsForSorting(c)
  651. Stuffing_Open()
  652. self.sortBags = {}
  653. local cmd = ((c == nil or c == "") and {"d"} or {strsplit("/", c)})
  654. for _, s in ipairs(cmd) do
  655. if s == "c" then
  656. self.sortBags = {}
  657. elseif s == "d" then
  658. if not self.bankFrame or not self.bankFrame:IsShown() then
  659. for _, i in ipairs(bags_BACKPACK) do
  660. if self.bags[i] and self.bags[i].bagType == ST_NORMAL then
  661. table.insert(self.sortBags, i)
  662. end
  663. end
  664. else
  665. for _, i in ipairs(bags_BANK) do
  666. if self.bags[i] and self.bags[i].bagType == ST_NORMAL then
  667. table.insert(self.sortBags, i)
  668. end
  669. end
  670. end
  671. elseif s == "p" then
  672. if not self.bankFrame or not self.bankFrame:IsShown() then
  673. for _, i in ipairs(bags_BACKPACK) do
  674. if self.bags[i] and self.bags[i].bagType == ST_SPECIAL then
  675. table.insert(self.sortBags, i)
  676. end
  677. end
  678. else
  679. for _, i in ipairs(bags_BANK) do
  680. if self.bags[i] and self.bags[i].bagType == ST_SPECIAL then
  681. table.insert(self.sortBags, i)
  682. end
  683. end
  684. end
  685. else
  686. if tonumber(s) == nil then
  687. Print(string.format(Loc["Error: don't know what \"%s\" means."], s))
  688. end
  689. table.insert(self.sortBags, tonumber(s))
  690. end
  691. end
  692. local bids = L.bags_bids
  693. for _, i in ipairs(self.sortBags) do
  694. bids = bids .. i .. " "
  695. end
  696. Print(bids)
  697. end
  698. -- slash command handler
  699. local function StuffingSlashCmd(Cmd)
  700. local cmd, args = strsplit(" ", Cmd:lower(), 2)
  701. if cmd == "config" then
  702. Stuffing_OpenConfig()
  703. elseif cmd == "sort" then
  704. Stuffing_Sort(args)
  705. elseif cmd == "psort" then
  706. Stuffing_Sort("c/p")
  707. elseif cmd == "stack" then
  708. Stuffing:SetBagsForSorting(args)
  709. Stuffing:Restack()
  710. elseif cmd == "test" then
  711. Stuffing:SetBagsForSorting(args)
  712. elseif cmd == "purchase" then
  713. -- XXX
  714. if Stuffing.bankFrame and Stuffing.bankFrame:IsShown() then
  715. local cnt, full = GetNumBankSlots()
  716. if full then
  717. Print(L.bags_noslots)
  718. return
  719. end
  720. if args == "yes" then
  721. PurchaseSlot()
  722. return
  723. end
  724. Print(string.format(L.bags_costs, GetBankSlotCost() / 10000))
  725. Print(L.bags_buyslots)
  726. else
  727. Print(L.bags_openbank)
  728. end
  729. else
  730. Print("sort - " .. L.bags_sort)
  731. Print("stack - " .. L.bags_stack)
  732. Print("purchase - " .. L.bags_buybankslot)
  733. end
  734. end
  735. function Stuffing:ADDON_LOADED(addon)
  736. if addon ~= "Tukui" then
  737. return nil
  738. end
  739. self:RegisterEvent("BAG_UPDATE")
  740. self:RegisterEvent("ITEM_LOCK_CHANGED")
  741. self:RegisterEvent("BANKFRAME_OPENED")
  742. self:RegisterEvent("BANKFRAME_CLOSED")
  743. self:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
  744. self:RegisterEvent("BAG_CLOSED")
  745. SlashCmdList["STUFFING"] = StuffingSlashCmd
  746. SLASH_STUFFING1 = "/bags"
  747. self:InitBags()
  748. tinsert(UISpecialFrames,"TukuiBags")
  749. ToggleBackpack = Stuffing_Toggle
  750. ToggleBag = Stuffing_ToggleBag
  751. ToggleAllBags = Stuffing_Toggle
  752. OpenAllBags = Stuffing_Open
  753. OpenBackpack = Stuffing_Open
  754. CloseAllBags = Stuffing_Close
  755. CloseBackpack = Stuffing_Close
  756. BankFrame:UnregisterAllEvents()
  757. end
  758. function Stuffing:PLAYER_ENTERING_WORLD()
  759. -- please don't do anything after 1 player_entering_world event.
  760. Stuffing:UnregisterEvent("PLAYER_ENTERING_WORLD")
  761. if T.toc >= 40200 then return end
  762. -- hooking and setting key ring bag
  763. -- this is just a reskin of Blizzard key bag to fit Tukui
  764. -- hooking OnShow because sometime key max slot changes.
  765. ContainerFrame1:HookScript("OnShow", function(self)
  766. local keybackdrop = CreateFrame("Frame", nil, self)
  767. keybackdrop:Point("TOPLEFT", 9, -40)
  768. keybackdrop:Point("BOTTOMLEFT", 0, 0)
  769. keybackdrop:Size(179,215)
  770. keybackdrop:SetTemplate("Default")
  771. ContainerFrame1CloseButton:Hide()
  772. ContainerFrame1Portrait:Hide()
  773. ContainerFrame1Name:Hide()
  774. ContainerFrame1BackgroundTop:SetAlpha(0)
  775. ContainerFrame1BackgroundMiddle1:SetAlpha(0)
  776. ContainerFrame1BackgroundMiddle2:SetAlpha(0)
  777. ContainerFrame1BackgroundBottom:SetAlpha(0)
  778. for i=1, GetKeyRingSize() do
  779. local slot = _G["ContainerFrame1Item"..i]
  780. local t = _G["ContainerFrame1Item"..i.."IconTexture"]
  781. slot:SetPushedTexture("")
  782. slot:SetNormalTexture("")
  783. t:SetTexCoord(.08, .92, .08, .92)
  784. t:Point("TOPLEFT", slot, 2, -2)
  785. t:Point("BOTTOMRIGHT", slot, -2, 2)
  786. slot:SetTemplate("Default")
  787. --slot.overlay:Kill()
  788. slot:SetBackdropColor(0,0,0)
  789. slot:StyleButton()
  790. end
  791. end)
  792. ContainerFrame1:ClearAllPoints()
  793. ContainerFrame1:Point("BOTTOMRIGHT", TukuiInfoRight, "TOPRIGHT", 4, 3)
  794. ContainerFrame1.ClearAllPoints = T.dummy
  795. ContainerFrame1.SetPoint = T.dummy
  796. end
  797. function Stuffing:PLAYERBANKSLOTS_CHANGED(id)
  798. if id > 28 then
  799. for _, v in ipairs(self.bagframe_buttons) do
  800. if v.frame and v.frame.GetInventorySlot then
  801. BankFrameItemButton_Update(v.frame)
  802. BankFrameItemButton_UpdateLocked(v.frame)
  803. if not v.frame.tooltipText then
  804. v.frame.tooltipText = ""
  805. end
  806. end
  807. end
  808. end
  809. if self.bankFrame and self.bankFrame:IsShown() then
  810. self:BagSlotUpdate(-1)
  811. end
  812. end
  813. function Stuffing:BAG_UPDATE(id)
  814. self:BagSlotUpdate(id)
  815. end
  816. function Stuffing:ITEM_LOCK_CHANGED(bag, slot)
  817. if slot == nil then
  818. return
  819. end
  820. for _, v in ipairs(self.buttons) do
  821. if v.bag == bag and v.slot == slot then
  822. self:SlotUpdate(v)
  823. break
  824. end
  825. end
  826. end
  827. function Stuffing:BANKFRAME_OPENED()
  828. Stuffing_Open()
  829. if not self.bankFrame then
  830. self:InitBank()
  831. end
  832. self:Layout(true)
  833. for _, x in ipairs(bags_BANK) do
  834. self:BagSlotUpdate(x)
  835. end
  836. self.bankFrame:Show()
  837. end
  838. function Stuffing:BANKFRAME_CLOSED()
  839. if not self.bankFrame then
  840. return
  841. end
  842. self.bankFrame:Hide()
  843. end
  844. function Stuffing:BAG_CLOSED(id)
  845. local b = self.bags[id]
  846. if b then
  847. table.remove(self.bags, id)
  848. b:Hide()
  849. table.insert (trashBag, #trashBag + 1, b)
  850. end
  851. while true do
  852. local changed = false
  853. for i, v in ipairs(self.buttons) do
  854. if v.bag == id then
  855. v.frame:Hide()
  856. v.iconTex:Hide()
  857. table.insert (trashButton, #trashButton + 1, v.frame)
  858. table.remove(self.buttons, i)
  859. v = nil
  860. changed = true
  861. end
  862. end
  863. if not changed then
  864. break
  865. end
  866. end
  867. end
  868. function Stuffing:SortOnUpdate(e)
  869. if not self.elapsed then
  870. self.elapsed = 0
  871. end
  872. if not self.itmax then
  873. self.itmax = 0
  874. end
  875. self.elapsed = self.elapsed + e
  876. if self.elapsed < 0.1 then
  877. return
  878. end
  879. self.elapsed = 0
  880. self.itmax = self.itmax + 1
  881. local changed, blocked = false, false
  882. if self.sortList == nil or next(self.sortList, nil) == nil then
  883. -- wait for all item locks to be released.
  884. local locks = false
  885. for i, v in pairs(self.buttons) do
  886. local _, _, l = GetContainerItemInfo(v.bag, v.slot)
  887. if l then
  888. locks = true
  889. else
  890. v.block = false
  891. end
  892. end
  893. if locks then
  894. -- something still locked. wait some more.
  895. return
  896. else
  897. -- all unlocked. get a new table.
  898. self:SetScript("OnUpdate", nil)
  899. self:SortBags()
  900. if self.sortList == nil then
  901. return
  902. end
  903. end
  904. end
  905. -- go through the list and move stuff if we can.
  906. for i, v in ipairs (self.sortList) do
  907. repeat
  908. if v.ignore then
  909. blocked = true
  910. break
  911. end
  912. if v.srcSlot.block then
  913. changed = true
  914. break
  915. end
  916. if v.dstSlot.block then
  917. changed = true
  918. break
  919. end
  920. local _, _, l1 = GetContainerItemInfo(v.dstSlot.bag, v.dstSlot.slot)
  921. local _, _, l2 = GetContainerItemInfo(v.srcSlot.bag, v.srcSlot.slot)
  922. if l1 then
  923. v.dstSlot.block = true
  924. end
  925. if l2 then
  926. v.srcSlot.block = true
  927. end
  928. if l1 or l2 then
  929. break
  930. end
  931. if v.sbag ~= v.dbag or v.sslot ~= v.dslot then
  932. if v.srcSlot.name ~= v.dstSlot.name then
  933. v.srcSlot.block = true
  934. v.dstSlot.block = true
  935. PickupContainerItem (v.sbag, v.sslot)
  936. PickupContainerItem (v.dbag, v.dslot)
  937. changed = true
  938. break
  939. end
  940. end
  941. until true
  942. end
  943. self.sortList = nil
  944. if (not changed and not blocked) or self.itmax > 250 then
  945. self:SetScript("OnUpdate", nil)
  946. self.sortList = nil
  947. Print (L.bags_sortingbags)
  948. end
  949. end
  950. local function InBags(x)
  951. if not Stuffing.bags[x] then
  952. return false
  953. end
  954. for _, v in ipairs(Stuffing.sortBags) do
  955. if x == v then
  956. return true
  957. end
  958. end
  959. return false
  960. end
  961. function Stuffing:SortBags()
  962. if (UnitAffectingCombat("player")) then return end
  963. local free
  964. local total = 0
  965. local bagtypeforfree
  966. if StuffingFrameBank and StuffingFrameBank:IsShown() then
  967. for i = 5, 11 do
  968. free, bagtypeforfree = GetContainerNumFreeSlots(i)
  969. if bagtypeforfree == 0 then
  970. total = free + total
  971. end
  972. end
  973. total = select(1, GetContainerNumFreeSlots(-1)) + total
  974. else
  975. for i = 0, 4 do
  976. free, bagtypeforfree = GetContainerNumFreeSlots(i)
  977. if bagtypeforfree == 0 then
  978. total = free + total
  979. end
  980. end
  981. end
  982. if total == 0 then
  983. print("|cffff0000"..ERROR_CAPS.." - "..ERR_INV_FULL.."|r")
  984. return
  985. end
  986. local bs = self.sortBags
  987. if #bs < 1 then
  988. Print (L.bags_nothingsort)
  989. return
  990. end
  991. local st = {}
  992. local bank = false
  993. Stuffing_Open()
  994. for i, v in pairs(self.buttons) do
  995. if InBags(v.bag) then
  996. self:SlotUpdate(v)
  997. if v.name then
  998. local tex, cnt, _, _, _, _, clink = GetContainerItemInfo(v.bag, v.slot)
  999. local n, _, q, iL, rL, c1, c2, _, Sl = GetItemInfo(clink)
  1000. table.insert(st, {
  1001. srcSlot = v,
  1002. sslot = v.slot,
  1003. sbag = v.bag,
  1004. --sort = q .. iL .. c1 .. c2 .. rL .. Sl .. n .. i,
  1005. --sort = q .. iL .. c1 .. c2 .. rL .. Sl .. n .. (#self.buttons - i),
  1006. sort = q .. c1 .. c2 .. rL .. n .. iL .. Sl .. (#self.buttons - i),
  1007. --sort = q .. (#self.buttons - i) .. n,
  1008. })
  1009. end
  1010. end
  1011. end
  1012. -- sort them
  1013. table.sort (st, function(a, b)
  1014. return a.sort > b.sort
  1015. end)
  1016. -- for each button we want to sort, get a destination button
  1017. local st_idx = #bs
  1018. local dbag = bs[st_idx]
  1019. local dslot = GetContainerNumSlots(dbag)
  1020. for i, v in ipairs (st) do
  1021. v.dbag = dbag
  1022. v.dslot = dslot
  1023. v.dstSlot = self:SlotNew(dbag, dslot)
  1024. dslot = dslot - 1
  1025. if dslot == 0 then
  1026. while true do
  1027. st_idx = st_idx - 1
  1028. if st_idx < 0 then
  1029. break
  1030. end
  1031. dbag = bs[st_idx]
  1032. if Stuffing:BagType(dbag) == ST_NORMAL or Stuffing:BagType(dbag) == ST_SPECIAL or dbag < 1 then
  1033. break
  1034. end
  1035. end
  1036. dslot = GetContainerNumSlots(dbag)
  1037. end
  1038. end
  1039. -- throw various stuff out of the search list
  1040. local changed = true
  1041. while changed do
  1042. changed = false
  1043. -- XXX why doesn't this remove all x->x moves in one pass?
  1044. for i, v in ipairs (st) do
  1045. -- source is same as destination
  1046. if (v.sslot == v.dslot) and (v.sbag == v.dbag) then
  1047. table.remove (st, i)
  1048. changed = true
  1049. end
  1050. end
  1051. end
  1052. -- kick off moving of stuff, if needed.
  1053. if st == nil or next(st, nil) == nil then
  1054. Print(L.bags_sortingbags)
  1055. self:SetScript("OnUpdate", nil)
  1056. else
  1057. self.sortList = st
  1058. self:SetScript("OnUpdate", Stuffing.SortOnUpdate)
  1059. end
  1060. end
  1061. function Stuffing:RestackOnUpdate(e)
  1062. if not self.elapsed then
  1063. self.elapsed = 0
  1064. end
  1065. self.elapsed = self.elapsed + e
  1066. if self.elapsed < 0.1 then
  1067. return
  1068. end
  1069. self.elapsed = 0
  1070. self:Restack()
  1071. end
  1072. function Stuffing:Restack()
  1073. local st = {}
  1074. Stuffing_Open()
  1075. for i, v in pairs(self.buttons) do
  1076. if InBags(v.bag) then
  1077. local tex, cnt, _, _, _, _, clink = GetContainerItemInfo(v.bag, v.slot)
  1078. if clink then
  1079. local n, _, _, _, _, _, _, s = GetItemInfo(clink)
  1080. if cnt ~= s then
  1081. if not st[n] then
  1082. st[n] = {{
  1083. item = v,
  1084. size = cnt,
  1085. max = s
  1086. }}
  1087. else
  1088. table.insert(st[n], {
  1089. item = v,
  1090. size = cnt,
  1091. max = s
  1092. })
  1093. end
  1094. end
  1095. end
  1096. end
  1097. end
  1098. local did_restack = false
  1099. for i, v in pairs(st) do
  1100. if #v > 1 then
  1101. for j = 2, #v, 2 do
  1102. local a, b = v[j - 1], v[j]
  1103. local _, _, l1 = GetContainerItemInfo(a.item.bag, a.item.slot)
  1104. local _, _, l2 = GetContainerItemInfo(b.item.bag, b.item.slot)
  1105. if l1 or l2 then
  1106. did_restack = true
  1107. else
  1108. PickupContainerItem (a.item.bag, a.item.slot)
  1109. PickupContainerItem (b.item.bag, b.item.slot)
  1110. did_restack = true
  1111. end
  1112. end
  1113. end
  1114. end
  1115. if did_restack then
  1116. self:SetScript("OnUpdate", Stuffing.RestackOnUpdate)
  1117. else
  1118. self:SetScript("OnUpdate", nil)
  1119. Print (L.bags_stackend)
  1120. end
  1121. end
  1122. function Stuffing.Menu(self, level)
  1123. if not level then
  1124. return
  1125. end
  1126. local info = self.info
  1127. wipe(info)
  1128. if level ~= 1 then
  1129. return
  1130. end
  1131. wipe(info)
  1132. info.text = L.bags_sortmenu
  1133. info.notCheckable = 1
  1134. info.func = function()
  1135. Stuffing_Sort("d")
  1136. end
  1137. UIDropDownMenu_AddButton(info, level)
  1138. wipe(info)
  1139. info.text = L.bags_sortspecial
  1140. info.notCheckable = 1
  1141. info.func = function()
  1142. Stuffing_Sort("c/p")
  1143. end
  1144. UIDropDownMenu_AddButton(info, level)
  1145. wipe(info)
  1146. info.text = L.bags_stackmenu
  1147. info.notCheckable = 1
  1148. info.func = function()
  1149. Stuffing:SetBagsForSorting("d")
  1150. Stuffing:Restack()
  1151. end
  1152. UIDropDownMenu_AddButton(info, level)
  1153. wipe(info)
  1154. info.text = L.bags_stackspecial
  1155. info.notCheckable = 1
  1156. info.func = function()
  1157. Stuffing:SetBagsForSorting("c/p")
  1158. Stuffing:Restack()
  1159. end
  1160. UIDropDownMenu_AddButton(info, level)
  1161. wipe(info)
  1162. info.text = L.bags_showbags
  1163. info.checked = function()
  1164. return bag_bars == 1
  1165. end
  1166. info.func = function()
  1167. if bag_bars == 1 then
  1168. bag_bars = 0
  1169. else
  1170. bag_bars = 1
  1171. end
  1172. Stuffing:Layout()
  1173. if Stuffing.bankFrame and Stuffing.bankFrame:IsShown() then
  1174. Stuffing:Layout(true)
  1175. end
  1176. end
  1177. UIDropDownMenu_AddButton(info, level)
  1178. if T.toc < 40200 then
  1179. wipe(info)
  1180. info.text = KEYRING
  1181. info.checked = function()
  1182. return key_ring == 1
  1183. end
  1184. info.func = function()
  1185. if key_ring == 1 then
  1186. key_ring = 0
  1187. else
  1188. key_ring = 1
  1189. end
  1190. Stuffing_Toggle()
  1191. ToggleKeyRing()
  1192. Stuffing:Layout()
  1193. end
  1194. UIDropDownMenu_AddButton(info, level)
  1195. end
  1196. wipe(info)
  1197. info.disabled = nil
  1198. info.notCheckable = 1
  1199. info.text = CLOSE
  1200. info.func = self.HideMenu
  1201. info.tooltipTitle = CLOSE
  1202. UIDropDownMenu_AddButton(info, level)
  1203. end