vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 BagnonFrame
3 Functionality for Bagnon Inventory\Bank frames
4  
5 BagSlots:
6 -2: Key (1.11)
7 -1: Bank (24 slots)
8 0: Main Inventory (16 slots)
9 1, 2, 3, 4: Inventory Bags (16 - 32?)
10 5, 6, 7, 8, 9, 10: Bank Bags (16 - 32?)
11  
12 TODO:
13 Potentially, I can make the frame completely dynamically generated and merge Bagnon, Bagnon_Core, and Banknon
14 --]]
15  
16 --Local constants
17 local FRAMESTRATA = {"LOW", "MEDIUM", "HIGH"};
18  
19 local DEFAULT_COLS = 8;
20 local DEFAULT_SPACING = 2;
21  
22 --[[
23 Load settings for the frame
24 --]]
25  
26 function BagnonFrame_Load(frame, bags, title)
27 local frameName = frame:GetName()
28  
29 --make frame close on escape
30 tinsert(UISpecialFrames, frameName);
31  
32 --initialize variables for the frame if there are none
33 if(not BagnonSets[frameName] ) then
34 BagnonSets[frameName] = {
35 stayOnScreen = 1,
36 };
37 end
38  
39 --add what bags are controlled by the frame
40 if(not BagnonSets[frameName].bags) then
41 BagnonSets[frameName].bags = bags;
42 end
43  
44 --set the frame's transparency
45 if(BagnonSets[frameName].alpha) then
46 frame:SetAlpha(BagnonSets[frameName].alpha);
47 end
48  
49 --set the frame's background
50 if(not BagnonSets[frameName].bg or tonumber(BagnonSets[frameName].bg) ) then
51 BagnonSets[frameName].bg = {r = 0, g = 0, b = 0, a = 1};
52 end
53  
54 local bgSets= BagnonSets[frameName].bg;
55 frame:SetBackdropColor(bgSets.r, bgSets.g, bgSets.b, bgSets.a);
56 frame:SetBackdropBorderColor(1, 1, 1, bgSets.a);
57  
58 --set the frame's layer (low, medium, or high)
59 if(BagnonSets[frameName].strata) then
60 BagnonFrame_SetStrata(frame, BagnonSets[frameName].strata);
61 end
62  
63 local bagFrame = getglobal(frameName .. "Bags");
64 if(bagFrame and BagnonSets[frameName].bagsShown) then
65 bagFrame:Show();
66 getglobal(frameName .. "ShowBags"):SetText(BAGNON_HIDEBAGS);
67 end
68  
69 frame:SetClampedToScreen(BagnonSets[frameName].stayOnScreen);
70  
71 --load any settings needed if we have cached data
72 if(BagnonDB) then
73 frame.player = UnitName("player");
74 frame.defaultBags = bags;
75  
76 local dropdownButton = CreateFrame("Button", frameName, frame, "BagnonDBUIDropDownButton");
77 dropdownButton:SetAlpha(frame:GetAlpha());
78 getglobal(frameName .. "Title"):SetPoint("TOPLEFT", dropdownButton, "TOPRIGHT", 2, 2);
79 end
80  
81 BagnonFrame_OrderBags(frame, BagnonSets[frameName].reverse);
82  
83 --set the frame's title
84 frame.title = title;
85 getglobal(frameName .. "Title"):SetText( format(frame.title, UnitName("player") ) );
86 frame:RegisterForClicks("LeftButtonDown", "LeftButtonUp", "RightButtonUp");
87  
88 --create the frame
89 --reposition actually handles rescaling
90 BagnonFrame_Reposition(frame);
91 BagnonFrame_Generate(frame);
92 end
93  
94 --[[
95 Generate the frame (add all items, resize)
96 --]]
97  
98 function BagnonFrame_Generate(frame)
99 frame.size = 0;
100 local frameName = frame:GetName();
101  
102 --generate a cached frame
103 if( Bagnon_IsCachedFrame(frame) ) then
104 MoneyFrame_Update(frameName .. "MoneyFrame", BagnonDB.GetMoney(frame.player));
105  
106 for _, bagID in pairs(frame.defaultBags) do
107 BagnonFrame_AddBag(frame, bagID);
108 end
109 --generate a normal frame
110 else
111 MoneyFrame_Update(frameName .. "MoneyFrame", GetMoney());
112  
113 for _, bagID in pairs(BagnonSets[frameName].bags) do
114 BagnonFrame_AddBag(frame, bagID);
115 end
116 end
117  
118 BagnonFrame_Layout(frame, BagnonSets[frame:GetName()].cols, BagnonSets[frame:GetName()].space);
119 frame:Show();
120 end
121  
122 --[[
123 Add all the slots of the given bag to the given frame.
124 Increase the total size of frame to include the size of the bag
125 --]]
126  
127 local function CreateDummyBag(parent, bagID)
128 local dummyBag = CreateFrame("Frame", parent:GetName() .. "DummyBag" .. bagID, parent);
129 dummyBag:SetID(bagID);
130  
131 return dummyBag;
132 end
133  
134 function BagnonFrame_AddBag(frame, bagID)
135 local frameName = frame:GetName();
136 local slot = frame.size;
137  
138 local bagSize;
139 if( Bagnon_IsCachedBag(frame.player, bagID) ) then
140 bagSize = (BagnonDB.GetBagData(frame.player, bagID)) or 0;
141 else
142 if(bagID == KEYRING_CONTAINER) then
143 bagSize = GetKeyRingSize();
144 else
145 bagSize = GetContainerNumSlots(bagID);
146 end
147 end
148  
149 --update used slots
150 local dummyBag = getglobal(frameName .. "DummyBag" .. bagID) or CreateDummyBag(frame, bagID);
151 for index = 1, bagSize, 1 do
152 slot = slot + 1;
153 local item = getglobal( frameName .. "Item".. slot) or BagnonItem_Create(frameName .. "Item".. slot, dummyBag);
154 item:SetID(index);
155 item:SetParent(dummyBag);
156 item:Show();
157  
158 BagnonItem_Update(item);
159 end
160  
161 frame.size = frame.size + bagSize;
162 end
163  
164 --[[
165 Resize and hide any unusable bag slots in the frame.
166 This function needs to know about the layout of the frame
167 --]]
168  
169 function BagnonFrame_TrimToSize(frame)
170 if( not frame.space ) then
171 return;
172 end
173  
174 local frameName = frame:GetName();
175 local slot, height;
176  
177 --hide unused slots
178 if(frame.size) then
179 local slot = frame.size + 1;
180 local button = getglobal( frameName .. "Item".. slot );
181  
182 while button do
183 button:Hide();
184 slot = slot + 1;
185 button = getglobal( frameName .. "Item".. slot );
186 end
187 end
188  
189 --set the frame's width
190 --correction for any frame that's completely empty
191 if(not frame.size or frame.size == 0 ) then
192 height = 64;
193 frame:SetWidth(256);
194 else
195 --15 is the estimated border width of the frame, 37 is the width of an item button
196 if(frame.size < frame.cols) then
197 frame:SetWidth( ( 37 + frame.space ) * frame.size + 16 - frame.space );
198 else
199 frame:SetWidth( ( 37 + frame.space ) * frame.cols + 16 - frame.space );
200 end
201  
202 --set the frame's height, adjusted to fit a bag frame if its shown/there is one
203 height = ( 37 + frame.space ) * math.ceil( frame.size / frame.cols ) + 64 - frame.space;
204 end
205  
206 --adjust for the bag frame, if present
207 local bagFrame = getglobal(frame:GetName() .. "Bags");
208  
209 if( bagFrame and bagFrame:IsShown() ) then
210 frame:SetHeight(height + bagFrame:GetHeight());
211  
212 if(frame:GetWidth() < bagFrame:GetWidth()) then
213 --the +8 is for correcting for the border width of the frame
214 frame:SetWidth(bagFrame:GetWidth() + 8);
215 end
216 else
217 frame:SetHeight(height);
218 end
219  
220 --this might no longer be necessary
221 --save the frame's position, if it moved
222 BagnonFrame_SavePosition(frame);
223 end
224  
225  
226 -- Update all item information for usable slots
227 function BagnonFrame_Update(frame, bagID)
228 if( not frame.size or Bagnon_IsCachedFrame(frame) ) then
229 return;
230 end
231  
232 local frameName = frame:GetName();
233 local startSlot = 1;
234 local endSlot;
235  
236 --if we don't know the ID of the bag that updated, then update all slots, else only update the necessary slots.
237 if(not bagID) then
238 endSlot = frame.size;
239 else
240 for _, bag in ipairs(BagnonSets[frameName].bags) do
241 if(bag == bagID) then
242 if(bag == KEYRING_CONTAINER) then
243 endSlot = startSlot + GetKeyRingSize() - 1;
244 elseif(bag == -1) then
245 endSlot = startSlot + 23;
246 else
247 endSlot = startSlot + GetContainerNumSlots(bag) - 1;
248 end
249 break;
250 else
251 if(bag == KEYRING_CONTAINER) then
252 startSlot = startSlot + GetKeyRingSize();
253 elseif(bag == -1) then
254 startSlot = startSlot + 24;
255 else
256 startSlot = startSlot + GetContainerNumSlots(bag);
257 end
258 end
259 end
260 end
261  
262 --update the necessary slots
263 for slot = startSlot, endSlot do
264 local item = getglobal( frameName .. "Item" .. slot );
265 if( item ) then
266 BagnonItem_Update( item );
267 end
268 end
269 end
270  
271 function BagnonFrame_UpdateLock(frame)
272 if( not frame.size or Bagnon_IsCachedFrame(frame) ) then
273 return;
274 end
275  
276 local frameName = frame:GetName();
277  
278 for slot = 1, frame.size do
279 local item = getglobal( frameName .. "Item" .. slot );
280 local _, _, locked = GetContainerItemInfo(item:GetParent():GetID(), item:GetID());
281 SetItemButtonDesaturated(item, locked, 0.5, 0.5, 0.5);
282 end
283 end
284  
285 -- Layout the frame with given number of columns and button spacing
286 function BagnonFrame_Layout(frame, cols, space)
287 if(not frame.size) then
288 return;
289 end
290  
291 local frameName = frame:GetName();
292  
293 if(not cols) then
294 cols = DEFAULT_COLS;
295 end
296  
297 if(not space) then
298 space = DEFAULT_SPACING;
299 end
300  
301 if(cols == DEFAULT_COLS) then
302 BagnonSets[frameName].cols = nil
303 else
304 BagnonSets[frameName].cols = cols
305 end
306  
307 if(space == DEFAULT_SPACING) then
308 BagnonSets[frameName].space = nil;
309 else
310 BagnonSets[frameName].space = space;
311 end
312  
313 local rows = math.ceil( frame.size / cols );
314 local index = 1;
315 local button;
316  
317 --resize the frame
318 frame.cols = cols;
319 frame.space = space;
320  
321  
322 button = getglobal(frameName .. "Item1");
323 if(button) then
324 button:ClearAllPoints();
325 button:SetPoint("TOPLEFT", frame, "TOPLEFT", 8, -31);
326  
327 for i = 1, rows, 1 do
328 for j = 1, cols, 1 do
329  
330 index = index + 1;
331 button = getglobal(frameName .. "Item" .. index);
332  
333 if(not button) then
334 break;
335 end
336  
337 button:ClearAllPoints();
338 button:SetPoint("LEFT", frameName .. "Item" .. index - 1, "RIGHT", space, 0);
339 end
340  
341 button = getglobal(frameName .. "Item" .. index);
342  
343 if(not button) then
344 break;
345 end
346  
347 button:ClearAllPoints();
348 button:SetPoint("TOP", frameName .. "Item" .. index - cols, "BOTTOM", 0, -space);
349 end
350 end
351  
352 BagnonFrame_TrimToSize(frame);
353 end
354  
355 --[[
356 Safe Open/Close/Toggle <frame>
357 --]]
358  
359 function BagnonFrame_Open(frameName, automatic)
360 local frame = getglobal(frameName);
361 if( frame ) then
362 BagnonFrame_Generate(frame);
363 else
364 LoadAddOn(frameName);
365 end
366 if(frame and not automatic) then
367 frame.manOpened = 1;
368 end
369 end
370  
371 function BagnonFrame_Close(frameName, automatic)
372 local frame = getglobal(frameName);
373 if ( frame ) then
374 if(not (automatic and frame.manOpened) ) then
375 frame:Hide();
376 frame.manOpened = nil;
377 end
378 end
379 end
380  
381 function BagnonFrame_Toggle(frameName)
382 local frame = getglobal(frameName);
383 if( frame ) then
384 if ( frame:IsVisible() ) then
385 BagnonFrame_Close(frameName);
386 else
387 BagnonFrame_Open(frameName);
388 end
389 else
390 LoadAddOn(frameName);
391 end
392 end
393  
394 --[[
395 Highlight all the slots of <bag>
396 --]]
397  
398 function BagnonFrame_HighlightSlots(frame, bagID)
399 if(not frame.size) then return; end
400  
401 local frameName = frame:GetName();
402 local slot;
403  
404 --update only the slots the player can use
405 for slot = 1, frame.size, 1 do
406 local item = getglobal( frameName .. "Item" .. slot );
407  
408 if( item:GetParent():GetID() == bagID ) then
409 item:LockHighlight();
410 end
411 end
412 end
413  
414 function BagnonFrame_UnhighlightAll(frame)
415 if(not frame.size) then return; end
416  
417 local frameName = frame:GetName();
418 local slot;
419  
420 --update only the slots the player can use
421 for slot = 1, frame.size, 1 do
422 getglobal( frameName .. "Item" .. slot ):UnlockHighlight();
423 end
424 end
425  
426 --[[
427 Add/Remove <Bag> from the frame
428 --]]
429  
430 function BagnonFrame_ToggleBag(frame, bagID)
431 if(not frame) then return; end
432  
433 local frameName = frame:GetName();
434  
435 --add bag
436 if(not Bagnon_FrameHasBag(frameName, bagID) ) then
437 table.insert(BagnonSets[frameName].bags, bagID);
438 --remove bag
439 else
440 local index;
441  
442 for index in BagnonSets[frameName].bags do
443 if( BagnonSets[frameName].bags[index] and BagnonSets[frameName].bags[index] == bagID) then
444 table.remove(BagnonSets[frame:GetName()].bags, index);
445 end
446 end
447 end
448  
449 BagnonFrame_OrderBags(frame, BagnonSets.reverseOrder);
450  
451 --update frame
452 if( frame:IsShown() ) then
453 BagnonFrame_Generate(frame);
454 end
455 end
456  
457 --[[
458 Frame Positioning Functions
459 --]]
460  
461 function BagnonFrame_StartMoving(frame)
462 if(not BagnonSets[frame:GetName()].locked) then
463 frame.isMoving = 1;
464 frame:StartMoving();
465 end
466 end
467  
468 function BagnonFrame_StopMoving(frame)
469 frame.isMoving = nil;
470 frame:StopMovingOrSizing();
471 BagnonFrame_SavePosition(frame);
472 end
473  
474 --Place the frame at the last place it was at.
475 --This is used when the frame first loads because the game currently does not remember the last position of a frame that's dynamically loaded
476 function BagnonFrame_Reposition(frame)
477 local frameName = frame:GetName();
478  
479 if(not (BagnonSets[frameName] and BagnonSets[frameName].top) ) then
480 return;
481 end
482  
483 local ratio;
484 --this step is to take care of a potential flaw if the UI scale changes between loadings of the frame
485 if(BagnonSets[frameName].parentScale ) then
486 ratio = BagnonSets[frameName].parentScale / frame:GetParent():GetScale();
487 else
488 ratio = 1;
489 end
490  
491 frame:ClearAllPoints();
492 frame:SetScale(BagnonSets[frameName].scale);
493 frame:SetPoint("TOPLEFT", frame:GetParent(), "BOTTOMLEFT", BagnonSets[frameName].left * ratio, BagnonSets[frameName].top * ratio);
494 end
495  
496 --Save the frame's current position. Needed because frames don't remember their positions if dynamically loaded.
497 function BagnonFrame_SavePosition(frame)
498 local frameName = frame:GetName();
499  
500 if(not BagnonSets[frameName] ) then
501 BagnonSets[frameName] = {};
502 end
503  
504 BagnonSets[frameName].top = frame:GetTop();
505 BagnonSets[frameName].left = frame:GetLeft();
506 BagnonSets[frameName].scale = frame:GetScale();
507 BagnonSets[frameName].parentScale = frame:GetParent():GetScale();
508 end
509  
510 --set the layer of the frame
511 function BagnonFrame_SetStrata(frame, strata)
512 BagnonSets[frame:GetName()].strata = strata;
513 frame:SetFrameStrata(FRAMESTRATA[strata]);
514 end
515  
516 --[[
517 Tooltip Functions
518 --]]
519  
520 --tooltips for the title
521 function BagnonFrame_OnEnter()
522 if(BagnonSets.showTooltips) then
523 GameTooltip_SetDefaultAnchor(GameTooltip,this);
524 GameTooltip:SetText(this:GetText(), 1, 1, 1);
525 GameTooltip:AddLine(BAGNON_TITLE_TOOLTIP);
526 GameTooltip:Show();
527 end
528 end
529  
530 function BagnonFrame_OnLeave()
531 GameTooltip:Hide();
532 end
533  
534 --[[
535 Money Frame
536 --]]
537  
538 --for money frame tooltips, ment to be overriden by forever/kc
539 function BagnonFrameMoney_OnEnter()
540 return;
541 end
542  
543 function BagnonFrameMoney_OnLeave()
544 GameTooltip:Hide();
545 end
546  
547 -- This is a hack that enables tooltips but still allows clicking on the money frame
548 function BagnonFrameMoney_OnClick()
549 local parentName = this:GetParent():GetName();
550  
551 if( MouseIsOver(getglobal(parentName .. "GoldButton")) ) then
552 local parent = this:GetParent();
553 OpenCoinPickupFrame(COPPER_PER_GOLD, MoneyTypeInfo[parent.moneyType].UpdateFunc(), parent);
554 parent.hasPickup = 1;
555 elseif( MouseIsOver(getglobal(parentName .. "SilverButton")) ) then
556 local parent = this:GetParent();
557 OpenCoinPickupFrame(COPPER_PER_SILVER, MoneyTypeInfo[parent.moneyType].UpdateFunc(), parent);
558 parent.hasPickup = 1;
559 elseif( MouseIsOver(getglobal(parentName .. "CopperButton")) ) then
560 local parent = this:GetParent();
561 OpenCoinPickupFrame(1, MoneyTypeInfo[parent.moneyType].UpdateFunc(), parent);
562 parent.hasPickup = 1;
563 end
564 end
565  
566 --[[
567 Rightclick Menu Stuff
568 --]]
569  
570 --hide any menus attached to the frame, if they're visible and we're hiding the frame
571 function BagnonFrame_OnHide()
572 if(BagnonMenu:IsVisible() and BagnonMenu.frame == this) then
573 BagnonMenu:Hide();
574 end
575 end
576  
577 --this function is here so that it can be overriden
578 function BagnonFrame_OnDoubleClick(frame)
579 return;
580 end
581  
582 function BagnonFrame_OnClick(frame, mouseButton)
583 if(mouseButton == "RightButton") then
584 BagnonMenu_Show(frame);
585 end
586 end
587  
588 --[[
589 Bag Sorting
590 --]]
591  
592 --when sorting in reverse, the keyring is always at the top of the frame
593 local function ReverseSort(a, b)
594 if(a == KEYRING_CONTAINER) then
595 return true;
596 elseif(b == KEYRING_CONTAINER) then
597 return false;
598 elseif(a and b) then
599 return a > b;
600 end;
601 end
602  
603 --when sorting in normal order, the keyring is always at the bottom of the frame
604 local function NormalSort(a, b)
605 if(a == KEYRING_CONTAINER) then
606 return false;
607 elseif(b == KEYRING_CONTAINER) then
608 return true;
609 elseif(a and b) then
610 return a < b;
611 end
612 end
613  
614 function BagnonFrame_OrderBags(frame, reverse)
615 if(reverse) then
616 if(frame) then
617 table.sort(BagnonSets[frame:GetName()].bags, ReverseSort);
618 if(frame.defaultBags) then
619 table.sort(frame.defaultBags, ReverseSort);
620 end
621 end
622 else
623 if(frame) then
624 table.sort(BagnonSets[frame:GetName()].bags, NormalSort);
625 if(frame.defaultBags) then
626 table.sort(frame.defaultBags, NormalSort);
627 end
628 end
629 end
630 end