vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 cgc = AceLibrary("AceAddon-2.0"):new("AceDB-2.0", "AceConsole-2.0", "AceDebug-2.0", "AceEvent-2.0", "AceHook-2.0")
2  
3 -- Dewdrop: handles our dropdown
4 local dewdrop = AceLibrary("Dewdrop-2.0")
5  
6 -- Our container for all frames.
7 local frames = {}
8  
9 -- The search type should default to "by name"
10 cgc:RegisterDB("cgCraftyDB")
11 cgc:RegisterDefaults('profile', {
12 searchType = {},
13 searchHistory = {},
14 })
15  
16 function cgc:OnInitialize()
17 self:SetDebugging(false)
18 self:RegisterChatCommand({ "/cgcrafty", "/cgc" }, nil)
19  
20 -- Tradeskill frame references
21 frames.trade = {}
22 frames.trade.elements = {
23 ["Main"] = "TradeSkillFrame",
24 ["Title"] = "TradeSkillFrameTitleText",
25 ["Scroll"] = "TradeSkillListScrollFrame",
26 ["ScrollBar"] = "TradeSkillListScrollFrameScrollBar",
27 ["Highlight"] = "TradeSkillHighlightFrame",
28 ["CollapseAll"] = "TradeSkillCollapseAllButton",
29 }
30 frames.trade.anchor = "TradeSkillCreateAllButton"
31 frames.trade.anchor_offset_x = -9
32 frames.trade.anchor_offset_y = -8
33 frames.trade.update = "TradeSkillFrame_Update"
34  
35 -- Crafting frame references
36 frames.craft = {}
37 frames.craft.elements = {
38 ["Main"] = "CraftFrame",
39 ["Title"] = "CraftFrameTitleText",
40 ["Scroll"] = "CraftListScrollFrame",
41 ["ScrollBar"] = "CraftListScrollFrameScrollBar",
42 ["Highlight"] = "CraftHighlightFrame",
43 }
44 frames.craft.anchor = "CraftCancelButton"
45 frames.craft.anchor_offset_x = 6
46 frames.craft.anchor_offset_y = -8
47 frames.craft.update = "CraftFrame_Update"
48  
49 -- Setup some closures for use later.
50 -- History search text setting variable get/save
51 self.getHistory = function(var) return self.db.profile.searchHistory[var] end
52 self.setHistory = function(val) self.db.profile.searchHistory[self.lastSearchTrade or getglobal(self.currentFrame.elements.Title):GetText()] = val end
53 self.clearHistory = function() self.db.profile.searchHistory = {} end
54 -- History search type setting variable get/save
55 self.getSearchType = function(val) return self.db.profile.searchType[getglobal(self.currentFrame.elements.Title):GetText()] or self.LOCALS.FRAME_SEARCH_TYPES[val] end
56 self.setSearchType = function(val) self.db.profile.searchType[getglobal(self.currentFrame.elements.Title):GetText()] = val end
57  
58 -- Search Text
59 self.searchText = nil
60 -- Clear our the search history
61 self.clearHistory()
62 -- Handler for the currently opened frame.
63 self.currentFrame = nil
64 end
65  
66 function cgc:OnEnable()
67 self:Debug("OnEnable called.")
68  
69 -- Tradeskill window --
70 self:RegisterEvent("TRADE_SKILL_SHOW")
71 -- Enchanting window --
72 self:RegisterEvent("CRAFT_SHOW")
73  
74 if not self.frame then
75 self:Debug("Creating cgcFrame.")
76 -- Create main frame
77 self.frame = CreateFrame("Frame", "cgcFrame", UIParent)
78 self.frame:Hide()
79 -- Set main frame properties
80 self.frame:SetPoint("CENTER", "UIParent", "CENTER", 0, 0)
81 self.frame:SetWidth(342)
82 self.frame:SetHeight(45)
83 self.frame:SetFrameStrata("MEDIUM")
84 self.frame:SetMovable(false)
85 self.frame:EnableMouse(true)
86 -- Set the main frame backdrop
87 self.frame:SetBackdrop({
88 bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", tile = true, tileSize = 32,
89 edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", edgeSize = 20,
90 insets = {left = 5, right = 6, top = 6, bottom = 5},
91 })
92 self.frame:SetBackdropColor(1, 1, 1, 1)
93 self.frame:SetBackdropBorderColor(0, .8, 0, 1)
94 self.frame:SetScript("OnShow", function() self:OnShow() end)
95  
96 -- Create sub-frames
97 -- Editbox for search text
98 self.frame.SearchBox = CreateFrame("EditBox", nil, self.frame, "InputBoxTemplate")
99 self.frame.SearchBox:SetAutoFocus(false)
100 self.frame.SearchBox:SetWidth(110)
101 self.frame.SearchBox:SetHeight(20)
102 self.frame.SearchBox:SetPoint("LEFT", self.frame, "LEFT", 20, 0)
103 self.frame.SearchBox:SetBackdropColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b)
104 self.frame.SearchBox:SetBackdropBorderColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
105 self.frame.SearchBox:SetScript("OnEnterPressed", function() self:Search(this:GetText()) end)
106  
107 -- Reset Button
108 self.frame.ResetButton = CreateFrame("Button", nil, self.frame, "GameMenuButtonTemplate")
109 self.frame.ResetButton:SetWidth(20)
110 self.frame.ResetButton:SetHeight(25)
111 self.frame.ResetButton:SetPoint("RIGHT", self.frame, "RIGHT", -15, 0)
112 self.frame.ResetButton:SetText(self.LOCALS.FRAME_RESET_TEXT)
113 self.frame.ResetButton:SetScript("OnClick", function() self:Reset() end)
114  
115 -- Submit Button
116 self.frame.SubmitButton = CreateFrame("Button", nil, self.frame, "GameMenuButtonTemplate")
117 self.frame.SubmitButton:SetWidth(20)
118 self.frame.SubmitButton:SetHeight(25)
119 self.frame.SubmitButton:SetPoint("RIGHT", self.frame.ResetButton, "LEFT", -10, 0)
120 self.frame.SubmitButton:SetText(self.LOCALS.FRAME_SUBMIT_TEXT)
121 self.frame.SubmitButton:SetScript("OnClick", function() self:Search(self.frame.SearchBox:GetText()) end)
122  
123 -- SearchType dropdown button to show the menu when clicked.
124 self.frame.SearchTypeButton = CreateFrame("Button", nil, self.frame, "GameMenuButtonTemplate")
125 self.frame.SearchTypeButton:SetWidth(70)
126 self.frame.SearchTypeButton:SetHeight(25)
127 self.frame.SearchTypeButton:SetPoint("LEFT", self.frame.SearchBox, "RIGHT", 8, 0)
128 self.frame.SearchTypeButton:SetText("Type")
129 self.frame.SearchTypeButton:SetScript("OnClick", function()
130 if ( dewdrop:IsOpen(self.frame.SearchTypeButton) ) then
131 dewdrop:Close()
132 else
133 dewdrop:Open(self.frame.SearchTypeButton)
134 end
135 end
136 )
137  
138 -- Create the SearchType dropdown menu
139 dewdrop:Register(self.frame.SearchTypeButton,
140 'point', function (parent)
141 return "TOPLEFT", "BOTTOMLEFT"
142 end,
143 'dontHook', true,
144 'children', function ()
145 dewdrop:AddLine(
146 'text', cgc.LOCALS.FRAME_SEARCH_TYPE_TITLE,
147 'isTitle', true
148 )
149 for i,type in self.LOCALS.FRAME_SEARCH_TYPES do
150 dewdrop:AddLine(
151 'text', type,
152 'func', function(val)
153 self.setSearchType(val)
154 self.frame.SearchTypeButton:SetText(val)
155 end,
156 'arg1', type,
157 'tooltipTitle', type,
158 'tooltipText', self.LOCALS.FRAME_SEARCH_TYPES_DESC[i],
159 'closeWhenClicked', true
160 )
161 end
162 end
163 )
164  
165 -- Link Reagents dropdown button to show the menu when clicked.
166 self.frame.LinkReagentButton = CreateFrame("Button", nil, self.frame, "GameMenuButtonTemplate")
167 self.frame.LinkReagentButton:SetWidth(50)
168 self.frame.LinkReagentButton:SetHeight(25)
169 self.frame.LinkReagentButton:SetPoint("LEFT", self.frame.SearchTypeButton, "RIGHT", 8, 0)
170 self.frame.LinkReagentButton:SetText(self.LOCALS.FRAME_LINK_REAGENTS)
171 self.frame.LinkReagentButton:SetScript("OnClick", function()
172 if ( dewdrop:IsOpen(self.frame.LinkReagentButton) ) then
173 dewdrop:Close()
174 else
175 dewdrop:Open(self.frame.LinkReagentButton)
176 end
177 end
178 )
179  
180 -- Create the LinkReagents dropdown menu
181 dewdrop:Register(self.frame.LinkReagentButton,
182 'point', function (parent)
183 return "TOPLEFT", "BOTTOMLEFT"
184 end,
185 'dontHook', true,
186 'children', function ()
187 dewdrop:AddLine(
188 'text', cgc.LOCALS.FRAME_LINK_REAGENTS_TITLE,
189 'isTitle', true
190 )
191 for i,channel in self.LOCALS.FRAME_LINK_TYPES do
192 -- There are two types lines:
193 -- 1. Those that are straightforward and do not require user input
194 -- 2. Those that require the user to input information to take it a step further.
195 -- channel[1] is the "common name"
196 -- channel[2] is the "channel"
197 -- channel[3] is the "desc"
198 if ( channel[2] ~= "WHISPER" and channel[2] ~= "CHANNEL" ) then
199 dewdrop:AddLine(
200 'text', channel[1],
201 'func', function(val)
202 self:SendReagentsMessage(val, nil)
203 end,
204 'arg1', channel[2],
205 'closeWhenClicked', true
206 )
207 else
208 dewdrop:AddLine(
209 'text', channel[1],
210 'hasArrow', true,
211 'hasEditBox', true,
212 'tooltipTitle', channel[1],
213 'tooltipText', channel[3],
214 'editBoxFunc', function(channel, text)
215 self:SendReagentsMessage(channel, text)
216 end,
217 'editBoxArg1', channel[2]
218 )
219 end
220 end
221 end
222 )
223 end
224  
225 -- If the mod was disabled when WoW loaded, then the main frame will not be visible. So we'll make it visible again.
226 if ( getglobal(frames.trade.elements.Main) and getglobal(frames.trade.elements.Main):IsShown() ) then
227 cgc:TRADE_SKILL_SHOW()
228 elseif ( getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown() ) then
229 cgc:CRAFT_SHOW()
230 end
231 end
232  
233 function cgc:OnDisable()
234 if self.frame then
235 self.frame:Hide()
236 end
237  
238 -- Clear our search history and current search text.
239 self.clearHistory()
240 self.searchText = ""
241  
242 -- Finally, update the trade/craft windows just in case we have any lingering search results.
243 if ( self.hooks and self.hooks[frames.trade.update] ) then
244 getglobal(frames.trade.update)()
245 end
246  
247 if ( self.hooks and self.hooks[frames.craft.update] ) then
248 getglobal(frames.craft.update)()
249 end
250 end
251  
252 function cgc:OnShow()
253 self:Debug("OnShow called.")
254 -- Insert previous search text, if any.
255 if self.searchText ~= nil then
256 self.frame.SearchBox:SetText(self.searchText)
257 end
258  
259 self:Debug("OnShowCurrentWindow:"..getglobal(self.currentFrame.elements.Title):GetText())
260 -- Update the "Type" dropdown so that it reflects the current searchType or "Name" by default.
261 if ( self.getSearchType() ~= nil ) then
262 self.frame.SearchTypeButton:SetText(self.getSearchType())
263 else
264 self.frame.SearchTypeButton:SetText(self.getSearchType(1))
265 end
266 end
267  
268 function cgc:CRAFT_SHOW()
269 self:Debug("Crafting window open.")
270 -- first time window has been opened
271 if ( not self.hooks or not self.hooks[frames.craft.update] ) then
272 self:Debug("First time crafting window has opened, register close and hooking the update.")
273 self:RegisterEvent("CRAFT_CLOSE", "OnClose")
274 self:Hook(frames.craft.update, function () self:Update(true) end)
275 end
276  
277 -- Have to set our current frame for the widgets that load.
278 self.currentFrame = frames.craft
279  
280 -- Is the tradeskill window open? If so we'll need to close it.
281 if ( getglobal(frames.trade.elements.Main) and getglobal(frames.trade.elements.Main):IsShown() ) then
282 getglobal(frames.trade.elements.Main):Hide()
283 end
284  
285 -- We need to dynmically position the addon because the trade/craft anchors are different.
286 self.frame:ClearAllPoints()
287 self.frame:SetPoint("TOPRIGHT", frames.craft.anchor, "BOTTOMRIGHT" , frames.craft.anchor_offset_x, frames.craft.anchor_offset_y)
288 -- Check if the frame was already shown, which means they just changed tradeskills and no update with the OnShow.
289 -- Otherwise, lets just show the frame.
290 if ( self.frame:IsShown() ) then
291 self:OnShow()
292 else
293 self.frame:Show()
294 end
295  
296 -- Run our update.
297 self:Update(true)
298 end
299  
300 function cgc:TRADE_SKILL_SHOW()
301 self:Debug("Tradeskill window open.")
302 -- first time window has been opened
303 if ( not self.hooks or not self.hooks[frames.trade.update] ) then
304 self:Debug("First time trade skill window has opened, register close and hooking the update.")
305 self:RegisterEvent("TRADE_SKILL_CLOSE", "OnClose")
306 self:Hook(frames.trade.update, function () self:Update() end)
307  
308 -- Check if AutoCraft exists, if it does we're going to have to anchor to something different.
309 if ( AutoCraftFrame ) then
310 frames.trade.anchor = "AutoCraftRunAutomatically"
311 frames.trade.anchor_offset_x = -7
312 end
313 end
314  
315 -- Have to set our current frame for the widgets that load.
316 self.currentFrame = frames.trade
317  
318 -- Is the crafting window open? If so we'll need to close it.
319 if ( getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown() ) then
320 getglobal(frames.craft.elements.Main):Hide()
321 end
322  
323 -- We need to dynmically position the addon because the trade/craft anchors are different.
324 self.frame:ClearAllPoints()
325 self.frame:SetPoint("TOPLEFT", getglobal(frames.trade.anchor), "BOTTOMLEFT" , frames.trade.anchor_offset_x, frames.trade.anchor_offset_y)
326 -- Check if the frame was already shown, which means they just changed tradeskills and no update with the OnShow.
327 -- Otherwise, lets just show the frame.
328 if ( self.frame:IsShown() ) then
329 self:OnShow()
330 else
331 self.frame:Show()
332 end
333  
334 -- Run the update.
335 self:Update()
336 end
337  
338 function cgc:OnClose()
339 self:Debug("Tradeskill/Craft window close.")
340 self.frame:Hide()
341 end
342  
343 function cgc:Update(craft)
344 self:Debug("cgc:Update called.")
345  
346 -- Update the search history and searh type dropdown
347 self.setHistory(self.searchText)
348 -- The user has changed their trade window, reset the search text if they haven't searched before
349 if ( not self.lastSearchTrade or self.lastSearchTrade ~= getglobal(self.currentFrame.elements.Title):GetText() ) then
350 -- Now we update last searched to the current trade/craft type/window name
351 self.lastSearchTrade = getglobal(self.currentFrame.elements.Title):GetText()
352 -- Does old text for the current window exist?
353 if ( self.getHistory(self.lastSearchTrade) ) then
354 self:Debug("Found history: "..self.lastSearchTrade)
355 self.searchText = self.getHistory(self.lastSearchTrade)
356 else
357 self:Debug("No history, searchText=''")
358 self.searchText = ""
359 end
360 -- Finally, update the actual searchbox.
361 self.frame.SearchBox:SetText(self.searchText)
362 end
363  
364 -- The user has decided to search for
365 if ( self:GetSearchText() and getglobal(self.currentFrame.elements.Main):IsShown() ) then
366 local searchType = self.getSearchType()
367 local skillOffset = FauxScrollFrame_GetOffset(getglobal(self.currentFrame.elements.Scroll))
368 local skillButton = nil
369  
370 -- Keeps the list from being rebuilt unncessarily when the user is scrolling through search results.
371 if ( self.found and getn(self.found) == 0 ) then
372 if ( searchType == "Reagent" ) then
373 -- search by reagent results
374 self:BuildListByReagent(self:GetSearchText(), craft)
375 elseif ( searchType == "Requires" ) then
376 -- search by requires results
377 self:BuildListByRequire(self:GetSearchText(), craft)
378 else
379 -- search by name results
380 self:BuildListByName(self:GetSearchText(), craft)
381 end
382 end
383  
384 -- If we're doing tradeskills, we don't have categories, so we don't need a collapse.
385 if ( not craft ) then
386 getglobal(frames.trade.elements.CollapseAll):Disable();
387 end
388  
389 -- Update the scroll frame.
390 FauxScrollFrame_Update(getglobal(self.currentFrame.elements.Scroll), getn(self.found), (craft and CRAFTS_DISPLAYED or TRADE_SKILLS_DISPLAYED), (craft and CRAFT_SKILL_HEIGHT or TRADE_SKILL_HEIGHT), nil, nil, nil, getglobal(self.currentFrame.elements.Highlight), 293, 316 )
391 getglobal(self.currentFrame.elements.Highlight):Hide()
392  
393 if ( getn(self.found) > 0 ) then
394 -- Do the actual display of the list now.
395 for i=1, (craft and CRAFTS_DISPLAYED or TRADE_SKILLS_DISPLAYED), 1 do
396 local skillIndex = i + skillOffset
397 skillButton = getglobal((craft and "Craft" or "TradeSkillSkill")..i)
398  
399 if ( i <= getn(self.found) ) then
400 -- Set button widths if scrollbar is shown or hidden
401 if ( getglobal(self.currentFrame.elements.Scroll):IsVisible() ) then
402 skillButton:SetWidth(293)
403 else
404 skillButton:SetWidth(323)
405 end
406  
407 self:Debug("self.found["..skillIndex.."].type="..self.found[skillIndex].type)
408 local color = (craft and CraftTypeColor[self.found[skillIndex].type] or TradeSkillTypeColor[self.found[skillIndex].type])
409 if ( color ) then
410 skillButton:SetTextColor(color.r, color.g, color.b)
411 end
412 skillButton:SetID(self.found[skillIndex].index)
413 skillButton:Show()
414  
415 if ( self.found[skillIndex].name == "" ) then
416 return
417 end
418  
419 skillButton:SetNormalTexture("")
420 getglobal((craft and "Craft" or "TradeSkillSkill")..i.."Highlight"):SetTexture("")
421 if ( self.found[skillIndex].available == 0 ) then
422 skillButton:SetText(" "..self.found[skillIndex].name)
423 else
424 skillButton:SetText(" ".. self.found[skillIndex].name .." [".. self.found[skillIndex].available .."]")
425 end
426  
427 -- Place the highlight and lock the highlight state
428 if ( (craft and GetCraftSelectionIndex() or GetTradeSkillSelectionIndex()) == self.found[skillIndex].index ) then
429 getglobal(self.currentFrame.elements.Highlight):SetPoint("TOPLEFT", skillButton, "TOPLEFT", 0, 0)
430 getglobal(self.currentFrame.elements.Highlight):Show()
431 skillButton:LockHighlight()
432 -- Setting the num avail so the create all button works for tradeskills
433 if (not craft and getglobal(frames.trade.elements.Main)) then
434 getglobal(self.currentFrame.elements.Main).numAvailable = self.found[skillIndex].available
435 end
436 else
437 -- The highlight is shown, but it's on an entry that we haven't selected. Probably a remnant from a selection before we did our search,
438 -- so we'll go ahead and hide the frame.
439 if ( not self:SelectionInList(skillOffset, craft) ) then
440 getglobal(self.currentFrame.elements.Highlight):Hide()
441 end
442 skillButton:UnlockHighlight()
443 end
444 else
445 skillButton:Hide()
446 end
447 end
448 else
449 getglobal(self.currentFrame.elements.Scroll):Hide()
450 for i=1, (craft and CRAFTS_DISPLAYED or TRADE_SKILLS_DISPLAYED), 1 do
451 skillButton = getglobal((craft and "Craft" or "TradeSkillSkill")..i)
452  
453 skillButton:SetWidth(323)
454 skillButton:SetTextColor(1, 1, 1)
455 skillButton:SetID(1)
456 skillButton:SetNormalTexture("")
457 getglobal((craft and "Craft" or "TradeSkillSkill")..i.."Highlight"):Hide()
458 skillButton:UnlockHighlight();
459 skillButton:Show()
460  
461 if ( i == 1 ) then
462 getglobal(self.currentFrame.elements.Highlight):Hide()
463 skillButton:SetText(self.LOCALS.FRAME_NO_RESULTS)
464 else
465 skillButton:SetText("")
466 end
467 end
468 end
469 else
470 cgc:Debug("Calling original update functions:"..(craft and frames.craft.update or frames.trade.update))
471 self.hooks[ craft and frames.craft.update or frames.trade.update ].orig()
472 end
473 end
474  
475 ----------------------------------------
476 -- Retrieve the current searchText.
477 function cgc:GetSearchText()
478 -- The second argument is a search with only spaces.
479 if ( self.searchText ~= nil and string.len(string.gsub(self.searchText, "%s", "")) > 0 ) then
480 return self.searchText
481 else
482 return false
483 end
484 end
485  
486 ----------------------------------------
487 -- Begin the search and clear out the scrolling frame so it's not out of position.
488 function cgc:Search(searchText)
489 self:Debug("Search called; currentFrame="..self.currentFrame.elements.Main)
490 self.searchText = self.frame.SearchBox:GetText()
491 -- Need to reset / create our self.found array.
492 self.found = {}
493  
494 self.frame.SearchBox:ClearFocus()
495 -- We have to clear the offset on the scroll frame, otherwise we error out and it's misscrolled.
496 -- self.currentFrame = (getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown() and "CraftListScrollFrame" or getglobal(frames.trade.elements.Main) and getglobal(frames.trade.elements.Main):IsShown() and "TradeSkillListScrollFrame"
497 FauxScrollFrame_SetOffset(getglobal(self.currentFrame.elements.Main), 0)
498 getglobal(self.currentFrame.elements.ScrollBar):SetValue(0)
499 -- Finally, do the update.
500 self:Update(getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown())
501 end
502  
503 ----------------------------------------
504 -- Reset the skill frames.
505 function cgc:Reset()
506 self.searchText = ""
507 self.frame.SearchBox:ClearFocus();
508 self.frame.SearchBox:SetText(self.searchText);
509 self.clearHistory()
510 self:Update(getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown())
511 end
512  
513 --[[ ---------------------------------------------------------------------------------------------------- ]]--
514 -- Building functions which do the bulk work of this mod. They traverse through the current skill opened
515 -- and check for any matches against the users requested searchText, or build chat links to be sent
516 -- through SendChatMessage()
517 --[[ ---------------------------------------------------------------------------------------------------- ]]--
518  
519 ----------------------------------------
520 -- Build search list by item name.
521 function cgc:BuildListByName(searchText, craft)
522 local foundIndex = 0
523 self.found = {}
524  
525 if ( craft ) then
526 self:Debug("BuildingListByName for crafting.")
527 end
528  
529 local skillName, skillType, numAvailable, isExpanded
530 for i=1, (craft and GetNumCrafts() or GetNumTradeSkills()), 1 do
531 if ( craft ) then
532 skillName, _, skillType, numAvailable, isExpanded = GetCraftInfo(i)
533 else
534 skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(i)
535 end
536  
537 if ( strfind(string.lower(skillName), string.lower(searchText)) and skillType ~= "header" ) then
538 cgc:Debug("Match #"..foundIndex..": skillType="..skillType)
539 foundIndex = foundIndex + 1
540 self.found[foundIndex] = {}
541 self.found[foundIndex] = {
542 name = skillName,
543 type = skillType,
544 available = numAvailable,
545 index = i
546 }
547 elseif ( skillType == "header" and not isExpanded ) then
548 -- We need to expand any unexpanded header types, otherwise we can't parse their sub data.
549 ExpandTradeSkillSubClass(i)
550 end
551 end
552  
553 self:Debug("We found ".. foundIndex .." matches.")
554 end
555  
556 ----------------------------------------
557 -- Build search list by required.
558 function cgc:BuildListByRequire(searchText, craft)
559 local foundIndex = 0
560 self.found = {}
561  
562 local skillName, skillType, numAvailable, isExpanded
563 local requires
564 for i=1, (craft and GetNumCrafts() or GetNumTradeSkills()), 1 do
565 if ( craft ) then
566 skillName, _, skillType, numAvailable, isExpanded = GetCraftInfo(i)
567 requires = GetCraftSpellFocus(i)
568 else
569 skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(i)
570 requires = GetTradeSkillTools(i)
571 end
572  
573 if ( requires and strfind(string.lower(BuildColoredListString(requires)), string.lower(searchText)) and skillType ~= "header" ) then
574 self:Debug("Found matching require for '"..searchText.."': "..requires.." ")
575 foundIndex = foundIndex + 1
576 self.found[foundIndex] = {}
577 self.found[foundIndex] = {
578 name = skillName,
579 type = skillType,
580 available = numAvailable,
581 index = i
582 }
583 elseif ( skillType == "header" and not isExpanded ) then
584 -- We need to expand any unexpanded header types, otherwise we can't parse their sub data.
585 ExpandTradeSkillSubClass(i)
586 end
587 end
588 end
589  
590 ----------------------------------------
591 -- Build search list reagent name.
592 function cgc:BuildListByReagent(searchText, craft)
593 local foundIndex = 0
594 self.found = {}
595  
596 local skillName, skillType, numAvailable, isExpanded, reagentName
597 for i=1, (craft and GetNumCrafts() or GetNumTradeSkills()), 1 do
598 if ( craft ) then
599 skillName, _, skillType, numAvailable, isExpanded = GetCraftInfo(i)
600 else
601 skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(i)
602 end
603  
604 if ( skillType ~= "header" ) then
605 for e=1, (craft and GetCraftNumReagents(i) or GetTradeSkillNumReagents(i)), 1 do
606 if ( craft ) then
607 reagentName, _, _, _ = GetCraftReagentInfo(i, e)
608 else
609 reagentName, _, _, _ = GetTradeSkillReagentInfo(i, e)
610 end
611  
612  
613 if ( reagentName and strfind(string.lower(reagentName), string.lower(searchText)) ) then
614 foundIndex = foundIndex + 1
615 self.found[foundIndex] = {}
616 self.found[foundIndex] = {
617 name = skillName,
618 type = skillType,
619 available = numAvailable,
620 index = i
621 }
622 -- Some reagents can share a similar name so if we already matched one, we can break here.
623 break
624 end
625 end
626 elseif ( skillType == "header" and not isExpanded ) then
627 -- We need to expand any unexpanded header types, otherwise we can't parse their sub data.
628 ExpandTradeSkillSubClass(i)
629 end
630 end
631 end
632  
633 ----------------------------------------
634 -- Utility function to reagent information to chat.
635 function cgc:SendReagentsMessage(channel, who)
636 local sIndex, itemString
637 local tempString = ""
638 local reagentLinks = {}
639 local reagentCounts = {}
640 local craft = getglobal(frames.craft.elements.Main) and getglobal(frames.craft.elements.Main):IsShown()
641  
642 -- Figure out which window is open or exit function
643 if ( getglobal(self.currentFrame.elements.Main):IsShown() ) then
644 sIndex = craft and GetCraftSelectionIndex() or GetTradeSkillSelectionIndex()
645 self:Debug("SRM: GetTradeSkillSelectionIndex="..GetTradeSkillSelectionIndex())
646 else
647 return
648 end
649  
650 self:Debug("SRM: sIndex = "..sIndex)
651 -- Double check the user has a skill selected.
652 if ( sIndex > 0 ) then
653 -- Insert the name first.
654 itemString = craft and GetCraftItemLink(sIndex) or GetTradeSkillItemLink(sIndex)
655  
656 -- Cycle through all the reagents and get the required amounts for each into two nice arrays
657 for rIndex=1, (craft and GetCraftNumReagents(sIndex) or GetTradeSkillNumReagents(sIndex)), 1 do
658 if ( craft ) then
659 reagentLinks[rIndex] = GetCraftReagentItemLink(sIndex, rIndex)
660 _, _, reagentCounts[rIndex], _ = GetCraftReagentInfo(sIndex, rIndex)
661 else
662 reagentLinks[rIndex] = GetTradeSkillReagentItemLink(sIndex, rIndex)
663 _, _, reagentCounts[rIndex], _ = GetTradeSkillReagentInfo(sIndex, rIndex)
664 end
665 end
666  
667 -- Now we'll make strings out of them, 4 reagent links at a time and print them out when we reach our limit.
668  
669 for i=1, getn(reagentLinks) do
670 tempString = tostring(tempString) .. reagentLinks[i] .. "x" .. reagentCounts[i] .. " "
671 if ( mod(i,3) == 0 or i == getn(reagentLinks) ) then
672 -- Combine the item name, add (cont) if this is the second go round.
673 tempString = itemString .. (i > 3 and " (cont) = " or " = ") .. tempString
674 SendChatMessage(tempString, channel, GetDefaultLanguage("player"), who)
675 tempString = ""
676 end
677 end
678 end
679 end
680  
681 ----------------------------------------
682 -- Utility function for Update(): checks to see if the selected item is currently visible in the scrolling frame.
683 function cgc:SelectionInList(skillOffset, craft)
684 for i=skillOffset+1, skillOffset+(craft and CRAFTS_DISPLAYED or TRADE_SKILLS_DISPLAYED), 1 do
685 if ( self.found[i] and self.found[i].index == (craft and GetCraftSelectionIndex() or GetTradeSkillSelectionIndex()) ) then
686 return true
687 end
688 end
689  
690 return false
691 end