annotate Summary.lua @ 31:e732843b16d2 v0.1.6-BETA

Added an info box to the top of the general group. Removed the ?Don't queue when below threshold?, this is now default (can?t make it too complicated). Implemented working functionality for virtual groups. ?Include in local item data? can now be overridden in every group. Added help text at the replenishing stock indicating how auction values are used when queueing. The tabs ?add items? and ?current items? will now be hidden rather than disabled when you have a virtual group selected. The auction value/price threshold for items will now be used when queueing items.
author Zerotorescue
date Sat, 30 Oct 2010 23:04:45 +0200
parents 95c813292a88
children 58fb38f0b447
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@31 425 -- Go through all items for this group
Zerotorescue@31 426
Zerotorescue@31 427 if ( item.count / minimumStock ) < showWhenBelow and (not hideWhenBelowPriceThreshold or priceThreshold == 0 or item.value < 0 or item.value >= priceThreshold) then
Zerotorescue@31 428 -- 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@0 429 local btnItemLink = AceGUI:Create("ItemLinkButton");
Zerotorescue@23 430 btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName)
Zerotorescue@23 431 local itemName, itemLink = GetItemInfo(itemId);
Zerotorescue@23 432
Zerotorescue@23 433 if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then
Zerotorescue@23 434 ChatEdit_InsertLink(itemLink);
Zerotorescue@23 435 elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then
Zerotorescue@23 436 -- Start search at page 0
Zerotorescue@23 437 AuctionFrameBrowse.page = 0;
Zerotorescue@23 438
Zerotorescue@23 439 -- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated)
Zerotorescue@23 440 BrowseName:SetText(itemName)
Zerotorescue@23 441
Zerotorescue@23 442 QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0);
Zerotorescue@23 443 end
Zerotorescue@23 444 end);
Zerotorescue@10 445 btnItemLink:SetRelativeWidth(.7);
Zerotorescue@1 446 btnItemLink:SetItemId(item.id);
Zerotorescue@0 447
Zerotorescue@0 448 iGroup:AddChild(btnItemLink);
Zerotorescue@0 449
Zerotorescue@0 450 -- Current quantity
Zerotorescue@0 451 local lblQuantity = AceGUI:Create("Label");
Zerotorescue@9 452 lblQuantity:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 453 lblQuantity:SetRelativeWidth(.099);
Zerotorescue@0 454
Zerotorescue@0 455 iGroup:AddChild(lblQuantity);
Zerotorescue@0 456
Zerotorescue@0 457 -- Required stock
Zerotorescue@9 458 local lblMinimumStock = AceGUI:Create("Label");
Zerotorescue@9 459 lblMinimumStock:SetText(minimumStock);
Zerotorescue@10 460 lblMinimumStock:SetRelativeWidth(.099);
Zerotorescue@0 461
Zerotorescue@9 462 iGroup:AddChild(lblMinimumStock);
Zerotorescue@1 463
Zerotorescue@1 464 -- Value
Zerotorescue@1 465 local lblValue = AceGUI:Create("Label");
Zerotorescue@1 466 lblValue:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@10 467 lblValue:SetRelativeWidth(.099);
Zerotorescue@1 468
Zerotorescue@1 469 iGroup:AddChild(lblValue);
Zerotorescue@1 470
Zerotorescue@1 471 -- Remember references to the value and current fields so we can fill them later
Zerotorescue@1 472 if item.set then
Zerotorescue@10 473 -- -3 means the price is unknown, queue look up
Zerotorescue@10 474 if item.value == -3 then
Zerotorescue@10 475 item.set.value = lblValue;
Zerotorescue@10 476 end
Zerotorescue@10 477 if item.count == -3 then
Zerotorescue@10 478 item.set.current = lblQuantity;
Zerotorescue@10 479 end
Zerotorescue@10 480
Zerotorescue@10 481 -- Don't queue if we already know everything we want to know
Zerotorescue@10 482 if item.value ~= -3 and item.count ~= -3 then
Zerotorescue@10 483 item.set = nil;
Zerotorescue@10 484 end
Zerotorescue@1 485 end
Zerotorescue@0 486 end
Zerotorescue@0 487 end
Zerotorescue@0 488
Zerotorescue@10 489 groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@10 490
Zerotorescue@1 491 iGroup:ResumeLayout();
Zerotorescue@1 492 mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time
Zerotorescue@10 493
Zerotorescue@10 494 groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 );
Zerotorescue@0 495 end
Zerotorescue@10 496
Zerotorescue@13 497 if groupStartTime and groupTimes then
Zerotorescue@13 498 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 499 end
Zerotorescue@0 500 end
Zerotorescue@1 501
Zerotorescue@1 502 mod.scrollFrame:ResumeLayout();
Zerotorescue@1 503 mod.scrollFrame:DoLayout();
Zerotorescue@1 504
Zerotorescue@10 505 addon:Debug(("Done building summary after %d ms."):format(ceil( ( GetTime() - buildStartTime ) * 1000 )));
Zerotorescue@10 506
Zerotorescue@1 507 if CACHE_ITEMS_TOTAL > 0 then
Zerotorescue@1 508 cacheStart = GetTime();
Zerotorescue@7 509 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@1 510 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 511 end
Zerotorescue@1 512 end
Zerotorescue@1 513
Zerotorescue@1 514 function mod:UpdateNextItem()
Zerotorescue@1 515 local i = 0;
Zerotorescue@1 516
Zerotorescue@1 517 for groupName, items in pairs(itemsCache) do
Zerotorescue@1 518 local minimumStock = addon:GetOptionByKey(groupName, "minimumStock");
Zerotorescue@1 519 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@1 520
Zerotorescue@1 521 for _, item in pairs(items) do
Zerotorescue@1 522 if item.set then
Zerotorescue@10 523 if item.count == -3 then
Zerotorescue@10 524 -- Only if item count was queued, update it
Zerotorescue@23 525 item.count = addon:GetItemCount(item.id, groupName);
Zerotorescue@10 526 if item.set.current and item.set.current.SetText then
Zerotorescue@10 527 item.set.current:SetText(self:DisplayItemCount(item.count, minimumStock));
Zerotorescue@10 528 end
Zerotorescue@1 529 end
Zerotorescue@1 530
Zerotorescue@10 531 if item.value == -3 then
Zerotorescue@10 532 -- Only if item value was queued, update it
Zerotorescue@23 533
Zerotorescue@23 534 -- The itemlink might not have been loaded yet in which case we retry
Zerotorescue@23 535 item.link = item.link or select(2, GetItemInfo(item.id));
Zerotorescue@23 536
Zerotorescue@23 537 if item.link then
Zerotorescue@23 538 item.value = addon:GetAuctionValue(item.link, groupName);
Zerotorescue@23 539 if item.set.value and item.set.value.SetText then
Zerotorescue@23 540 item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold));
Zerotorescue@23 541 end
Zerotorescue@10 542 end
Zerotorescue@1 543 end
Zerotorescue@1 544
Zerotorescue@1 545 item.set = nil;
Zerotorescue@1 546
Zerotorescue@1 547 i = i + 1;
Zerotorescue@1 548 CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1;
Zerotorescue@1 549
Zerotorescue@9 550 if mod.frame then
Zerotorescue@9 551 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 552 end
Zerotorescue@1 553
Zerotorescue@13 554 if i >= addon.db.global.defaults.summary.speed then
Zerotorescue@1 555 return;
Zerotorescue@1 556 end
Zerotorescue@1 557 end
Zerotorescue@1 558 end
Zerotorescue@1 559 end
Zerotorescue@1 560
Zerotorescue@1 561 -- Reset trackers
Zerotorescue@1 562 CACHE_ITEMS_TOTAL = 0;
Zerotorescue@1 563 CACHE_ITEMS_CURRENT = 0;
Zerotorescue@1 564
Zerotorescue@1 565 -- Stop timer
Zerotorescue@1 566 self:CancelTimer(self.tmrUpdater, true);
Zerotorescue@10 567
Zerotorescue@10 568 -- Rebuild list so hidden items due to too low prices get added
Zerotorescue@10 569 self:Build();
Zerotorescue@1 570
Zerotorescue@1 571 -- Announce
Zerotorescue@10 572 mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds.");
Zerotorescue@1 573
Zerotorescue@1 574 -- Forget time
Zerotorescue@1 575 cacheStart = nil;
Zerotorescue@0 576 end
Zerotorescue@0 577
Zerotorescue@0 578 function mod:ColorCode(num, required)
Zerotorescue@0 579 local percentage = ( num / required );
Zerotorescue@0 580
Zerotorescue@0 581 if percentage >= addon.db.global.defaults.colors.green then
Zerotorescue@0 582 return ("|cff00ff00%d|r"):format(num);
Zerotorescue@0 583 elseif percentage >= addon.db.global.defaults.colors.yellow then
Zerotorescue@0 584 return ("|cffffff00%d|r"):format(num);
Zerotorescue@0 585 elseif percentage >= addon.db.global.defaults.colors.orange then
Zerotorescue@0 586 return ("|cffff9933%d|r"):format(num);
Zerotorescue@0 587 elseif percentage >= addon.db.global.defaults.colors.red then
Zerotorescue@0 588 return ("|cffff0000%d|r"):format(num);
Zerotorescue@0 589 end
Zerotorescue@0 590 end
Zerotorescue@0 591
Zerotorescue@1 592 function mod:DisplayMoney(value, priceThreshold)
Zerotorescue@7 593 if value == -1 then
Zerotorescue@7 594 return "|cff0000ffNone up|r";
Zerotorescue@7 595 elseif value == -2 then
Zerotorescue@7 596 return "|cff0000ffNo AH mod|r";
Zerotorescue@9 597 elseif value == -3 then
Zerotorescue@9 598 return "|cffffff00Unknown|r";
Zerotorescue@13 599 elseif value == -4 then
Zerotorescue@13 600 return "|cff00ff00-|r";
Zerotorescue@23 601 elseif value == -5 then
Zerotorescue@23 602 return "|cffff9933Error|r";
Zerotorescue@23 603 elseif priceThreshold and value < priceThreshold then
Zerotorescue@17 604 return ("|cffaaaaaa%s|r"):format(addon:ReadableMoney(value or 0, true):gsub("|([a-fA-F0-9]+)([gsc]+)|r", "%2"));
Zerotorescue@1 605 else
Zerotorescue@1 606 return addon:ReadableMoney(value or 0, true);
Zerotorescue@1 607 end
Zerotorescue@1 608 end
Zerotorescue@1 609
Zerotorescue@9 610 function mod:DisplayItemCount(value, minimumStock)
Zerotorescue@13 611 if value == -1 then
Zerotorescue@13 612 return "|cffffff00Unknown|r";
Zerotorescue@13 613 elseif value == -3 then
Zerotorescue@9 614 return "|cffffff00Unknown|r";
Zerotorescue@9 615 else
Zerotorescue@9 616 return self:ColorCode(value, minimumStock);
Zerotorescue@9 617 end
Zerotorescue@9 618 end
Zerotorescue@9 619
Zerotorescue@0 620 function mod:NumberFormat(num)
Zerotorescue@0 621 local formatted = string.gsub(num, "(%d)(%d%d%d)$", "%1,%2", 1);
Zerotorescue@0 622
Zerotorescue@0 623 while true do
Zerotorescue@0 624 formatted, matches = string.gsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1);
Zerotorescue@0 625
Zerotorescue@0 626 if matches == 0 then
Zerotorescue@0 627 break;
Zerotorescue@0 628 end
Zerotorescue@0 629 end
Zerotorescue@0 630
Zerotorescue@0 631 return formatted;
Zerotorescue@1 632 end