annotate Summary.lua @ 27:95c813292a88

Fixed the ?Hide when below threshold? option.
author Zerotorescue
date Thu, 28 Oct 2010 19:31:58 +0200
parents 7d7aaa3fbe94
children e732843b16d2
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@1 20 end, "s", "sum", "summary");
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@23 28 end, "r", "reset");
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@1 271 local trackAt = (values.trackAtCharacters or (values.trackAtCharacters == nil and addon.db.global.defaults.trackAtCharacters));
Zerotorescue@1 272
Zerotorescue@1 273 -- Does this group have any items and do we want to track it at this char?
Zerotorescue@1 274 if values.items and trackAt[playerName] then
Zerotorescue@10 275
Zerotorescue@10 276
Zerotorescue@0 277 -- Get group settings
Zerotorescue@9 278 local minimumStock = (values.minimumStock or (values.minimumStock == nil and addon.db.global.defaults.minimumStock));
Zerotorescue@1 279 local showWhenBelow = (values.summaryThresholdShow or (values.summaryThresholdShow == nil and addon.db.global.defaults.summaryThresholdShow));
Zerotorescue@1 280 local priceThreshold = (values.priceThreshold or (values.priceThreshold == nil and addon.db.global.defaults.priceThreshold));
Zerotorescue@27 281 local hideWhenBelowPriceThreshold = (values.summaryHidePriceThreshold or (values.summaryHidePriceThreshold == nil and addon.db.global.defaults.summaryHidePriceThreshold));
Zerotorescue@23 282 local alwaysGetAuctionValue = (values.alwaysGetAuctionValue or (values.alwaysGetAuctionValue == nil and addon.db.global.defaults.alwaysGetAuctionValue));
Zerotorescue@10 283
Zerotorescue@0 284 -- Make group container
Zerotorescue@0 285 local iGroup = AceGUI:Create("InlineGroupWithButton");
Zerotorescue@1 286 iGroup:PauseLayout();
Zerotorescue@0 287 iGroup:SetTitle(groupName);
Zerotorescue@0 288 iGroup:SetFullWidth(true);
Zerotorescue@0 289 iGroup:SetLayout("Flow");
Zerotorescue@0 290 iGroup:MakeButton({
Zerotorescue@0 291 name = "Queue",
Zerotorescue@0 292 desc = "Queue all items in this group.",
Zerotorescue@0 293 exec = function()
Zerotorescue@14 294 print("Queueing all items within " .. groupName .. " craftable by the currently open profession.");
Zerotorescue@14 295 self:SendMessage("IM_QUEUE_GROUP", groupName);
Zerotorescue@0 296 end,
Zerotorescue@0 297 });
Zerotorescue@0 298
Zerotorescue@10 299
Zerotorescue@10 300
Zerotorescue@0 301 -- Headers
Zerotorescue@1 302
Zerotorescue@0 303 -- Itemlink
Zerotorescue@0 304 local lblItem = AceGUI:Create("InteractiveLabel");
Zerotorescue@0 305 lblItem:SetText("|cfffed000Item|r");
Zerotorescue@0 306 lblItem:SetFontObject(GameFontHighlight);
Zerotorescue@10 307 lblItem:SetRelativeWidth(.7);
Zerotorescue@0 308 lblItem:SetCallback("OnClick", function() ReSort("item"); end);
Zerotorescue@13 309 lblItem:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 310 lblItem:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 311 lblItem.frame.tooltipTitle = "Item";
Zerotorescue@13 312 lblItem.frame.tooltip = "Sort on the item quality, then name.";
Zerotorescue@0 313
Zerotorescue@0 314 iGroup:AddChild(lblItem);
Zerotorescue@0 315
Zerotorescue@0 316 -- Current quantity
Zerotorescue@0 317 local lblQuantity = AceGUI:Create("InteractiveLabel");
Zerotorescue@0 318 lblQuantity:SetText("|cfffed000Cur.|r");
Zerotorescue@0 319 lblQuantity:SetFontObject(GameFontHighlight);
Zerotorescue@10 320 lblQuantity:SetRelativeWidth(.099);
Zerotorescue@0 321 lblQuantity:SetCallback("OnClick", function() ReSort("current"); end);
Zerotorescue@13 322 lblQuantity:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 323 lblQuantity:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 324 lblQuantity.frame.tooltipTitle = "Current stock";
Zerotorescue@13 325 lblQuantity.frame.tooltip = "Sort on the amount of items currently in stock.";
Zerotorescue@0 326
Zerotorescue@0 327 iGroup:AddChild(lblQuantity);
Zerotorescue@0 328
Zerotorescue@0 329 -- Required stock
Zerotorescue@9 330 local lblMinimumStock = AceGUI:Create("InteractiveLabel");
Zerotorescue@13 331 lblMinimumStock:SetText("|cfffed000Min.|r");
Zerotorescue@9 332 lblMinimumStock:SetFontObject(GameFontHighlight);
Zerotorescue@10 333 lblMinimumStock:SetRelativeWidth(.099);
Zerotorescue@9 334 lblMinimumStock:SetCallback("OnClick", function() ReSort("percentage"); end);
Zerotorescue@13 335 lblMinimumStock:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 336 lblMinimumStock:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 337 lblMinimumStock.frame.tooltipTitle = "Minimum stock";
Zerotorescue@13 338 lblMinimumStock.frame.tooltip = "Sort on the minimum amount of items you wish to keep in stock.";
Zerotorescue@0 339
Zerotorescue@9 340 iGroup:AddChild(lblMinimumStock);
Zerotorescue@0 341
Zerotorescue@1 342 -- Lowest value
Zerotorescue@1 343 local lblValue = AceGUI:Create("InteractiveLabel");
Zerotorescue@1 344 lblValue:SetText("|cfffed000Value|r");
Zerotorescue@1 345 lblValue:SetFontObject(GameFontHighlight);
Zerotorescue@10 346 lblValue:SetRelativeWidth(.099);
Zerotorescue@1 347 lblValue:SetCallback("OnClick", function() ReSort("value"); end);
Zerotorescue@13 348 lblValue:SetCallback("OnEnter", ShowTooltip);
Zerotorescue@13 349 lblValue:SetCallback("OnLeave", HideTooltip);
Zerotorescue@13 350 lblValue.frame.tooltipTitle = "Value";
Zerotorescue@13 351 lblValue.frame.tooltip = "Sort on the item auction value.";
Zerotorescue@1 352
Zerotorescue@1 353 iGroup:AddChild(lblValue);
Zerotorescue@1 354
Zerotorescue@10 355
Zerotorescue@10 356 -- Retrieve items list
Zerotorescue@1 357 if not itemsCache[groupName] then
Zerotorescue@1 358 itemsCache[groupName] = {};
Zerotorescue@0 359
Zerotorescue@1 360 -- Sort item list
Zerotorescue@12 361 for itemId, _ in pairs(values.items) do
Zerotorescue@1 362 local itemName, itemLink, itemRarity = GetItemInfo(itemId);
Zerotorescue@1 363
Zerotorescue@1 364 table.insert(itemsCache[groupName], {
Zerotorescue@1 365 id = itemId,
Zerotorescue@12 366 name = itemName or unknownItemName:format(itemId),
Zerotorescue@23 367 link = itemLink,
Zerotorescue@23 368 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 369 rarity = itemRarity or 1,
Zerotorescue@23 370 count = -3,--addon:GetItemCount(itemId, groupName),
Zerotorescue@1 371 set = {},
Zerotorescue@1 372 });
Zerotorescue@1 373 CACHE_ITEMS_TOTAL = CACHE_ITEMS_TOTAL + 1;
Zerotorescue@1 374 end
Zerotorescue@0 375 end
Zerotorescue@0 376
Zerotorescue@10 377 groupTimes.init = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 378
Zerotorescue@10 379
Zerotorescue@10 380
Zerotorescue@10 381 -- Sort items
Zerotorescue@1 382 table.sort(itemsCache[groupName], function(a, b)
Zerotorescue@1 383 if sortMethod == "item" and a.rarity == b.rarity then
Zerotorescue@1 384 -- Do a name-compare for items of the same rarity
Zerotorescue@1 385 -- Otherwise epics first, then junk
Zerotorescue@0 386 if sortDirectory == "ASC" then
Zerotorescue@1 387 return a.name:upper() < b.name:upper();
Zerotorescue@0 388 else
Zerotorescue@1 389 return a.name:upper() > b.name:upper();
Zerotorescue@1 390 end
Zerotorescue@1 391 elseif sortMethod == "item" then
Zerotorescue@1 392 if sortDirectory == "ASC" then
Zerotorescue@1 393 return a.rarity > b.rarity; -- the comparers were reversed because we want epics first
Zerotorescue@1 394 else
Zerotorescue@1 395 return a.rarity < b.rarity; -- the comparers were reversed because we want epics first
Zerotorescue@0 396 end
Zerotorescue@0 397 elseif sortMethod == "current" then
Zerotorescue@0 398 if sortDirectory == "ASC" then
Zerotorescue@0 399 return a.count < b.count;
Zerotorescue@0 400 else
Zerotorescue@0 401 return a.count > b.count;
Zerotorescue@0 402 end
Zerotorescue@0 403 elseif sortMethod == "percentage" then
Zerotorescue@0 404 if sortDirectory == "ASC" then
Zerotorescue@10 405 return ( a.count / minimumStock ) < ( b.count / minimumStock );
Zerotorescue@0 406 else
Zerotorescue@10 407 return ( a.count / minimumStock ) > ( b.count / minimumStock );
Zerotorescue@0 408 end
Zerotorescue@1 409 elseif sortMethod == "value" then
Zerotorescue@1 410 if sortDirectory == "ASC" then
Zerotorescue@1 411 return a.value < b.value;
Zerotorescue@1 412 else
Zerotorescue@1 413 return a.value > b.value;
Zerotorescue@1 414 end
Zerotorescue@0 415 end
Zerotorescue@0 416 end);
Zerotorescue@0 417
Zerotorescue@10 418 groupTimes.sorting = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 419
Zerotorescue@10 420
Zerotorescue@10 421
Zerotorescue@10 422
Zerotorescue@10 423 -- Show itemslist
Zerotorescue@1 424 for i, item in pairs(itemsCache[groupName]) do
Zerotorescue@27 425 if ( item.count / minimumStock ) < showWhenBelow and not (hideWhenBelowPriceThreshold and item.value < priceThreshold and item.value >= 0) then
Zerotorescue@0 426 local btnItemLink = AceGUI:Create("ItemLinkButton");
Zerotorescue@23 427 btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName)
Zerotorescue@23 428 local itemName, itemLink = GetItemInfo(itemId);
Zerotorescue@23 429
Zerotorescue@23 430 if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then
Zerotorescue@23 431 ChatEdit_InsertLink(itemLink);
Zerotorescue@23 432 elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then
Zerotorescue@23 433 -- Start search at page 0
Zerotorescue@23 434 AuctionFrameBrowse.page = 0;
Zerotorescue@23 435
Zerotorescue@23 436 -- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated)
Zerotorescue@23 437 BrowseName:SetText(itemName)
Zerotorescue@23 438
Zerotorescue@23 439 QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0);
Zerotorescue@23 440 end
Zerotorescue@23 441 end);
Zerotorescue@10 442 btnItemLink:SetRelativeWidth(.7);
Zerotorescue@1 443 btnItemLink:SetItemId(item.id);
Zerotorescue@0 444
Zerotorescue@0 445 iGroup:AddChild(btnItemLink);
Zerotorescue@0 446
Zerotorescue@0 447 -- Current quantity
Zerotorescue@0 448 local lblQuantity = AceGUI:Create("Label");
Zerotorescue@9 449 lblQuantity:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 450 lblQuantity:SetRelativeWidth(.099);
Zerotorescue@0 451
Zerotorescue@0 452 iGroup:AddChild(lblQuantity);
Zerotorescue@0 453
Zerotorescue@0 454 -- Required stock
Zerotorescue@9 455 local lblMinimumStock = AceGUI:Create("Label");
Zerotorescue@9 456 lblMinimumStock:SetText(minimumStock);
Zerotorescue@10 457 lblMinimumStock:SetRelativeWidth(.099);
Zerotorescue@0 458
Zerotorescue@9 459 iGroup:AddChild(lblMinimumStock);
Zerotorescue@1 460
Zerotorescue@1 461 -- Value
Zerotorescue@1 462 local lblValue = AceGUI:Create("Label");
Zerotorescue@1 463 lblValue:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@10 464 lblValue:SetRelativeWidth(.099);
Zerotorescue@1 465
Zerotorescue@1 466 iGroup:AddChild(lblValue);
Zerotorescue@1 467
Zerotorescue@1 468 -- Remember references to the value and current fields so we can fill them later
Zerotorescue@1 469 if item.set then
Zerotorescue@10 470 -- -3 means the price is unknown, queue look up
Zerotorescue@10 471 if item.value == -3 then
Zerotorescue@10 472 item.set.value = lblValue;
Zerotorescue@10 473 end
Zerotorescue@10 474 if item.count == -3 then
Zerotorescue@10 475 item.set.current = lblQuantity;
Zerotorescue@10 476 end
Zerotorescue@10 477
Zerotorescue@10 478 -- Don't queue if we already know everything we want to know
Zerotorescue@10 479 if item.value ~= -3 and item.count ~= -3 then
Zerotorescue@10 480 item.set = nil;
Zerotorescue@10 481 end
Zerotorescue@1 482 end
Zerotorescue@0 483 end
Zerotorescue@0 484 end
Zerotorescue@0 485
Zerotorescue@10 486 groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 487
Zerotorescue@1 488 iGroup:ResumeLayout();
Zerotorescue@1 489 mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time
Zerotorescue@10 490
Zerotorescue@10 491 groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@0 492 end
Zerotorescue@10 493
Zerotorescue@13 494 if groupStartTime and groupTimes then
Zerotorescue@13 495 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 496 end
Zerotorescue@0 497 end
Zerotorescue@1 498
Zerotorescue@1 499 mod.scrollFrame:ResumeLayout();
Zerotorescue@1 500 mod.scrollFrame:DoLayout();
Zerotorescue@1 501
Zerotorescue@10 502 addon:Debug(("Done building summary after %d ms."):format(ceil( ( GetTime() - buildStartTime ) * 1000 )));
Zerotorescue@10 503
Zerotorescue@1 504 if CACHE_ITEMS_TOTAL > 0 then
Zerotorescue@1 505 cacheStart = GetTime();
Zerotorescue@7 506 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@1 507 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 508 end
Zerotorescue@1 509 end
Zerotorescue@1 510
Zerotorescue@1 511 function mod:UpdateNextItem()
Zerotorescue@1 512 local i = 0;
Zerotorescue@1 513
Zerotorescue@1 514 for groupName, items in pairs(itemsCache) do
Zerotorescue@1 515 local minimumStock = addon:GetOptionByKey(groupName, "minimumStock");
Zerotorescue@1 516 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@1 517
Zerotorescue@1 518 for _, item in pairs(items) do
Zerotorescue@1 519 if item.set then
Zerotorescue@10 520 if item.count == -3 then
Zerotorescue@10 521 -- Only if item count was queued, update it
Zerotorescue@23 522 item.count = addon:GetItemCount(item.id, groupName);
Zerotorescue@10 523 if item.set.current and item.set.current.SetText then
Zerotorescue@10 524 item.set.current:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 525 end
Zerotorescue@1 526 end
Zerotorescue@1 527
Zerotorescue@10 528 if item.value == -3 then
Zerotorescue@10 529 -- Only if item value was queued, update it
Zerotorescue@23 530
Zerotorescue@23 531 -- The itemlink might not have been loaded yet in which case we retry
Zerotorescue@23 532 item.link = item.link or select(2, GetItemInfo(item.id));
Zerotorescue@23 533
Zerotorescue@23 534 if item.link then
Zerotorescue@23 535 item.value = addon:GetAuctionValue(item.link, groupName);
Zerotorescue@23 536 if item.set.value and item.set.value.SetText then
Zerotorescue@23 537 item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@23 538 end
Zerotorescue@10 539 end
Zerotorescue@1 540 end
Zerotorescue@1 541
Zerotorescue@1 542 item.set = nil;
Zerotorescue@1 543
Zerotorescue@1 544 i = i + 1;
Zerotorescue@1 545 CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1;
Zerotorescue@1 546
Zerotorescue@9 547 if mod.frame then
Zerotorescue@9 548 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 549 end
Zerotorescue@1 550
Zerotorescue@13 551 if i >= addon.db.global.defaults.summary.speed then
Zerotorescue@1 552 return;
Zerotorescue@1 553 end
Zerotorescue@1 554 end
Zerotorescue@1 555 end
Zerotorescue@1 556 end
Zerotorescue@1 557
Zerotorescue@1 558 -- Reset trackers
Zerotorescue@1 559 CACHE_ITEMS_TOTAL = 0;
Zerotorescue@1 560 CACHE_ITEMS_CURRENT = 0;
Zerotorescue@1 561
Zerotorescue@1 562 -- Stop timer
Zerotorescue@1 563 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@10 564
Zerotorescue@10 565 -- Rebuild list so hidden items due to too low prices get added
Zerotorescue@10 566 self:Build();
Zerotorescue@1 567
Zerotorescue@1 568 -- Announce
Zerotorescue@10 569 mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds.");
Zerotorescue@1 570
Zerotorescue@1 571 -- Forget time
Zerotorescue@1 572 cacheStart = nil;
Zerotorescue@0 573 end
Zerotorescue@0 574
Zerotorescue@0 575 function mod:ColorCode(num, required)
Zerotorescue@0 576 local percentage = ( num / required );
Zerotorescue@0 577
Zerotorescue@0 578 if percentage >= addon.db.global.defaults.colors.green then
Zerotorescue@0 579 return ("|cff00ff00%d|r"):format(num);
Zerotorescue@0 580 elseif percentage >= addon.db.global.defaults.colors.yellow then
Zerotorescue@0 581 return ("|cffffff00%d|r"):format(num);
Zerotorescue@0 582 elseif percentage >= addon.db.global.defaults.colors.orange then
Zerotorescue@0 583 return ("|cffff9933%d|r"):format(num);
Zerotorescue@0 584 elseif percentage >= addon.db.global.defaults.colors.red then
Zerotorescue@0 585 return ("|cffff0000%d|r"):format(num);
Zerotorescue@0 586 end
Zerotorescue@0 587 end
Zerotorescue@0 588
Zerotorescue@1 589 function mod:DisplayMoney(value, priceThreshold)
Zerotorescue@7 590 if value == -1 then
Zerotorescue@7 591 return "|cff0000ffNone up|r";
Zerotorescue@7 592 elseif value == -2 then
Zerotorescue@7 593 return "|cff0000ffNo AH mod|r";
Zerotorescue@9 594 elseif value == -3 then
Zerotorescue@9 595 return "|cffffff00Unknown|r";
Zerotorescue@13 596 elseif value == -4 then
Zerotorescue@13 597 return "|cff00ff00-|r";
Zerotorescue@23 598 elseif value == -5 then
Zerotorescue@23 599 return "|cffff9933Error|r";
Zerotorescue@23 600 elseif priceThreshold and value < priceThreshold then
Zerotorescue@17 601 return ("|cffaaaaaa%s|r"):format(addon:ReadableMoney(value or 0, true):gsub("|([a-fA-F0-9]+)([gsc]+)|r", "%2"));
Zerotorescue@1 602 else
Zerotorescue@1 603 return addon:ReadableMoney(value or 0, true);
Zerotorescue@1 604 end
Zerotorescue@1 605 end
Zerotorescue@1 606
Zerotorescue@9 607 function mod:DisplayItemCount(value, minimumStock)
Zerotorescue@13 608 if value == -1 then
Zerotorescue@13 609 return "|cffffff00Unknown|r";
Zerotorescue@13 610 elseif value == -3 then
Zerotorescue@9 611 return "|cffffff00Unknown|r";
Zerotorescue@9 612 else
Zerotorescue@9 613 return self:ColorCode(value, minimumStock);
Zerotorescue@9 614 end
Zerotorescue@9 615 end
Zerotorescue@9 616
Zerotorescue@0 617 function mod:NumberFormat(num)
Zerotorescue@0 618 local formatted = string.gsub(num, "(%d)(%d%d%d)$", "%1,%2", 1);
Zerotorescue@0 619
Zerotorescue@0 620 while true do
Zerotorescue@0 621 formatted, matches = string.gsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1);
Zerotorescue@0 622
Zerotorescue@0 623 if matches == 0 then
Zerotorescue@0 624 break;
Zerotorescue@0 625 end
Zerotorescue@0 626 end
Zerotorescue@0 627
Zerotorescue@0 628 return formatted;
Zerotorescue@1 629 end