annotate Summary.lua @ 54:06fee4208bf2

Altoholic should now properly show an on select message when chosen. Selecting DataStore as item count addons should no longer break. The local item count displayed in the summary is now actually local rather than global.
author Zerotorescue
date Mon, 20 Dec 2010 14:30:31 +0100
parents 9607b3251655
children 03c0610e9c1e
rev   line source
Zerotorescue@17 1 local addon = select(2, ...);
Zerotorescue@1 2 local mod = addon:NewModule("Summary", "AceEvent-3.0", "AceTimer-3.0");
Zerotorescue@0 3
Zerotorescue@0 4 local AceGUI = LibStub("AceGUI-3.0");
Zerotorescue@0 5
Zerotorescue@23 6 local unknownItemName = "Unknown (#%d)";
Zerotorescue@23 7
Zerotorescue@23 8 local itemsCache = {};
Zerotorescue@23 9
Zerotorescue@23 10 local CACHE_ITEMS_TOTAL, CACHE_ITEMS_CURRENT = 0, 0;
Zerotorescue@23 11 local cacheStart;
Zerotorescue@23 12
Zerotorescue@0 13 function mod:OnEnable()
Zerotorescue@0 14 self:RegisterWidgets();
Zerotorescue@0 15
Zerotorescue@1 16 -- Register our own slash commands
Zerotorescue@1 17 addon:RegisterSlash(function()
Zerotorescue@1 18 mod:BuildMain();
Zerotorescue@1 19 mod:Build();
Zerotorescue@36 20 end, { "s", "sum", "summary" }, "|Hfunction:InventoriumCommandHandler:summary|h|cff00fff7/im summary|r|h (or /im s) - Show the summary window containing an overview of all items within the groups tracked at this current character.");
Zerotorescue@23 21 addon:RegisterSlash(function()
Zerotorescue@23 22 if mod.frame then
Zerotorescue@23 23 mod.frame:SetWidth(650);
Zerotorescue@23 24 mod.frame:SetHeight(600);
Zerotorescue@23 25
Zerotorescue@23 26 print("Resetting width and height of the summary frame.");
Zerotorescue@23 27 end
Zerotorescue@36 28 end, { "r", "reset" }, "|Hfunction:InventoriumCommandHandler:reset|h|cff00fff7/im reset|r|h (or /im r) - Reset the size of the summary frame.");
Zerotorescue@0 29 end
Zerotorescue@0 30
Zerotorescue@13 31 local function ShowTooltip(self)
Zerotorescue@13 32 -- If this function is called from a widget, self is the widget and self.frame the actual frame
Zerotorescue@13 33 local this = self.frame or self;
Zerotorescue@13 34
Zerotorescue@13 35 GameTooltip:SetOwner(this, "ANCHOR_NONE");
Zerotorescue@13 36 GameTooltip:SetPoint("BOTTOM", this, "TOP");
Zerotorescue@13 37 GameTooltip:SetText(this.tooltipTitle, 1, .82, 0, 1);
Zerotorescue@13 38
Zerotorescue@13 39 if type(this.tooltip) == "string" then
Zerotorescue@13 40 GameTooltip:AddLine(this.tooltip, 1, 1, 1, 1);
Zerotorescue@13 41 end
Zerotorescue@13 42
Zerotorescue@13 43 GameTooltip:Show();
Zerotorescue@13 44 end
Zerotorescue@13 45
Zerotorescue@13 46 local function HideTooltip()
Zerotorescue@13 47 GameTooltip:Hide();
Zerotorescue@13 48 end
Zerotorescue@13 49
Zerotorescue@0 50 function mod:RegisterWidgets()
Zerotorescue@0 51 -- Register InlineGroupWithButton-widget
Zerotorescue@0 52 -- This widget adds a button next to the header of an inline group
Zerotorescue@0 53 -- SetPoint doesn't seem usable within AceGUI.
Zerotorescue@0 54
Zerotorescue@0 55 local widgetType = "InlineGroupWithButton";
Zerotorescue@0 56 local widgetVersion = 1;
Zerotorescue@0 57
Zerotorescue@0 58 local function Constructor()
Zerotorescue@0 59 local widget = AceGUI:Create("InlineGroup");
Zerotorescue@0 60 widget.type = widgetType;
Zerotorescue@0 61
Zerotorescue@0 62 widget.MakeButton = function(self, buttonSettings)
Zerotorescue@0 63 if type(buttonSettings) == "table" then
Zerotorescue@14 64 if not self.btnQueue then
Zerotorescue@14 65 -- Because widgets are re-used, we don't want to recreate this button
Zerotorescue@14 66 self.btnQueue = CreateFrame("Button", nil, self.frame, "UIPanelButtonTemplate");
Zerotorescue@14 67 self.btnQueue:SetHeight(22);
Zerotorescue@14 68 self.btnQueue:SetWidth(120);
Zerotorescue@14 69 end
Zerotorescue@14 70 self.btnQueue:SetText(buttonSettings.name);
Zerotorescue@14 71 self.btnQueue:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -10, 5);
Zerotorescue@14 72
Zerotorescue@14 73 -- Triggers
Zerotorescue@14 74 self.btnQueue:SetScript("OnClick", buttonSettings.exec);
Zerotorescue@14 75
Zerotorescue@14 76 -- Tooltip
Zerotorescue@14 77 self.btnQueue.tooltipTitle = buttonSettings.name;
Zerotorescue@14 78 self.btnQueue.tooltip = buttonSettings.desc or "";
Zerotorescue@14 79 self.btnQueue:SetScript("OnEnter", ShowTooltip);
Zerotorescue@14 80 self.btnQueue:SetScript("OnLeave", HideTooltip);
Zerotorescue@0 81 else
Zerotorescue@0 82 error("settings must be a table - usage: MakeButton(table);");
Zerotorescue@0 83 end
Zerotorescue@14 84 end;
Zerotorescue@0 85
Zerotorescue@0 86 return widget;
Zerotorescue@0 87 end
Zerotorescue@0 88
Zerotorescue@0 89 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion);
Zerotorescue@0 90 end
Zerotorescue@0 91
Zerotorescue@0 92 function mod:BuildMain()
Zerotorescue@11 93 LibStub("AceConfigDialog-3.0"):Close("InventoriumOptions");
Zerotorescue@0 94
Zerotorescue@10 95 self:CloseFrame();
Zerotorescue@10 96
Zerotorescue@1 97 -- Main Window
Zerotorescue@1 98 mod.frame = AceGUI:Create("Frame");
Zerotorescue@23 99 _G["InventoriumSummary"] = mod.frame; -- name the global frame so it can be put in the UISpecialFrames
Zerotorescue@13 100 mod.frame:SetTitle("Summary");
Zerotorescue@1 101 mod.frame:SetLayout("Fill");
Zerotorescue@1 102 mod.frame:SetCallback("OnClose", function(widget)
Zerotorescue@7 103 mod:CancelTimer(self.tmrUpdater, true);
Zerotorescue@9 104 mod:CloseFrame();
Zerotorescue@1 105 end);
Zerotorescue@13 106 mod.frame:SetWidth(addon.db.global.defaults.summary.width);
Zerotorescue@13 107 mod.frame:SetHeight(addon.db.global.defaults.summary.height);
Zerotorescue@13 108 mod.frame.OnWidthSet = function(_, width)
Zerotorescue@13 109 addon.db.global.defaults.summary.width = width;
Zerotorescue@13 110 end;
Zerotorescue@13 111 mod.frame.OnHeightSet = function(_, height)
Zerotorescue@13 112 addon.db.global.defaults.summary.height = height;
Zerotorescue@13 113 end;
Zerotorescue@0 114
Zerotorescue@23 115 -- Close on escape
Zerotorescue@23 116 tinsert(UISpecialFrames, "InventoriumSummary");
Zerotorescue@23 117
Zerotorescue@1 118 -- ScrollFrame child
Zerotorescue@1 119 mod.scrollFrame = AceGUI:Create("ScrollFrame");
Zerotorescue@1 120 mod.scrollFrame:SetLayout("Flow");
Zerotorescue@0 121
Zerotorescue@1 122 mod.frame:AddChild(mod.scrollFrame);
Zerotorescue@1 123
Zerotorescue@1 124 -- Reset items cache
Zerotorescue@1 125 table.wipe(itemsCache);
Zerotorescue@0 126 end
Zerotorescue@0 127
Zerotorescue@9 128 function mod:CloseFrame()
Zerotorescue@9 129 if mod.frame then
Zerotorescue@9 130 mod.frame:Release();
Zerotorescue@9 131 mod.frame = nil;
Zerotorescue@10 132
Zerotorescue@10 133 -- Stop caching
Zerotorescue@10 134
Zerotorescue@10 135 -- Stop timer
Zerotorescue@10 136 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@10 137
Zerotorescue@10 138 -- Reset trackers
Zerotorescue@10 139 CACHE_ITEMS_TOTAL = 0;
Zerotorescue@10 140 CACHE_ITEMS_CURRENT = 0;
Zerotorescue@9 141 end
Zerotorescue@9 142 end
Zerotorescue@9 143
Zerotorescue@0 144 local sortMethod = "item";
Zerotorescue@0 145 local sortDirectory = "ASC";
Zerotorescue@0 146 local function ReSort(subject)
Zerotorescue@0 147 if sortMethod == subject then
Zerotorescue@0 148 sortDirectory = (sortDirectory == "ASC" and "DESC") or "ASC";
Zerotorescue@0 149 else
Zerotorescue@0 150 sortDirectory = "ASC";
Zerotorescue@0 151 end
Zerotorescue@0 152 sortMethod = subject;
Zerotorescue@0 153
Zerotorescue@0 154 mod:Build();
Zerotorescue@0 155 end
Zerotorescue@10 156
Zerotorescue@10 157 -- From http://www.wowwiki.com/API_sort
Zerotorescue@10 158 local function pairsByKeys (t, f)
Zerotorescue@10 159 local a = {}
Zerotorescue@10 160 for n in pairs(t) do table.insert(a, n) end
Zerotorescue@10 161 table.sort(a, f)
Zerotorescue@10 162 local i = 0 -- iterator variable
Zerotorescue@10 163 local iter = function () -- iterator function
Zerotorescue@10 164 i = i + 1
Zerotorescue@10 165 if a[i] == nil then return nil
Zerotorescue@10 166 else return a[i], t[a[i]]
Zerotorescue@10 167 end
Zerotorescue@10 168 end
Zerotorescue@10 169 return iter
Zerotorescue@10 170 end
Zerotorescue@0 171
Zerotorescue@0 172 function mod:Build()
Zerotorescue@10 173 local buildStartTime, times = GetTime(), {};
Zerotorescue@0 174
Zerotorescue@1 175 -- We are going to add hunderds of widgets to this container, but don't want it to also cause hunderds of reflows, thus pause reflowing and just do it once when everything is prepared
Zerotorescue@1 176 -- This appears to be required for each container we wish to pause, so also do this for the contents
Zerotorescue@1 177 mod.scrollFrame:PauseLayout();
Zerotorescue@1 178
Zerotorescue@10 179 mod.scrollFrame:ReleaseChildren();
Zerotorescue@10 180
Zerotorescue@10 181 -- Refresh button
Zerotorescue@10 182 local btnRefresh = AceGUI:Create("Button");
Zerotorescue@10 183 btnRefresh:SetText("Refresh");
Zerotorescue@10 184 btnRefresh:SetRelativeWidth(.2);
Zerotorescue@10 185 btnRefresh:SetCallback("OnClick", function()
Zerotorescue@10 186 -- Reset items cache
Zerotorescue@10 187 table.wipe(itemsCache);
Zerotorescue@10 188
Zerotorescue@10 189 -- Rebuild itemlist and start caching
Zerotorescue@10 190 mod:Build();
Zerotorescue@10 191 end);
Zerotorescue@13 192 btnRefresh:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 193 btnRefresh:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 194 btnRefresh.frame.tooltipTitle = "Refresh Cache";
Zerotorescue@13 195 btnRefresh.frame.tooltip = "Refresh the list and recache the item counts and auction values.";
Zerotorescue@10 196
Zerotorescue@10 197 mod.scrollFrame:AddChild(btnRefresh);
Zerotorescue@10 198
Zerotorescue@13 199 local lblSpacer = AceGUI:Create("Label");
Zerotorescue@13 200 lblSpacer:SetRelativeWidth(.03);
Zerotorescue@13 201
Zerotorescue@13 202 mod.scrollFrame:AddChild(lblSpacer);
Zerotorescue@13 203
Zerotorescue@10 204 -- Speed slider
Zerotorescue@13 205 local sdrSpeed = AceGUI:Create("Slider");
Zerotorescue@13 206 sdrSpeed:SetLabel("Processing speed");
Zerotorescue@14 207 sdrSpeed:SetSliderValues(0.01, 5, 0.05);
Zerotorescue@13 208 sdrSpeed:SetIsPercent(true);
Zerotorescue@13 209 sdrSpeed:SetRelativeWidth(.3);
Zerotorescue@13 210 sdrSpeed:SetCallback("OnMouseUp", function(self, event, value)
Zerotorescue@13 211 addon.db.global.defaults.summary.speed = ceil( value * 100 / 5 );
Zerotorescue@13 212
Zerotorescue@13 213 CACHE_ITEMS_PER_UPDATE = addon.db.global.defaults.summary.speed; -- max = 20, min = 1
Zerotorescue@10 214 end);
Zerotorescue@13 215 sdrSpeed:SetValue( addon.db.global.defaults.summary.speed * 5 / 100 );
Zerotorescue@13 216 sdrSpeed:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 217 sdrSpeed:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 218 sdrSpeed.frame.tooltipTitle = "Caching Processing Speed";
Zerotorescue@13 219 sdrSpeed.frame.tooltip = "Change the speed at which item counts and auction values are being cached. Higher is faster but may drastically reduce your FPS while caching.\n\nAnything above 100% will probably become uncomfortable.";
Zerotorescue@10 220
Zerotorescue@13 221 mod.scrollFrame:AddChild(sdrSpeed);
Zerotorescue@13 222
Zerotorescue@13 223 local lblSpacer = AceGUI:Create("Label");
Zerotorescue@13 224 lblSpacer:SetRelativeWidth(.23);
Zerotorescue@13 225
Zerotorescue@13 226 mod.scrollFrame:AddChild(lblSpacer);
Zerotorescue@13 227
Zerotorescue@13 228 -- Config button
Zerotorescue@13 229 --[[local btnConfig = AceGUI:Create("Button");
Zerotorescue@13 230 btnConfig:SetText("Config");
Zerotorescue@13 231 btnConfig:SetRelativeWidth(.2);
Zerotorescue@13 232 btnConfig:SetCallback("OnClick", function()
Zerotorescue@13 233 --TODO: Tidy up
Zerotorescue@13 234 SlashCmdList["INVENTORIUM"]("config");
Zerotorescue@13 235 end);
Zerotorescue@13 236 btnConfig:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 237 btnConfig:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 238 btnConfig.frame.tooltipTitle = "Config";
Zerotorescue@13 239 btnConfig.frame.tooltip = "Click to open the config window. This will close the current window.";
Zerotorescue@13 240
Zerotorescue@13 241 mod.scrollFrame:AddChild(btnConfig);]]
Zerotorescue@13 242
Zerotorescue@13 243 local lblSpacer = AceGUI:Create("Label");
Zerotorescue@13 244 lblSpacer:SetRelativeWidth(.03);
Zerotorescue@13 245
Zerotorescue@13 246 mod.scrollFrame:AddChild(lblSpacer);
Zerotorescue@13 247
Zerotorescue@13 248 -- Queue all button
Zerotorescue@13 249 local btnQueueAll = AceGUI:Create("Button");
Zerotorescue@13 250 btnQueueAll:SetText("Queue All");
Zerotorescue@13 251 btnQueueAll:SetRelativeWidth(.2);
Zerotorescue@13 252 btnQueueAll:SetCallback("OnClick", function()
Zerotorescue@14 253 self:SendMessage("IM_QUEUE_ALL");
Zerotorescue@13 254 end);
Zerotorescue@13 255 btnQueueAll:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 256 btnQueueAll:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 257 btnQueueAll.frame.tooltipTitle = "Queue all";
Zerotorescue@13 258 btnQueueAll.frame.tooltip = "Queue everything that requires restocking within every single visible group.";
Zerotorescue@13 259
Zerotorescue@13 260 mod.scrollFrame:AddChild(btnQueueAll);
Zerotorescue@10 261
Zerotorescue@10 262 times.init = ceil( ( GetTime() - buildStartTime ) * 1000 );
Zerotorescue@10 263 addon:Debug("Time spent legend: (init / sorting / preparing / building / all).");
Zerotorescue@10 264
Zerotorescue@1 265 local playerName = UnitName("player");
Zerotorescue@1 266
Zerotorescue@1 267 -- Go through all our stored groups
Zerotorescue@10 268 for groupName, values in pairsByKeys(addon.db.global.groups, function(a, b) return a:lower() < b:lower(); end) do
Zerotorescue@10 269 local groupStartTime, groupTimes = GetTime(), {};
Zerotorescue@10 270
Zerotorescue@50 271 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@50 272
Zerotorescue@1 273
Zerotorescue@1 274 -- Does this group have any items and do we want to track it at this char?
Zerotorescue@1 275 if values.items and trackAt[playerName] then
Zerotorescue@10 276
Zerotorescue@10 277
Zerotorescue@0 278 -- Get group settings
Zerotorescue@50 279 local minimumStock = addon:GetOptionByKey(groupName, "minimumStock");
Zerotorescue@50 280 local showWhenBelow = addon:GetOptionByKey(groupName, "summaryThresholdShow");
Zerotorescue@50 281 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@50 282 local hideWhenBelowPriceThreshold = addon:GetOptionByKey(groupName, "summaryHidePriceThreshold");
Zerotorescue@50 283 local alwaysGetAuctionValue = addon:GetOptionByKey(groupName, "alwaysGetAuctionValue");
Zerotorescue@10 284
Zerotorescue@0 285 -- Make group container
Zerotorescue@0 286 local iGroup = AceGUI:Create("InlineGroupWithButton");
Zerotorescue@1 287 iGroup:PauseLayout();
Zerotorescue@0 288 iGroup:SetTitle(groupName);
Zerotorescue@0 289 iGroup:SetFullWidth(true);
Zerotorescue@0 290 iGroup:SetLayout("Flow");
Zerotorescue@0 291 iGroup:MakeButton({
Zerotorescue@0 292 name = "Queue",
Zerotorescue@0 293 desc = "Queue all items in this group.",
Zerotorescue@0 294 exec = function()
Zerotorescue@14 295 print("Queueing all items within " .. groupName .. " craftable by the currently open profession.");
Zerotorescue@14 296 self:SendMessage("IM_QUEUE_GROUP", groupName);
Zerotorescue@0 297 end,
Zerotorescue@0 298 });
Zerotorescue@0 299
Zerotorescue@10 300
Zerotorescue@10 301
Zerotorescue@0 302 -- Headers
Zerotorescue@1 303
Zerotorescue@0 304 -- Itemlink
Zerotorescue@0 305 local lblItem = AceGUI:Create("InteractiveLabel");
Zerotorescue@0 306 lblItem:SetText("|cfffed000Item|r");
Zerotorescue@0 307 lblItem:SetFontObject(GameFontHighlight);
Zerotorescue@50 308 lblItem:SetRelativeWidth(.6);
Zerotorescue@0 309 lblItem:SetCallback("OnClick", function() ReSort("item"); end);
Zerotorescue@13 310 lblItem:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 311 lblItem:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 312 lblItem.frame.tooltipTitle = "Item";
Zerotorescue@13 313 lblItem.frame.tooltip = "Sort on the item quality, then name.";
Zerotorescue@0 314
Zerotorescue@0 315 iGroup:AddChild(lblItem);
Zerotorescue@0 316
Zerotorescue@50 317 -- Local quantity
Zerotorescue@50 318 local lblLocal = AceGUI:Create("InteractiveLabel");
Zerotorescue@50 319 lblLocal:SetText("|cfffed000Loc.|r");
Zerotorescue@50 320 lblLocal:SetFontObject(GameFontHighlight);
Zerotorescue@50 321 lblLocal:SetRelativeWidth(.099);
Zerotorescue@50 322 lblLocal:SetCallback("OnClick", function() ReSort("local"); end);
Zerotorescue@50 323 lblLocal:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@50 324 lblLocal:SetCallback("OnLeave", HideTooltip);
Zerotorescue@50 325 lblLocal.frame.tooltipTitle = "Local stock";
Zerotorescue@50 326 lblLocal.frame.tooltip = "Sort on the amount of items currently in local stock.";
Zerotorescue@50 327
Zerotorescue@50 328 iGroup:AddChild(lblLocal);
Zerotorescue@50 329
Zerotorescue@0 330 -- Current quantity
Zerotorescue@0 331 local lblQuantity = AceGUI:Create("InteractiveLabel");
Zerotorescue@0 332 lblQuantity:SetText("|cfffed000Cur.|r");
Zerotorescue@0 333 lblQuantity:SetFontObject(GameFontHighlight);
Zerotorescue@10 334 lblQuantity:SetRelativeWidth(.099);
Zerotorescue@0 335 lblQuantity:SetCallback("OnClick", function() ReSort("current"); end);
Zerotorescue@13 336 lblQuantity:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 337 lblQuantity:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 338 lblQuantity.frame.tooltipTitle = "Current stock";
Zerotorescue@13 339 lblQuantity.frame.tooltip = "Sort on the amount of items currently in stock.";
Zerotorescue@0 340
Zerotorescue@0 341 iGroup:AddChild(lblQuantity);
Zerotorescue@0 342
Zerotorescue@0 343 -- Required stock
Zerotorescue@9 344 local lblMinimumStock = AceGUI:Create("InteractiveLabel");
Zerotorescue@13 345 lblMinimumStock:SetText("|cfffed000Min.|r");
Zerotorescue@9 346 lblMinimumStock:SetFontObject(GameFontHighlight);
Zerotorescue@10 347 lblMinimumStock:SetRelativeWidth(.099);
Zerotorescue@9 348 lblMinimumStock:SetCallback("OnClick", function() ReSort("percentage"); end);
Zerotorescue@13 349 lblMinimumStock:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 350 lblMinimumStock:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 351 lblMinimumStock.frame.tooltipTitle = "Minimum stock";
Zerotorescue@13 352 lblMinimumStock.frame.tooltip = "Sort on the minimum amount of items you wish to keep in stock.";
Zerotorescue@0 353
Zerotorescue@9 354 iGroup:AddChild(lblMinimumStock);
Zerotorescue@0 355
Zerotorescue@1 356 -- Lowest value
Zerotorescue@1 357 local lblValue = AceGUI:Create("InteractiveLabel");
Zerotorescue@1 358 lblValue:SetText("|cfffed000Value|r");
Zerotorescue@1 359 lblValue:SetFontObject(GameFontHighlight);
Zerotorescue@10 360 lblValue:SetRelativeWidth(.099);
Zerotorescue@1 361 lblValue:SetCallback("OnClick", function() ReSort("value"); end);
Zerotorescue@13 362 lblValue:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 363 lblValue:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 364 lblValue.frame.tooltipTitle = "Value";
Zerotorescue@13 365 lblValue.frame.tooltip = "Sort on the item auction value.";
Zerotorescue@1 366
Zerotorescue@1 367 iGroup:AddChild(lblValue);
Zerotorescue@1 368
Zerotorescue@10 369
Zerotorescue@10 370 -- Retrieve items list
Zerotorescue@1 371 if not itemsCache[groupName] then
Zerotorescue@1 372 itemsCache[groupName] = {};
Zerotorescue@0 373
Zerotorescue@1 374 -- Sort item list
Zerotorescue@12 375 for itemId, _ in pairs(values.items) do
Zerotorescue@1 376 local itemName, itemLink, itemRarity = GetItemInfo(itemId);
Zerotorescue@1 377
Zerotorescue@1 378 table.insert(itemsCache[groupName], {
Zerotorescue@1 379 id = itemId,
Zerotorescue@12 380 name = itemName or unknownItemName:format(itemId),
Zerotorescue@23 381 link = itemLink,
Zerotorescue@23 382 value = ((priceThreshold == 0 and not alwaysGetAuctionValue) and -4) or -3,-- if (no price threshold is set for this item and you don't want to always get auction value), then don't look it up either --addon:GetAuctionValue(itemLink),
Zerotorescue@12 383 rarity = itemRarity or 1,
Zerotorescue@23 384 count = -3,--addon:GetItemCount(itemId, groupName),
Zerotorescue@50 385 localCount = -3,
Zerotorescue@1 386 set = {},
Zerotorescue@1 387 });
Zerotorescue@1 388 CACHE_ITEMS_TOTAL = CACHE_ITEMS_TOTAL + 1;
Zerotorescue@1 389 end
Zerotorescue@0 390 end
Zerotorescue@0 391
Zerotorescue@10 392 groupTimes.init = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 393
Zerotorescue@10 394
Zerotorescue@10 395
Zerotorescue@10 396 -- Sort items
Zerotorescue@1 397 table.sort(itemsCache[groupName], function(a, b)
Zerotorescue@1 398 if sortMethod == "item" and a.rarity == b.rarity then
Zerotorescue@1 399 -- Do a name-compare for items of the same rarity
Zerotorescue@1 400 -- Otherwise epics first, then junk
Zerotorescue@0 401 if sortDirectory == "ASC" then
Zerotorescue@1 402 return a.name:upper() < b.name:upper();
Zerotorescue@0 403 else
Zerotorescue@1 404 return a.name:upper() > b.name:upper();
Zerotorescue@1 405 end
Zerotorescue@1 406 elseif sortMethod == "item" then
Zerotorescue@1 407 if sortDirectory == "ASC" then
Zerotorescue@1 408 return a.rarity > b.rarity; -- the comparers were reversed because we want epics first
Zerotorescue@1 409 else
Zerotorescue@1 410 return a.rarity < b.rarity; -- the comparers were reversed because we want epics first
Zerotorescue@0 411 end
Zerotorescue@0 412 elseif sortMethod == "current" then
Zerotorescue@0 413 if sortDirectory == "ASC" then
Zerotorescue@0 414 return a.count < b.count;
Zerotorescue@0 415 else
Zerotorescue@0 416 return a.count > b.count;
Zerotorescue@0 417 end
Zerotorescue@50 418 elseif sortMethod == "local" then
Zerotorescue@50 419 if sortDirectory == "ASC" then
Zerotorescue@50 420 return a.localCount < b.localCount;
Zerotorescue@50 421 else
Zerotorescue@50 422 return a.localCount > b.localCount;
Zerotorescue@50 423 end
Zerotorescue@0 424 elseif sortMethod == "percentage" then
Zerotorescue@0 425 if sortDirectory == "ASC" then
Zerotorescue@10 426 return ( a.count / minimumStock ) < ( b.count / minimumStock );
Zerotorescue@0 427 else
Zerotorescue@10 428 return ( a.count / minimumStock ) > ( b.count / minimumStock );
Zerotorescue@0 429 end
Zerotorescue@1 430 elseif sortMethod == "value" then
Zerotorescue@1 431 if sortDirectory == "ASC" then
Zerotorescue@1 432 return a.value < b.value;
Zerotorescue@1 433 else
Zerotorescue@1 434 return a.value > b.value;
Zerotorescue@1 435 end
Zerotorescue@0 436 end
Zerotorescue@0 437 end);
Zerotorescue@0 438
Zerotorescue@10 439 groupTimes.sorting = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 440
Zerotorescue@10 441
Zerotorescue@10 442
Zerotorescue@10 443
Zerotorescue@10 444 -- Show itemslist
Zerotorescue@1 445 for i, item in pairs(itemsCache[groupName]) do
Zerotorescue@31 446 -- Go through all items for this group
Zerotorescue@31 447
Zerotorescue@50 448 if (( item.count / minimumStock ) < showWhenBelow or ( item.localCount / minimumStock ) < showWhenBelow) and (not hideWhenBelowPriceThreshold or priceThreshold == 0 or item.value < 0 or item.value >= priceThreshold) then
Zerotorescue@31 449 -- if the option "hide when below threshold" is disabled or no price threshold is set or the value is above the price threshold or the value could not be determined, proceed
Zerotorescue@50 450
Zerotorescue@0 451 local btnItemLink = AceGUI:Create("ItemLinkButton");
Zerotorescue@23 452 btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName)
Zerotorescue@23 453 local itemName, itemLink = GetItemInfo(itemId);
Zerotorescue@23 454
Zerotorescue@23 455 if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then
Zerotorescue@23 456 ChatEdit_InsertLink(itemLink);
Zerotorescue@23 457 elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then
Zerotorescue@23 458 -- Start search at page 0
Zerotorescue@23 459 AuctionFrameBrowse.page = 0;
Zerotorescue@23 460
Zerotorescue@23 461 -- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated)
Zerotorescue@23 462 BrowseName:SetText(itemName)
Zerotorescue@23 463
Zerotorescue@23 464 QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0);
Zerotorescue@23 465 end
Zerotorescue@23 466 end);
Zerotorescue@50 467 btnItemLink:SetRelativeWidth(.6);
Zerotorescue@1 468 btnItemLink:SetItemId(item.id);
Zerotorescue@0 469
Zerotorescue@0 470 iGroup:AddChild(btnItemLink);
Zerotorescue@0 471
Zerotorescue@50 472 -- Local quantity
Zerotorescue@50 473 local lblLocal = AceGUI:Create("Label");
Zerotorescue@50 474 lblLocal:SetText(self:DisplayItemCount(item.localCount, minimumStock));
Zerotorescue@50 475 lblLocal:SetRelativeWidth(.099);
Zerotorescue@50 476
Zerotorescue@50 477 iGroup:AddChild(lblLocal);
Zerotorescue@50 478
Zerotorescue@0 479 -- Current quantity
Zerotorescue@0 480 local lblQuantity = AceGUI:Create("Label");
Zerotorescue@9 481 lblQuantity:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 482 lblQuantity:SetRelativeWidth(.099);
Zerotorescue@0 483
Zerotorescue@0 484 iGroup:AddChild(lblQuantity);
Zerotorescue@0 485
Zerotorescue@0 486 -- Required stock
Zerotorescue@9 487 local lblMinimumStock = AceGUI:Create("Label");
Zerotorescue@9 488 lblMinimumStock:SetText(minimumStock);
Zerotorescue@10 489 lblMinimumStock:SetRelativeWidth(.099);
Zerotorescue@0 490
Zerotorescue@9 491 iGroup:AddChild(lblMinimumStock);
Zerotorescue@1 492
Zerotorescue@1 493 -- Value
Zerotorescue@1 494 local lblValue = AceGUI:Create("Label");
Zerotorescue@1 495 lblValue:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@10 496 lblValue:SetRelativeWidth(.099);
Zerotorescue@1 497
Zerotorescue@1 498 iGroup:AddChild(lblValue);
Zerotorescue@1 499
Zerotorescue@1 500 -- Remember references to the value and current fields so we can fill them later
Zerotorescue@1 501 if item.set then
Zerotorescue@10 502 -- -3 means the price is unknown, queue look up
Zerotorescue@10 503 if item.value == -3 then
Zerotorescue@10 504 item.set.value = lblValue;
Zerotorescue@10 505 end
Zerotorescue@10 506 if item.count == -3 then
Zerotorescue@10 507 item.set.current = lblQuantity;
Zerotorescue@10 508 end
Zerotorescue@50 509 if item.localCount == -3 then
Zerotorescue@50 510 item.set.localCount = lblLocal;
Zerotorescue@50 511 end
Zerotorescue@10 512
Zerotorescue@10 513 -- Don't queue if we already know everything we want to know
Zerotorescue@50 514 if item.value ~= -3 and item.count ~= -3 and item.localCount ~= -3 then
Zerotorescue@10 515 item.set = nil;
Zerotorescue@10 516 end
Zerotorescue@1 517 end
Zerotorescue@0 518 end
Zerotorescue@0 519 end
Zerotorescue@0 520
Zerotorescue@10 521 groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 522
Zerotorescue@1 523 iGroup:ResumeLayout();
Zerotorescue@1 524 mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time
Zerotorescue@10 525
Zerotorescue@10 526 groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@0 527 end
Zerotorescue@10 528
Zerotorescue@13 529 if groupStartTime and groupTimes then
Zerotorescue@13 530 addon:Debug(("Building of %s took %d ms (%d / %d / %d / %d / %d)."):format(groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 )));
Zerotorescue@13 531 end
Zerotorescue@0 532 end
Zerotorescue@1 533
Zerotorescue@1 534 mod.scrollFrame:ResumeLayout();
Zerotorescue@1 535 mod.scrollFrame:DoLayout();
Zerotorescue@1 536
Zerotorescue@10 537 addon:Debug(("Done building summary after %d ms."):format(ceil( ( GetTime() - buildStartTime ) * 1000 )));
Zerotorescue@10 538
Zerotorescue@1 539 if CACHE_ITEMS_TOTAL > 0 then
Zerotorescue@1 540 cacheStart = GetTime();
Zerotorescue@7 541 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@1 542 self.tmrUpdater = self:ScheduleRepeatingTimer("UpdateNextItem", .01); -- Once every 100 frames (or once every x frames if you have less than 100 FPS, basically, once every frame)
Zerotorescue@1 543 end
Zerotorescue@1 544 end
Zerotorescue@1 545
Zerotorescue@1 546 function mod:UpdateNextItem()
Zerotorescue@1 547 local i = 0;
Zerotorescue@1 548
Zerotorescue@1 549 for groupName, items in pairs(itemsCache) do
Zerotorescue@1 550 local minimumStock = addon:GetOptionByKey(groupName, "minimumStock");
Zerotorescue@1 551 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@1 552
Zerotorescue@1 553 for _, item in pairs(items) do
Zerotorescue@1 554 if item.set then
Zerotorescue@10 555 if item.count == -3 then
Zerotorescue@10 556 -- Only if item count was queued, update it
Zerotorescue@23 557 item.count = addon:GetItemCount(item.id, groupName);
Zerotorescue@10 558 if item.set.current and item.set.current.SetText then
Zerotorescue@10 559 item.set.current:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 560 end
Zerotorescue@1 561 end
Zerotorescue@1 562
Zerotorescue@50 563 if item.localCount == -3 then
Zerotorescue@50 564 -- Only if item count was queued, update it
Zerotorescue@54 565 item.localCount = addon:GetLocalItemCount(item.id, groupName);
Zerotorescue@50 566 if item.set.localCount and item.set.localCount.SetText then
Zerotorescue@50 567 item.set.localCount:SetText(self:DisplayItemCount(item.localCount, minimumStock));
Zerotorescue@50 568 end
Zerotorescue@50 569 end
Zerotorescue@50 570
Zerotorescue@10 571 if item.value == -3 then
Zerotorescue@10 572 -- Only if item value was queued, update it
Zerotorescue@23 573
Zerotorescue@23 574 -- The itemlink might not have been loaded yet in which case we retry
Zerotorescue@23 575 item.link = item.link or select(2, GetItemInfo(item.id));
Zerotorescue@23 576
Zerotorescue@23 577 if item.link then
Zerotorescue@23 578 item.value = addon:GetAuctionValue(item.link, groupName);
Zerotorescue@23 579 if item.set.value and item.set.value.SetText then
Zerotorescue@23 580 item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@23 581 end
Zerotorescue@10 582 end
Zerotorescue@1 583 end
Zerotorescue@1 584
Zerotorescue@1 585 item.set = nil;
Zerotorescue@1 586
Zerotorescue@1 587 i = i + 1;
Zerotorescue@1 588 CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1;
Zerotorescue@1 589
Zerotorescue@9 590 if mod.frame then
Zerotorescue@9 591 mod.frame:SetStatusText(("Caching auction values and item-counts... %d%% has already been processed."):format(floor(CACHE_ITEMS_CURRENT / CACHE_ITEMS_TOTAL * 100)));
Zerotorescue@9 592 end
Zerotorescue@1 593
Zerotorescue@13 594 if i >= addon.db.global.defaults.summary.speed then
Zerotorescue@1 595 return;
Zerotorescue@1 596 end
Zerotorescue@1 597 end
Zerotorescue@1 598 end
Zerotorescue@1 599 end
Zerotorescue@1 600
Zerotorescue@1 601 -- Reset trackers
Zerotorescue@1 602 CACHE_ITEMS_TOTAL = 0;
Zerotorescue@1 603 CACHE_ITEMS_CURRENT = 0;
Zerotorescue@1 604
Zerotorescue@1 605 -- Stop timer
Zerotorescue@1 606 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@10 607
Zerotorescue@10 608 -- Rebuild list so hidden items due to too low prices get added
Zerotorescue@10 609 self:Build();
Zerotorescue@1 610
Zerotorescue@1 611 -- Announce
Zerotorescue@10 612 mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds.");
Zerotorescue@1 613
Zerotorescue@1 614 -- Forget time
Zerotorescue@1 615 cacheStart = nil;
Zerotorescue@0 616 end
Zerotorescue@0 617
Zerotorescue@0 618 function mod:ColorCode(num, required)
Zerotorescue@0 619 local percentage = ( num / required );
Zerotorescue@0 620
Zerotorescue@0 621 if percentage >= addon.db.global.defaults.colors.green then
Zerotorescue@0 622 return ("|cff00ff00%d|r"):format(num);
Zerotorescue@0 623 elseif percentage >= addon.db.global.defaults.colors.yellow then
Zerotorescue@0 624 return ("|cffffff00%d|r"):format(num);
Zerotorescue@0 625 elseif percentage >= addon.db.global.defaults.colors.orange then
Zerotorescue@0 626 return ("|cffff9933%d|r"):format(num);
Zerotorescue@0 627 elseif percentage >= addon.db.global.defaults.colors.red then
Zerotorescue@0 628 return ("|cffff0000%d|r"):format(num);
Zerotorescue@0 629 end
Zerotorescue@0 630 end
Zerotorescue@0 631
Zerotorescue@1 632 function mod:DisplayMoney(value, priceThreshold)
Zerotorescue@7 633 if value == -1 then
Zerotorescue@7 634 return "|cff0000ffNone up|r";
Zerotorescue@7 635 elseif value == -2 then
Zerotorescue@7 636 return "|cff0000ffNo AH mod|r";
Zerotorescue@9 637 elseif value == -3 then
Zerotorescue@9 638 return "|cffffff00Unknown|r";
Zerotorescue@13 639 elseif value == -4 then
Zerotorescue@13 640 return "|cff00ff00-|r";
Zerotorescue@23 641 elseif value == -5 then
Zerotorescue@23 642 return "|cffff9933Error|r";
Zerotorescue@23 643 elseif priceThreshold and value < priceThreshold then
Zerotorescue@17 644 return ("|cffaaaaaa%s|r"):format(addon:ReadableMoney(value or 0, true):gsub("|([a-fA-F0-9]+)([gsc]+)|r", "%2"));
Zerotorescue@1 645 else
Zerotorescue@1 646 return addon:ReadableMoney(value or 0, true);
Zerotorescue@1 647 end
Zerotorescue@1 648 end
Zerotorescue@1 649
Zerotorescue@9 650 function mod:DisplayItemCount(value, minimumStock)
Zerotorescue@13 651 if value == -1 then
Zerotorescue@13 652 return "|cffffff00Unknown|r";
Zerotorescue@13 653 elseif value == -3 then
Zerotorescue@9 654 return "|cffffff00Unknown|r";
Zerotorescue@9 655 else
Zerotorescue@9 656 return self:ColorCode(value, minimumStock);
Zerotorescue@9 657 end
Zerotorescue@9 658 end
Zerotorescue@9 659
Zerotorescue@0 660 function mod:NumberFormat(num)
Zerotorescue@0 661 local formatted = string.gsub(num, "(%d)(%d%d%d)$", "%1,%2", 1);
Zerotorescue@0 662
Zerotorescue@0 663 while true do
Zerotorescue@0 664 formatted, matches = string.gsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1);
Zerotorescue@0 665
Zerotorescue@0 666 if matches == 0 then
Zerotorescue@0 667 break;
Zerotorescue@0 668 end
Zerotorescue@0 669 end
Zerotorescue@0 670
Zerotorescue@0 671 return formatted;
Zerotorescue@1 672 end