comparison Core.lua @ 1:9fff13c08f99

Initial release, config and summary windows mostly working. Base functionality available.
author Zerotorescue
date Fri, 08 Oct 2010 16:11:59 +0200
parents c6ff7ba0e8f6
children 1a815139e4c3
comparison
equal deleted inserted replaced
0:c6ff7ba0e8f6 1:9fff13c08f99
1 -- You can access this addon's object through: LibStub("AceAddon-3.0"):GetAddon("Inventory") 1 -- You can access this addon's object through: LibStub("AceAddon-3.0"):GetAddon("Inventory")
2 local addon = LibStub("AceAddon-3.0"):NewAddon("Inventory", "AceEvent-3.0", "AceTimer-3.0"); 2 local addon = LibStub("AceAddon-3.0"):NewAddon("Inventory", "AceEvent-3.0");
3
4 local AceGUI = LibStub("AceGUI-3.0");
3 5
4 local Media = LibStub("LibSharedMedia-3.0"); 6 local Media = LibStub("LibSharedMedia-3.0");
5 Media:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]]); 7 Media:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]]);
6 Media:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]]); 8 Media:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]]);
7 Media:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]]); 9 Media:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]]);
36 summaryThresholdShow = 10, 38 summaryThresholdShow = 10,
37 restockTarget = 60, 39 restockTarget = 60,
38 minCraftingQueue = 0.05, 40 minCraftingQueue = 0.05,
39 bonusQueue = 0.1, 41 bonusQueue = 0.1,
40 priceThreshold = 0, 42 priceThreshold = 0,
43 hideFromSummaryWhenBelowPriceThreshold = false,
41 trackAtCharacters = {}, 44 trackAtCharacters = {},
42 colors = { 45 colors = {
43 red = 0; 46 red = 0;
44 orange = 0.3; 47 orange = 0.3;
45 yellow = 0.6; 48 yellow = 0.6;
84 InterfaceOptionsFrame_OpenToCategory(self.name) 87 InterfaceOptionsFrame_OpenToCategory(self.name)
85 end); 88 end);
86 -- And add it to the interface options 89 -- And add it to the interface options
87 InterfaceOptions_AddCategory(frame); 90 InterfaceOptions_AddCategory(frame);
88 91
89 self:MakeWidgets(); 92 self:MakeItemLinkButtonWidget();
93 self:MakeConfigItemLinkButtonWidget();
90 94
91 -- Remember this character is mine 95 -- Remember this character is mine
92 local playerName = UnitName("player"); 96 local playerName = UnitName("player");
93 if not self.db.factionrealm.characters[playerName] then 97 if not self.db.factionrealm.characters[playerName] then
94 self.db.factionrealm.characters[playerName] = true; 98 self.db.factionrealm.characters[playerName] = true;
96 -- Default to tracking on all chars, untracking is a convenience, not tracking by default would probably get multiple issue reports. 100 -- Default to tracking on all chars, untracking is a convenience, not tracking by default would probably get multiple issue reports.
97 self.db.global.defaults.trackAtCharacters[playerName] = true; 101 self.db.global.defaults.trackAtCharacters[playerName] = true;
98 end 102 end
99 end 103 end
100 104
101 function addon:MakeWidgets() 105 local slashArgs = {};
102 local AceGUI = LibStub("AceGUI-3.0"); 106 function addon:RegisterSlash(func, ...)
103 107 for _, arg in pairs({ ... }) do
108 slashArgs[arg] = func;
109 end
110 end
111
112 function addon:MakeItemLinkButtonWidget()
104 --[[ 113 --[[
105 [ ItemLinkButton ] 114 [ ItemLinkButton ]
106 UserData: itemId, onClick event 115 This custom widget has to show an icon with the item link next to it.
116 Upon hover it must show the item tooltip.
117 Upon click it must execute the function provided through user data.
118
119 UserData: itemId, onClickEvent
120
107 OnEnter: tooltip show 121 OnEnter: tooltip show
108 OnLeave: tooltip hid 122 OnLeave: tooltip hide
109 123 OnClick: UserData.onClickEvent
110 ]] 124 ]]
111
112 -- Define out custom item link button widget
113 -- This will be called as if it's an input element, we overwrite some of the related functions which are called for default input fields
114 125
115 local widgetType = "ItemLinkButton"; 126 local widgetType = "ItemLinkButton";
116 local widgetVersion = 1; 127 local widgetVersion = 1;
117 128
118 -- Empty function for disabling functions 129 local function Constructor()
119 local function Dummy() end 130 local widget = AceGUI:Create("InteractiveLabel");
120 131 widget.type = widgetType;
121 -- Overwrite the SetText-function of our custom widgets 132
122 local function CustomWidgetSetText(self, value, ...) 133 -- We overwrite the OnAcquire as we want to set our callbacks even
123 if value then 134 -- when the widget is re-used from the widget pool
124 -- Remember the itemId in a local parameter (using :GetText, we'd have to run a pattern over it and it would all get silly) 135 widget.originalOnAcquire = widget.OnAcquire;
125 self.itemId = tonumber(value); 136 widget.OnAcquire = function(self, ...)
126 137
127 if not self.itemId then error("itemId is not a number."); end 138
128 139 -- We overwrite the setcallback because we don't want anything else
129 -- Put the icon in front of it 140 -- to overwrite our OnEnter, OnLeave and OnClick events
130 self:SetImage(GetItemIcon(self.itemId)); 141 -- which would be done by the AceConfigDialog after a widget gets re-used
142 if not self.originalSetCallBack then
143 self.originalSetCallBack = self.SetCallback;
144 self.SetCallback = function(this, event, func, ...)
145 if event == "OnEnter" or event == "OnLeave" or event == "OnClick" then
146 -- Don't allow overwriting of these events
147 return;
148 elseif event == "CustomOnEnter" then
149 return this.originalSetCallBack(this, "OnEnter", func, ...);
150 elseif event == "CustomOnLeave" then
151 return this.originalSetCallBack(this, "OnLeave", func, ...);
152 elseif event == "CustomOnClick" then
153 return this.originalSetCallBack(this, "OnClick", func, ...);
154 else
155 return this.originalSetCallBack(this, event, func, ...);
156 end
157 end;
158 end
159
160
161 -- Set our own events, since we disabled the normal event-names, we'll call them our custom versions
162 self:SetCallback("CustomOnEnter", function(this)
163 local itemId = this:GetUserData("itemId");
164
165 if itemId then
166 GameTooltip:SetOwner(this.frame, "ANCHOR_TOPRIGHT");
167 GameTooltip:SetHyperlink(("item:%d"):format(itemId));
168 GameTooltip:Show();
169 end
170 end);
171 self:SetCallback("CustomOnLeave", function(this)
172 GameTooltip:Hide();
173 end);
174 self:SetCallback("CustomOnClick", function(this)
175 if this.OnClick then
176 this.OnClick(this);
177 end
178
179 local func = this:GetUserData("exec");
180 local itemId = this:GetUserData("itemId");
181
182 if func then
183 -- If this is a config option we will need the group id
184 local path = this:GetUserData("path");
185 local groupId = (path and path[2]) or nil;
186
187 func(groupId, itemId);
188 end
189 end);
190
191
192
193 -- Then also do whatever it wanted to do
194 self.originalOnAcquire(self, ...);
195 end;
196
197 -- Remember the original SetText as this might get overwritten by the config-widget
198 widget.originalSetText = widget.SetText;
199
200 widget.SetItemId = function(self, itemId)
201 self:SetUserData("itemId", itemId);
202
203 -- Put the icon in front of it
204 self:SetImage(GetItemIcon(itemId));
131 -- Standardize the size 205 -- Standardize the size
132 self:SetImageSize(16, 16); 206 self:SetImageSize(16, 16);
133 207
134 -- Make readable font 208 -- Make readable font
135 self:SetFontObject(GameFontHighlight); 209 self:SetFontObject(GameFontHighlight);
136 210
137 -- We don't want to set the itemId as text, but rather the item link, so get that. 211 -- We don't want to set the itemId as text, but rather the item link, so get that.
138 value = select(2, GetItemInfo(value)) or ("Unknown (#%d)"):format(value); 212 local itemLink = select(2, GetItemInfo(itemId)) or ("Unknown (#%d)"):format(itemId);
139 213
140 return self.originalSetText(self, value, ...); 214 self:originalSetText(itemLink);
141 end 215 end;
142 end 216
143 217 return widget;
144 -- Overwrite the OnEnter-event of our custom widgets to use our own function 218 end
145 local function CustomWidgetOnEnter(self)
146 if self.itemId then
147 GameTooltip:SetOwner(self.frame, "ANCHOR_TOPRIGHT");
148 GameTooltip:SetHyperlink(("item:%d"):format(self.itemId));
149 GameTooltip:Show();
150 end
151 end
152
153 -- Overwrite the OnClick-event of our custom widgets to use our own function
154 local function CustomWidgetOnClick(self)
155 local info = self:GetUserDataTable()
156
157 info.option.set(self, info);
158 end
159 219
160 -- Overwrite the SetCallback-function of our custom widgets 220 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion);
161 local function CustomWidgetSetCallback(self, event, func, ...) 221 end
162 if event == "OnEnter" then 222
163 -- This event is called once when creating the widget 223 function addon:MakeConfigItemLinkButtonWidget()
164 -- When it becomes hidden, all events appear to be removed, but once it's shown again, OnEnter will be re-applied 224 -- Define out custom item link button widget
165 -- Hence any registered Callback must be done in here 225 -- This will be called as if it's an input element, we overwrite some of the related functions which are called for default input fields
166 226
167 self.originalSetCallBack(self, "OnClick", CustomWidgetOnClick); 227 local widgetType = "ConfigItemLinkButton";
168 228 local widgetVersion = 1;
169 return self.originalSetCallBack(self, event, CustomWidgetOnEnter, ...); 229
170 else 230 -- Empty function for disabling functions
171 return self.originalSetCallBack(self, event, func, ...); 231 local function Dummy() end
172 end
173 end
174
175 local function CustomWidgetHideTooltip()
176 GameTooltip:Hide();
177 end
178 232
179 -- Makes an instance of our ItemLinkButton widget 233 -- Makes an instance of our ItemLinkButton widget
180 local function GetItemLinkButton() 234 local function GetItemLinkButton()
181 local widget = AceGUI:Create("InteractiveLabel"); 235 local widget = AceGUI:Create("ItemLinkButton");
182 widget.type = widgetType; 236 widget.type = widgetType;
183 237
184 -- We can only provide custom widgets for input, select and multiselect fields 238 -- We can only provide custom widgets for input, select and multiselect fields
185 -- Input being the simplest, we use that - however, it provides two parameters: label and text. We only need one, disable the other. 239 -- Input being the simplest, we use that - however, it provides two parameters: label and text. We only need one, disable the other.
186 widget.SetLabel = Dummy; 240 widget.SetLabel = Dummy;
187 241
188 if not widget.originalSetText then 242 -- SetText is called when this button is being created and contains the itemId
189 -- When setting text we provide an itemId 243 -- Forward that itemId to the ItemLinkButton
190 -- Use this itemId to set the icon and do all fancy stuff 244 widget.SetText = function(self, value, ...)
191 widget.originalSetText = widget.SetText; 245 if value and tonumber(value) then
192 widget.SetText = CustomWidgetSetText; 246 self:SetItemId(tonumber(value));
193 end 247 end
194 248 end;
195 249
196 if not widget.originalSetCallBack then 250 widget.OnClick = function(self, ...)
197 -- We don't want AceConfig to overwrite our OnEnter with the tooltip functions, so override that 251 local option = self:GetUserData("option");
198 widget.originalSetCallBack = widget.SetCallback; 252
199 widget.SetCallback = CustomWidgetSetCallback; 253 if option and option.set then
200 254 self:SetUserData("exec", option.set);
201 -- Make sure it's called (AceConfig will probably repeat this, but we are prepared in case it's ever changed) 255 end
202 widget:SetCallback("OnEnter", Dummy); 256 end;
203 widget:SetCallback("OnLeave", CustomWidgetHideTooltip);
204 end
205 257
206 return widget; 258 return widget;
207 end 259 end
208 260
209 AceGUI:RegisterWidgetType(widgetType, GetItemLinkButton, widgetVersion); 261 AceGUI:RegisterWidgetType(widgetType, GetItemLinkButton, widgetVersion);
234 ChatFrame_RemoveAllMessageGroups(chatFrame); 286 ChatFrame_RemoveAllMessageGroups(chatFrame);
235 self.debugChannel = chatFrame; 287 self.debugChannel = chatFrame;
236 288
237 print("New debug channel created."); 289 print("New debug channel created.");
238 end 290 end
291 elseif slashArgs[cmd] then
292 slashArgs[cmd]();
239 else 293 else
240 print("Wrong command, available: /inventory config (or /inventory c)"); 294 print("Wrong command, available: /inventory config (or /inventory c)");
241 end 295 end
242 end 296 end
243 297
284 options.args.profiles.order = 200; 338 options.args.profiles.order = 200;
285 339
286 self:MakeGroupOptions(); 340 self:MakeGroupOptions();
287 341
288 self:FillGroupOptions(); 342 self:FillGroupOptions();
343 end
344
345 local goldText = "%s%d|cffffd700g|r ";
346 local silverText = "%s%d|cffc7c7cfs|r ";
347 local copperText = "%s%d|cffeda55fc|r";
348
349 function addon:ReadableMoney(copper, clean)
350 local text = "";
351
352 local gold = floor( copper / COPPER_PER_GOLD );
353 if gold > 0 then
354 text = goldText:format(text, gold);
355 end
356
357 if not clean or (not gold or gold < 100) then
358 local silver = floor( ( copper % COPPER_PER_GOLD ) / COPPER_PER_SILVER );
359 if silver > 0 then
360 text = silverText:format(text, silver);
361 end
362
363 if not clean or (not gold or gold < 10) then
364 local copper = floor( copper % COPPER_PER_SILVER );
365 if copper > 0 or text == "" then
366 text = copperText:format(text, copper);
367 end
368 end
369 end
370
371
372 return string.trim(text);
373 end
374
375 function addon:ReadableMoneyToCopper(value)
376 -- If a player enters a value it will be filled without color codes
377 -- If it is retrieved from the database, it will be colored coded
378 -- Thus we look for both
379 local gold = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+g|r") or string.match(value, "(%d+)g"));
380 local silver = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+s|r") or string.match(value, "(%d+)s"));
381 local copper = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+c|r") or string.match(value, "(%d+)c"));
382
383 return ( (gold or 0) * COPPER_PER_GOLD ) + ( (silver or 0) * COPPER_PER_SILVER ) + (copper or 0);
384 end
385
386 function addon:ValidateReadableMoney(info, value)
387 -- If a player enters a value it will be filled without color codes
388 -- If it is retrieved from the database, it will be colored coded
389 -- Thus we look for both
390 local gold = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+g|r") or string.match(value, "(%d+)g"));
391 local silver = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+s|r") or string.match(value, "(%d+)s"));
392 local copper = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+c|r") or string.match(value, "(%d+)c"));
393
394 if not gold and not silver and not copper then
395 return "The provided amount of money is invalid. Please provide the amount of money as #g#s#c, e.g. 591617g24s43c.";
396 else
397 return true;
398 end
289 end 399 end
290 400
291 function addon:FillGeneralOptions() 401 function addon:FillGeneralOptions()
292 options.args.general = { 402 options.args.general = {
293 order = 100, 403 order = 100,
386 set = function(i, v) self.db.global.defaults.alertBelowMinimum = v; end, 496 set = function(i, v) self.db.global.defaults.alertBelowMinimum = v; end,
387 }, 497 },
388 trackAtCharacters = { 498 trackAtCharacters = {
389 order = 40, 499 order = 40,
390 type = "multiselect", 500 type = "multiselect",
391 control = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead.
392 name = "Track at", 501 name = "Track at",
393 desc = "Select at which characters this should appear in the summary and generate alerts.", 502 desc = "Select at which characters this should appear in the summary and generate alerts.",
394 values = function() 503 values = function()
395 local temp = {}; 504 local temp = {};
396 for charName in pairs(self.db.factionrealm.characters) do 505 for charName in pairs(self.db.factionrealm.characters) do
397 temp[charName] = charName; 506 temp[charName] = charName;
398 end 507 end
399 508
400 return temp; 509 return temp;
401 end, 510 end,
402 get = function(i, v) 511 get = function(i, v) return self.db.global.defaults.trackAtCharacters[v]; end,
403 return self.db.global.defaults.trackAtCharacters[v];
404 end,
405 set = function(i, v, e) 512 set = function(i, v, e)
406 self.db.global.defaults.trackAtCharacters[v] = e or nil; 513 self.db.global.defaults.trackAtCharacters[v] = e or nil;
514
515 -- We MUST close this pullout or we can get errors or even game client crashes once we click another group or close the config dialog!
516 local count = AceGUI:GetNextWidgetNum("Dropdown-Pullout");
517 for i = 0, count do
518 if _G['AceGUI30Pullout' .. i] then
519 _G['AceGUI30Pullout' .. i]:Hide();
520 end
521 end
407 end, 522 end,
523 dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead.
408 }, 524 },
409 }, 525 },
410 }, 526 },
411 refill = { 527 refill = {
412 order = 20, 528 order = 20,
460 min = 0, 576 min = 0,
461 max = 10, -- 1000% 577 max = 10, -- 1000%
462 step = 0.01, -- 1% 578 step = 0.01, -- 1%
463 isPercent = true, 579 isPercent = true,
464 name = "Bonus queue", 580 name = "Bonus queue",
465 desc = "Get additional items when I have none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left.", 581 desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.",
466 get = function() return self.db.global.defaults.bonusQueue; end, 582 get = function() return self.db.global.defaults.bonusQueue; end,
467 set = function(i, v) self.db.global.defaults.bonusQueue = v; end, 583 set = function(i, v) self.db.global.defaults.bonusQueue = v; end,
468 }, 584 },
469 priceThreshold = { 585 priceThreshold = {
470 order = 40, 586 order = 40,
471 type = "input", 587 type = "input",
472 name = "Price threshold", 588 name = "Price threshold",
473 desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.", 589 desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.",
474 validate = function() 590 validate = function(info, value) return self:ValidateReadableMoney(info, value); end,
475 -- gold check 591 get = function() return self:ReadableMoney(self.db.global.defaults.priceThreshold); end,
476 end, 592 set = function(i, v) self.db.global.defaults.priceThreshold = self:ReadableMoneyToCopper(v); end,
477 get = function() return self.db.global.defaults.priceThreshold; end, 593 },
478 set = function(i, v) self.db.global.defaults.priceThreshold = v; end, 594 hideFromSummaryWhenBelowPriceThreshold = { -- I wish this var could be a little bit shorter...
479 },
480 hideFromSummaryPriceThreshold = {
481 order = 50, 595 order = 50,
482 type = "toggle", 596 type = "toggle",
483 name = "Don't show when below threshold", 597 name = "Hide when below threshold",
484 desc = "Hide items from the summary when their value is below the set price threshold.", 598 desc = "Hide items from the summary when their value is below the set price threshold.",
599 get = function() return self.db.global.defaults.hideFromSummaryWhenBelowPriceThreshold; end,
600 set = function(i, v) self.db.global.defaults.hideFromSummaryWhenBelowPriceThreshold = v; end,
485 }, 601 },
486 }, 602 },
487 }, 603 },
488 colorCodes = { 604 colorCodes = {
489 order = 30, 605 order = 30,
556 end 672 end
557 673
558 local count = 0; 674 local count = 0;
559 local temp = {}; 675 local temp = {};
560 676
561 local function SetOption(info, value) 677 local function SetOption(info, value, multiSelectEnabled)
562 local groupName = groupIdToName[info[2]]; 678 local groupName = groupIdToName[info[2]];
563 local optionName = info[#info]; 679 local optionName = info[#info];
564 680
565 -- No need to store a setting if it's disabled (false) 681 -- No need to store a setting if it's disabled (false)
566 if not value and info.arg and not info.arg:find("override") then 682 if not value and info.arg and not info.arg:find("override") then
568 684
569 -- If this is an override toggler then also set the related field to nil 685 -- If this is an override toggler then also set the related field to nil
570 addon.db.global.groups[groupName][info.arg] = nil; 686 addon.db.global.groups[groupName][info.arg] = nil;
571 end 687 end
572 688
573 addon.db.global.groups[groupName][optionName] = value; 689 if multiSelectEnabled ~= nil then
574 end 690 -- The saved vars for a multiselect will always be an array, it may not yet exist in which case it must be created.
575 691 if not addon.db.global.groups[groupName][optionName] then
576 local function GetOptionByKey(groupName, optionName, noDefault) 692 addon.db.global.groups[groupName][optionName] = {};
693 end
694
695 addon.db.global.groups[groupName][optionName][value] = multiSelectEnabled or nil;
696 else
697 addon.db.global.groups[groupName][optionName] = value;
698 end
699 end
700
701 function addon:GetOptionByKey(groupName, optionName, noDefault)
577 if addon.db.global.groups[groupName][optionName] ~= nil then 702 if addon.db.global.groups[groupName][optionName] ~= nil then
578 return addon.db.global.groups[groupName][optionName]; 703 return addon.db.global.groups[groupName][optionName];
579 elseif addon.db.global.defaults[optionName] and not noDefault then 704 elseif addon.db.global.defaults[optionName] and not noDefault then
580 return addon.db.global.defaults[optionName]; 705 return addon.db.global.defaults[optionName];
581 else 706 else
585 710
586 local function GetOption(info) 711 local function GetOption(info)
587 local groupName = groupIdToName[info[2]]; 712 local groupName = groupIdToName[info[2]];
588 local optionName = info[#info]; 713 local optionName = info[#info];
589 714
590 return GetOptionByKey(groupName, optionName); 715 return addon:GetOptionByKey(groupName, optionName);
716 end
717
718 local function GetMultiOption(info, value)
719 local groupName = groupIdToName[info[2]];
720 local optionName = info[#info];
721
722 if addon.db.global.groups[groupName][optionName] ~= nil then
723 return addon.db.global.groups[groupName][optionName][value];
724 elseif addon.db.global.defaults[optionName] then
725 return addon.db.global.defaults[optionName][value];
726 else
727 return nil;
728 end
591 end 729 end
592 730
593 local function GetDisabled(info) 731 local function GetDisabled(info)
594 if not info.arg or not info.arg:find("override") then 732 if not info.arg or not info.arg:find("override") then
595 return false; 733 return false;
596 end 734 end
597 735
598 local groupName = groupIdToName[info[2]]; 736 local groupName = groupIdToName[info[2]];
599 local optionName = info[#info]; 737 local optionName = info[#info];
600 738
601 return (GetOptionByKey(groupName, info.arg, true) == nil); 739 return (addon:GetOptionByKey(groupName, info.arg, true) == nil);
602 end 740 end
603 741
604 local function ValidateGroupName(_, value) 742 local function ValidateGroupName(_, value)
605 value = string.lower(string.trim(value or "")); 743 value = string.lower(string.trim(value or ""));
606 744
650 return tostring( 7 - (itemRarity or 0) ) .. (itemName or ""); 788 return tostring( 7 - (itemRarity or 0) ) .. (itemName or "");
651 end, 789 end,
652 get = function(info) 790 get = function(info)
653 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side 791 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side
654 end, 792 end,
655 set = function(widget, info) 793 set = function(groupId, itemId)
656 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info. 794 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info.
657 795
658 if widget.itemId then 796 if itemId then
659 local groupName = groupIdToName[info[2]]; 797 local groupName = groupIdToName[groupId];
660 798
661 if not AddToGroup(groupName, widget.itemId) then 799 if not AddToGroup(groupName, itemId) then
662 print("|cffff0000Couldn't add the item with itemId (" .. widget.itemId .. ") because it is already in a group.|r"); 800 print("|cffff0000Couldn't add the item with itemId (" .. itemId .. ") because it is already in a group.|r");
663 end 801 end
664 end 802 end
665 end, 803 end,
666 width = "double", 804 width = "double",
667 dialogControl = "ItemLinkButton", 805 dialogControl = "ConfigItemLinkButton",
668 }; 806 };
669 807
670 local tblRemoveItemTemplate = { 808 local tblRemoveItemTemplate = {
671 order = 0, 809 order = 0,
672 type = "input", 810 type = "input",
675 return tostring( 7 - (itemRarity or 0) ) .. (itemName or ""); 813 return tostring( 7 - (itemRarity or 0) ) .. (itemName or "");
676 end, 814 end,
677 get = function(info) 815 get = function(info)
678 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side 816 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side
679 end, 817 end,
680 set = function(widget, info) 818 set = function(groupId, itemId)
681 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info. 819 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info.
682 820
683 if widget.itemId then 821 if itemId then
684 local groupName = groupIdToName[info[2]]; 822 local groupName = groupIdToName[groupId];
685 823
686 -- Unset this item 824 -- Unset this item
687 addon.db.global.groups[groupName].items[widget.itemId] = nil; 825 addon.db.global.groups[groupName].items[itemId] = nil;
688 826
689 -- Now rebuild the list 827 -- Now rebuild the list
690 AceConfigRegistry:NotifyChange("InventoryOptions"); 828 AceConfigRegistry:NotifyChange("InventoryOptions");
691 end 829 end
692 end, 830 end,
693 width = "double", 831 width = "double",
694 dialogControl = "ItemLinkButton", 832 dialogControl = "ConfigItemLinkButton",
695 }; 833 };
696 834
697 local function UpdateAddItemList(info) 835 local function UpdateAddItemList(info)
698 local groupName = groupIdToName[info[2]]; 836 local groupName = groupIdToName[info[2]];
699 837
841 type = "toggle", 979 type = "toggle",
842 name = "Alert when below minimum", 980 name = "Alert when below minimum",
843 desc = "Show an alert when an item in this group gets below the minimum stock threshold.", 981 desc = "Show an alert when an item in this group gets below the minimum stock threshold.",
844 arg = "overrideAlertBelowMinimum", 982 arg = "overrideAlertBelowMinimum",
845 }, 983 },
984 overrideTrackAtCharacters = {
985 order = 39,
986 type = "toggle",
987 name = "Override track at",
988 desc = "Allows you to override at which characters items in this group should appear in the summary and generate alerts.",
989 arg = "trackAtCharacters",
990 },
991 trackAtCharacters = {
992 order = 40,
993 type = "multiselect",
994 name = "Track at",
995 desc = "Select at which characters this should appear in the summary and generate alerts.",
996 values = function()
997 local temp = {};
998 for charName in pairs(addon.db.factionrealm.characters) do
999 temp[charName] = charName;
1000 end
1001
1002 -- We MUST close this pullout or we can get errors or even game client crashes once we click another group or close the config dialog!
1003 local count = AceGUI:GetNextWidgetNum("Dropdown-Pullout");
1004 for i = 0, count do
1005 if _G['AceGUI30Pullout' .. i] then
1006 _G['AceGUI30Pullout' .. i]:Hide();
1007 end
1008 end
1009
1010 return temp;
1011 end,
1012 get = GetMultiOption,
1013 dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead.
1014 arg = "overrideTrackAtCharacters",
1015 },
846 }, 1016 },
847 }, 1017 },
848 refill = { 1018 refill = {
849 order = 20, 1019 order = 20,
850 type = "group", 1020 type = "group",
859 type = "description", 1029 type = "description",
860 name = function(info) 1030 name = function(info)
861 local groupName = groupIdToName[info[2]]; 1031 local groupName = groupIdToName[info[2]];
862 local r = "Here you can specify the amount of items to which you wish to restock when you are collecting new items for the currently selected group. This may be higher than the minimum stock.\n\n"; 1032 local r = "Here you can specify the amount of items to which you wish to restock when you are collecting new items for the currently selected group. This may be higher than the minimum stock.\n\n";
863 1033
864 r = r .. "When restocking the target amount is |cfffed000" .. GetOptionByKey(groupName, "restockTarget") .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( GetOptionByKey(groupName, "minCraftingQueue") * GetOptionByKey(groupName, "restockTarget") ) .. "|r (|cfffed000" .. ( GetOptionByKey(groupName, "minCraftingQueue") * 100 ) .. "%|r) of the restock target."; 1034 r = r .. "When restocking the target amount is |cfffed000" .. addon:GetOptionByKey(groupName, "restockTarget") .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * addon:GetOptionByKey(groupName, "restockTarget") ) .. "|r (|cfffed000" .. ( addon:GetOptionByKey(groupName, "minCraftingQueue") * 100 ) .. "%|r) of the restock target.";
865 1035
866 return r; 1036 return r;
867 end, 1037 end,
868 }, 1038 },
869 header = { 1039 header = {
904 step = 0.01, 1074 step = 0.01,
905 isPercent = true, 1075 isPercent = true,
906 name = "Don't queue if I only miss", 1076 name = "Don't queue if I only miss",
907 desc = "Don't add a craftable item to the queue if I only miss this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.", 1077 desc = "Don't add a craftable item to the queue if I only miss this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.",
908 arg = "overrideMinCraftingQueue", 1078 arg = "overrideMinCraftingQueue",
1079 },
1080 overrideBonusQueue = {
1081 order = 29,
1082 type = "toggle",
1083 name = "Override bonus queue",
1084 desc = "Allows you to override the bonus craftable items queue setting for this group.",
1085 arg = "bonusQueue",
1086 },
1087 bonusQueue = {
1088 order = 30,
1089 type = "range",
1090 min = 0,
1091 max = 10, -- 1000%
1092 step = 0.01, -- 1%
1093 isPercent = true,
1094 name = "Bonus queue",
1095 desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.",
1096 arg = "overrideBonusQueue",
1097 },
1098 overridePriceThreshold = {
1099 order = 39,
1100 type = "toggle",
1101 name = "Override price threshold",
1102 desc = "Allows you to override the price threshold setting for this group.",
1103 arg = "priceThreshold",
1104 },
1105 priceThreshold = {
1106 order = 40,
1107 type = "input",
1108 name = "Price threshold",
1109 desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.",
1110 validate = function(info, value) return addon:ValidateReadableMoney(info, value); end,
1111 get = function(i) return addon:ReadableMoney(GetOption(i)); end,
1112 set = function(i, v) SetOption(i, addon:ReadableMoneyToCopper(v)); end,
1113 arg = "overridePriceThreshold",
1114 },
1115 overrideHideFromSummaryWhenBelowPriceThreshold = {
1116 order = 49,
1117 type = "toggle",
1118 name = "Override summary showing",
1119 desc = "Allows you to override if items in this group should be hidden from the summary while their value is below the price threshold.",
1120 arg = "hideFromSummaryWhenBelowPriceThreshold",
1121 },
1122 hideFromSummaryWhenBelowPriceThreshold = { -- I wish this var could be a little bit shorter...
1123 order = 50,
1124 type = "toggle",
1125 name = "Hide when below threshold",
1126 desc = "Hide items from the summary when their value is below the set price threshold.",
1127 arg = "overrideHideFromSummaryWhenBelowPriceThreshold",
909 }, 1128 },
910 }, 1129 },
911 }, 1130 },
912 }, 1131 },
913 }, 1132 },
1281 1500
1282 function addon:GetItemCount(itemId) 1501 function addon:GetItemCount(itemId)
1283 return Altoholic:GetItemCount(itemId); 1502 return Altoholic:GetItemCount(itemId);
1284 end 1503 end
1285 1504
1505 function addon:GetAuctionValue(link)
1506 if GetAuctionBuyout then
1507 -- Auctionator support
1508
1509 local lowBuy = GetAuctionBuyout(link);
1510
1511 if lowBuy == nil then
1512 -- No auctions up at this time
1513 return -1;
1514 end
1515
1516 return lowBuy;
1517 elseif AucAdvanced ~= nil and AucAdvanced.Modules.Util.SimpleAuction ~= nil and AucAdvanced.Modules.Util.SimpleAuction.Private.GetItems ~= nil then
1518 -- Auctioneer support
1519
1520 local imgSeen, _, _, _, _, lowBuy, _, _ = AucAdvanced.Modules.Util.SimpleAuction.Private.GetItems(link);
1521 --local imgseen, image, matchBid, matchBuy, lowBid, lowBuy, aveBuy, aSeen
1522
1523 if imgSeen <= 0 then
1524 -- No auctions up at this time
1525 return -1;
1526 end
1527
1528 return lowBuy;
1529 end
1530 end
1531
1286 1532
1287 1533
1288 1534
1289 function addon:Debug(t) 1535 function addon:Debug(t)
1290 if not self.debugChannel and self.debugChannel ~= false then 1536 if not self.debugChannel and self.debugChannel ~= false then