annotate SecureMenu.lua @ 96:e3147b41ea9d v1.0beta9

Correct display, tooltips and error message when there are actual tradeskill spells in the SecureMenu. Still not sure that it works with enough reagents...
author contrebasse
date Fri, 20 May 2011 00:53:42 +0200
parents c369a2e16ab6
children c8d527a9fb3a
rev   line source
contrebasse@0 1 local addonName, A = ...
contrebasse@0 2
contrebasse@0 3 -- Create the menu frame
contrebasse@34 4 local MenuFrame = CreateFrame("Frame","ReagentMaker_ExternalFrame",UIParent)
contrebasse@0 5 MenuFrame:Hide()
contrebasse@3 6 MenuFrame:SetSize(192,256)
contrebasse@2 7 MenuFrame:SetFrameStrata("DIALOG")
contrebasse@3 8 MenuFrame:EnableMouse(true)
contrebasse@3 9 MenuFrame:SetPoint("CENTER")
contrebasse@3 10 tinsert(UISpecialFrames,"ReagentMaker_ExternalFrame") -- make it closable with escape
contrebasse@2 11
contrebasse@20 12 local SCAN_DELAY = 0.2
contrebasse@20 13 local t_throttle = SCAN_DELAY
contrebasse@20 14 function MenuFrame.throttleUpdateCounts(self, t_elapsed)
contrebasse@20 15 t_throttle = t_throttle - t_elapsed
contrebasse@20 16 if t_throttle<0 then
contrebasse@20 17 self:SetScript("OnUpdate", nil)
contrebasse@20 18
contrebasse@20 19 -- Update counts
contrebasse@20 20 MenuFrame.updateCounts()
contrebasse@20 21 end
contrebasse@20 22 end
contrebasse@3 23 MenuFrame:SetScript("OnEvent",function(self,event,...)
contrebasse@20 24 if event == "BAG_UPDATE" then
contrebasse@20 25 t_throttle = SCAN_DELAY
contrebasse@20 26 self:SetScript("OnUpdate", MenuFrame.throttleUpdateCounts)
contrebasse@19 27 elseif event == "TRADE_SKILL_CLOSE" or event == "PLAYER_REGEN_DISABLED" then
contrebasse@3 28 MenuFrame:Hide()
contrebasse@3 29 end
contrebasse@3 30 end)
contrebasse@3 31 MenuFrame:RegisterEvent("TRADE_SKILL_CLOSE")
contrebasse@3 32 MenuFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
contrebasse@20 33 MenuFrame:RegisterEvent("BAG_UPDATE")
contrebasse@20 34 MenuFrame:SetScript("OnEnter",function(self)
contrebasse@20 35 if self.reagentLink then
contrebasse@20 36 GameTooltip:SetOwner(self)
contrebasse@20 37 GameTooltip:SetHyperlink(self.reagentLink)
contrebasse@20 38 GameTooltip:Show()
contrebasse@20 39 GameTooltip:ClearAllPoints()
contrebasse@20 40 GameTooltip:SetPoint("TOPRIGHT",self,"TOPLEFT",10,0)
contrebasse@32 41 if self.spellLink then
contrebasse@32 42 A.tooltipRecipe:SetOwner(GameTooltip)
contrebasse@32 43 A.tooltipRecipe:SetHyperlink(self.spellLink)
contrebasse@32 44 A.tooltipRecipe:Show()
contrebasse@32 45 A.tooltipRecipe:ClearAllPoints()
contrebasse@32 46 A.tooltipRecipe:SetPoint("TOPRIGHT",GameTooltip,"BOTTOMRIGHT")
contrebasse@32 47 end
contrebasse@20 48 end
contrebasse@20 49 end)
contrebasse@20 50 MenuFrame:SetScript("OnLeave",function()
contrebasse@20 51 GameTooltip:Hide()
contrebasse@32 52 A.tooltipRecipe:Hide()
contrebasse@20 53 end)
contrebasse@33 54
contrebasse@33 55 -- Hide frame when selecting a recipe which doesn't need this reagent
contrebasse@33 56 hooksecurefunc("SelectTradeSkill",function()
contrebasse@33 57 local selectedIndex = GetTradeSkillSelectionIndex()
contrebasse@33 58 for reagentRecipeIndex = 1,GetTradeSkillNumReagents(selectedIndex) do
contrebasse@33 59 local reagentID = A.link2ID(GetTradeSkillReagentItemLink(selectedIndex, reagentRecipeIndex))
contrebasse@33 60 if reagentID == MenuFrame.itemID or (MenuFrame.superItemID and reagentID == MenuFrame.superItemID) then
contrebasse@33 61 return
contrebasse@33 62 end
contrebasse@33 63 end
contrebasse@33 64 MenuFrame:Hide()
contrebasse@33 65 end)
contrebasse@3 66 A.MenuFrame = MenuFrame
contrebasse@3 67
contrebasse@3 68 -- Background adaptable vertically
contrebasse@3 69 local bg_top = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0)
contrebasse@3 70 bg_top:SetTexture("Interface\\LootFrame\\UI-LootPanel")
contrebasse@3 71 bg_top:SetSize(192,80)
contrebasse@3 72 bg_top:SetPoint("TOP")
contrebasse@3 73 bg_top:SetTexCoord(0,192/256,0,80/256)
contrebasse@3 74 local bg_bot = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0)
contrebasse@3 75 bg_bot:SetTexture("Interface\\LootFrame\\UI-LootPanel")
contrebasse@3 76 bg_bot:SetSize(192,16)
contrebasse@3 77 bg_bot:SetPoint("BOTTOM")
contrebasse@3 78 bg_bot:SetTexCoord(0,192/256,240/256,1)
contrebasse@3 79 local bg_mid = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0)
contrebasse@3 80 bg_mid:SetTexture("Interface\\LootFrame\\UI-LootPanel")
contrebasse@3 81 bg_mid:SetWidth(192)
contrebasse@3 82 bg_mid:SetPoint("TOP",bg_top,"BOTTOM")
contrebasse@3 83 bg_mid:SetPoint("BOTTOM",bg_bot,"TOP")
contrebasse@3 84 bg_mid:SetTexCoord(0,192/256,80/256,240/256)
contrebasse@3 85
contrebasse@3 86 -- Bouton de fermeture
contrebasse@3 87 local CloseButton = CreateFrame("Button",nil,MenuFrame,"UIPanelCloseButton");
contrebasse@3 88 CloseButton:SetPoint("TOPRIGHT",0,-10)
contrebasse@3 89
contrebasse@3 90 -- Main icon
contrebasse@3 91 local itemIcon = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,-1)
contrebasse@3 92 itemIcon:SetSize(64,64)
contrebasse@3 93 itemIcon:SetPoint("TOPLEFT",8,-4)
contrebasse@3 94
contrebasse@3 95 -- Title
contrebasse@3 96 local TitleText = MenuFrame:CreateFontString(nil,"ARTWORK","GameFontHighlight")
contrebasse@45 97 --TitleText:SetSize(92,14)
contrebasse@45 98 TitleText:SetSize(92,36)
contrebasse@45 99 TitleText:SetPoint("TOPRIGHT",CloseButton,"TOPLEFT",4,-8)
contrebasse@45 100 TitleText:SetWordWrap(true)
contrebasse@45 101 TitleText:SetNonSpaceWrap(false)
contrebasse@45 102 TitleText:SetJustifyV("TOP")
contrebasse@45 103
contrebasse@3 104
contrebasse@3 105 local MENU_ENTRY_HEIGHT = 41
contrebasse@3 106 local MENU_ENTRY_WIDTH = 147
contrebasse@3 107 local MENU_ENTRY_ICON_RATIO = 40/48
contrebasse@2 108
contrebasse@0 109 local numActiveEntries = 0
contrebasse@0 110 local menuEntries = {}
contrebasse@0 111
contrebasse@3 112 -- Button hovering
contrebasse@5 113 local function btnEntered(btn)
contrebasse@20 114 if btn.numMakable and btn.numMakable>0 then
contrebasse@5 115 btn.textureHighlight:Show()
contrebasse@5 116 end
contrebasse@3 117
contrebasse@20 118 GameTooltip:SetOwner(btn,"ANCHOR_LEFT")
contrebasse@5 119 GameTooltip:SetHyperlink(btn.reagentLink)
contrebasse@5 120 GameTooltip:Show()
contrebasse@96 121 if btn.spellLink and btn.spellLink~=btn.reagentLink then
contrebasse@31 122 A.tooltipRecipe:SetOwner(GameTooltip)
contrebasse@31 123 A.tooltipRecipe:SetHyperlink(btn.spellLink)
contrebasse@31 124 A.tooltipRecipe:Show()
contrebasse@31 125 A.tooltipRecipe:ClearAllPoints()
contrebasse@31 126 A.tooltipRecipe:SetPoint("TOPRIGHT",GameTooltip,"BOTTOMRIGHT")
contrebasse@20 127 end
contrebasse@3 128 end
contrebasse@5 129 local function btnLeft(btn)
contrebasse@5 130 btn.textureHighlight:Hide()
contrebasse@5 131 GameTooltip:Hide()
contrebasse@5 132 A.tooltipRecipe:Hide()
contrebasse@3 133 end
contrebasse@3 134 local function createMenuEntry()
contrebasse@3 135 local btn = CreateFrame("Button", nil, MenuFrame, "SecureActionButtonTemplate")
contrebasse@3 136 table.insert(menuEntries,btn)
contrebasse@3 137
contrebasse@3 138 btn:Hide()
contrebasse@3 139 btn:SetSize(MENU_ENTRY_WIDTH,MENU_ENTRY_HEIGHT)
contrebasse@3 140 btn:SetFrameStrata("DIALOG")
contrebasse@3 141
contrebasse@3 142 -- Set its position
contrebasse@3 143 if #menuEntries>1 then
contrebasse@3 144 btn:SetPoint("TOP",menuEntries[#menuEntries-1],"BOTTOM",0,-2)
contrebasse@2 145 else
contrebasse@3 146 btn:SetPoint("TOPLEFT",MenuFrame,"TOPLEFT",24,-79)
contrebasse@2 147 end
contrebasse@3 148
contrebasse@3 149 local icon = btn:CreateTexture(nil,"BACKGROUND")
contrebasse@3 150 icon:SetPoint("TOPLEFT")
contrebasse@3 151 icon:SetSize(39,39)
contrebasse@3 152 btn.icon = icon
contrebasse@3 153
contrebasse@3 154 local itemNameBG = btn:CreateTexture(nil,"BACKGROUND")
contrebasse@3 155 itemNameBG:SetTexture("Interface\\QuestFrame\\UI-QuestItemNameFrame")
contrebasse@3 156 itemNameBG:SetSize(128,64)
contrebasse@3 157 itemNameBG:SetPoint("LEFT",icon,"RIGHT",-10,0)
contrebasse@3 158
contrebasse@3 159 local itemName = btn:CreateFontString(nil,"BACKGROUND","GameFontHighlight")
contrebasse@3 160 itemName:SetSize(90,36)
contrebasse@3 161 itemName:SetPoint("LEFT",itemNameBG,"LEFT",15,0)
contrebasse@3 162 itemName:SetJustifyH("LEFT")
contrebasse@3 163 itemName:SetWordWrap(true)
contrebasse@3 164 itemName:SetNonSpaceWrap(false)
contrebasse@3 165 btn.itemName = itemName
contrebasse@3 166
contrebasse@3 167 local textureHighlight = btn:CreateTexture(nil,"BORDER")
contrebasse@3 168 textureHighlight:Hide()
contrebasse@3 169 textureHighlight:SetTexture("Interface\\BUTTONS\\CheckButtonHilight")
contrebasse@3 170 textureHighlight:SetBlendMode("ADD")
contrebasse@3 171 textureHighlight:SetAllPoints(icon)
contrebasse@3 172 btn.textureHighlight = textureHighlight
contrebasse@5 173
contrebasse@5 174 local countDetail = btn:CreateFontString(nil,"ARTWORK","NumberFontNormal")
contrebasse@5 175 countDetail:SetPoint("BOTTOMRIGHT",icon,"BOTTOMRIGHT",-1,1)
contrebasse@5 176 countDetail:SetJustifyH("RIGHT")
contrebasse@5 177 countDetail:SetJustifyV("BOTTOM")
contrebasse@5 178 btn.countDetail = countDetail
contrebasse@5 179
contrebasse@10 180 local resultNumber = btn:CreateFontString(nil,"ARTWORK","NumberFontNormal")
contrebasse@11 181 resultNumber:SetPoint("TOPLEFT",icon,"TOPLEFT",1,-3)
contrebasse@10 182 resultNumber:SetJustifyH("LEFT")
contrebasse@10 183 resultNumber:SetJustifyV("TOP")
contrebasse@11 184 resultNumber:SetFont("Fonts\\ARIALN.TTF", 12, "OUTLINE")
contrebasse@10 185 btn.resultNumber = resultNumber
contrebasse@10 186
contrebasse@20 187 btn:SetScript("OnEnter", btnEntered)
contrebasse@20 188 btn:SetScript("OnLeave", btnLeft)
contrebasse@3 189
contrebasse@3 190 return btn
contrebasse@2 191 end
contrebasse@1 192
contrebasse@40 193 local function WarnNotMakable(btn)
contrebasse@96 194 if not btn.reagentID then
contrebasse@96 195 A.Error(A.L["You do not have enough reagents to craft [%s]"]:format(TitleText:GetText()))
contrebasse@96 196 else
contrebasse@96 197 A.Error(A.L["You do not have enough [%s] to craft [%s]"]:format(btn.itemNameString,TitleText:GetText()))
contrebasse@96 198 end
contrebasse@40 199 end
contrebasse@40 200
contrebasse@40 201 -- Update counts and button actions
contrebasse@19 202 function MenuFrame.updateCounts()
contrebasse@3 203 local anyMakable
contrebasse@0 204 for i=1,numActiveEntries do
contrebasse@3 205 btn = menuEntries[i]
contrebasse@3 206 local itemCount = GetItemCount(btn.reagentID)
contrebasse@3 207
contrebasse@3 208 local numMakable = math.floor(itemCount/(btn.reagentsForOneRecipe or 1))
contrebasse@3 209 btn.countDetail:SetText(itemCount.."/"..(btn.reagentsForOneRecipe or 1))
contrebasse@3 210
contrebasse@3 211 if numMakable>0 then
contrebasse@40 212 -- Set action
contrebasse@73 213 if type(btn.action)=="function" then
contrebasse@40 214 btn:SetScript("PreClick",btn.action)
contrebasse@40 215 btn:SetAttribute("type", nil)
contrebasse@40 216 btn:SetAttribute("macrotext", nil)
contrebasse@40 217 else --if type(action)=="string" then
contrebasse@40 218 btn:SetScript("PreClick",nil)
contrebasse@40 219 btn:SetAttribute("type", "macro")
contrebasse@73 220 btn:SetAttribute("macrotext", btn.action:format(btn.itemNameString))
contrebasse@40 221 end -- if
contrebasse@40 222
contrebasse@3 223 anyMakable = true
contrebasse@5 224 btn.countDetail:SetTextColor(1, 1, 1, 1)
contrebasse@3 225 btn.icon:SetVertexColor(1,1,1);
contrebasse@3 226 btn.itemName:SetTextColor(1,1,1,1)
contrebasse@3 227 else
contrebasse@5 228 -- Do not disable the button, to be able to show the tooltip
contrebasse@40 229 -- Disable only the effects
contrebasse@40 230 btn:SetScript("PreClick",WarnNotMakable)
contrebasse@40 231 btn:SetAttribute("type", nil)
contrebasse@40 232 btn:SetAttribute("macrotext", nil)
contrebasse@40 233
contrebasse@5 234 btn.countDetail:SetTextColor(1, 0.1, 0.1, 1)
contrebasse@3 235 btn.icon:SetVertexColor(0.5, 0.5, 0.5)
contrebasse@3 236 btn.itemName:SetTextColor(1,1,1,0.5)
contrebasse@3 237 end
contrebasse@5 238
contrebasse@5 239 btn.numMakable = numMakable
contrebasse@3 240 end
contrebasse@3 241
contrebasse@5 242 local r,g,b = TitleText:GetTextColor()
contrebasse@3 243 if anyMakable then
contrebasse@3 244 itemIcon:SetVertexColor(1,1,1)
contrebasse@5 245 TitleText:SetTextColor(r,g,b,1)
contrebasse@3 246 else
contrebasse@3 247 itemIcon:SetVertexColor(0.5, 0.5, 0.5)
contrebasse@5 248 TitleText:SetTextColor(r,g,b,0.7)
contrebasse@0 249 end
contrebasse@0 250 end
contrebasse@0 251
contrebasse@73 252 local function menuAddItem(action,itemID,reagent)
contrebasse@0 253 local btn
contrebasse@0 254 -- Create a button only if necessary
contrebasse@0 255 if numActiveEntries >= #menuEntries then
contrebasse@3 256 btn = createMenuEntry()
contrebasse@0 257 else
contrebasse@0 258 btn = menuEntries[numActiveEntries+1]
contrebasse@0 259 end
contrebasse@0 260
contrebasse@3 261 -- Set text and icon
contrebasse@96 262 local name, link, texture, _
contrebasse@96 263 if reagent[1] then
contrebasse@96 264 name, link, _, _, _, _, _, _, _, texture = GetItemInfo(reagent[1])
contrebasse@96 265 if not (name and link and texture) then
contrebasse@96 266 -- Will be retried on next OnUpdate
contrebasse@96 267 return
contrebasse@96 268 end
contrebasse@96 269 elseif reagent.spellLink then
contrebasse@96 270 --name, rank, icon, powerCost, isFunnel, powerType, castingTime, minRange, maxRange = GetSpellInfo(id)
contrebasse@96 271 name, _, texture = GetSpellInfo(A.link2ID(reagent.spellLink))
contrebasse@96 272 if not (name and texture) then
contrebasse@96 273 -- Will be retried on next OnUpdate
contrebasse@96 274 return
contrebasse@96 275 end
contrebasse@96 276 link = reagent.spellLink
contrebasse@3 277 end
contrebasse@96 278
contrebasse@73 279 btn.itemName:SetText(name)
contrebasse@73 280 btn.icon:SetTexture(texture)
contrebasse@3 281
contrebasse@10 282 -- Set chance to have the item or the number of items created
contrebasse@93 283 btn.resultNumber:Hide()
contrebasse@10 284 if reagent[3] then
contrebasse@10 285 if reagent[3]<1 then
contrebasse@10 286 btn.resultNumber:SetText((reagent[3]*100).."%")
contrebasse@93 287 btn.resultNumber:Show()
contrebasse@11 288 elseif reagent[4] and reagent[3]~=reagent[4] then
contrebasse@11 289 btn.resultNumber:SetText(math.min(reagent[3],reagent[4]).."-"..math.max(reagent[3],reagent[4]))
contrebasse@93 290 btn.resultNumber:Show()
contrebasse@10 291 elseif reagent[3]>1 then
contrebasse@10 292 btn.resultNumber:SetText(reagent[3])
contrebasse@93 293 btn.resultNumber:Show()
contrebasse@10 294 end
contrebasse@10 295 end
contrebasse@10 296
contrebasse@3 297 -- Save params
contrebasse@3 298 btn.itemID = itemID
contrebasse@10 299 btn.reagentID = reagent[1]
contrebasse@5 300 btn.reagentLink = link
contrebasse@10 301 btn.reagentsForOneRecipe = reagent[2]
contrebasse@73 302 btn.spellLink = reagent.spellLink
contrebasse@40 303 btn.action = action
contrebasse@40 304 btn.itemNameString = name
contrebasse@0 305
contrebasse@3 306 btn:Show()
contrebasse@0 307
contrebasse@2 308 -- Increase the entry number
contrebasse@0 309 numActiveEntries = numActiveEntries + 1
contrebasse@34 310
contrebasse@34 311 -- Everything went well
contrebasse@34 312 return true
contrebasse@0 313 end -- function
contrebasse@3 314
contrebasse@34 315 -- Function used on OnUpdate tu update the frame if there were errors the previous time
contrebasse@34 316 local function reopen()
contrebasse@34 317 -- Release OnUpdate frame (could conflict with BAG_UPDATE)
contrebasse@34 318 MenuFrame:SetScript("OnUpdate",nil)
contrebasse@34 319
contrebasse@34 320 -- reopen
contrebasse@34 321 A.externalCraftWindow(MenuFrame.itemID,MenuFrame.superItemID)
contrebasse@34 322 end
contrebasse@34 323
contrebasse@3 324 -- Fill the window and open it
contrebasse@33 325 function A.externalCraftWindow(itemID,superItemID)
contrebasse@3 326 -- Do not open during combat
contrebasse@3 327 if InCombatLockdown() then return end
contrebasse@3 328
contrebasse@3 329 -- Save the tradeskill
contrebasse@3 330 A.currentTradeSkill = GetTradeSkillLine()
contrebasse@3 331
contrebasse@3 332 -- Close the previous menu
contrebasse@3 333 MenuFrame:Hide()
contrebasse@3 334 for i=1,numActiveEntries do
contrebasse@3 335 menuEntries[i]:Hide()
contrebasse@3 336 end
contrebasse@3 337 numActiveEntries = 0
contrebasse@3 338
contrebasse@3 339 -- Fill the info of the reagent to make
contrebasse@35 340 local name, link, quality, _, _, _, _, _, _, texture = GetItemInfo(itemID)
contrebasse@3 341 SetPortraitToTexture(itemIcon, texture)
contrebasse@3 342 TitleText:SetText(name)
contrebasse@5 343 local color = ITEM_QUALITY_COLORS[quality]
contrebasse@5 344 TitleText:SetTextColor(color.r, color.g, color.b)
contrebasse@3 345
contrebasse@20 346 -- Save vars to show the tooltip later
contrebasse@20 347 MenuFrame.reagentLink = link
contrebasse@73 348 MenuFrame.spellLink = A.isRecipeUnique(A.data[itemID]) and A.data[itemID][1].spellLink
contrebasse@33 349 MenuFrame.itemID = itemID
contrebasse@73 350 MenuFrame.superItemID = superItemID -- optional, will be nil if not set
contrebasse@34 351
contrebasse@3 352 -- Loop over the available recipes
contrebasse@76 353 local noSkipped = true -- check if we have to reload the external frame to get all the data
contrebasse@76 354 local existsValidEntries -- check if the menu contains at least one item (cross-tradeskill problem)
contrebasse@3 355 for _,reagent in ipairs(A.data[itemID]) do
contrebasse@73 356 if reagent.macro then
contrebasse@29 357 -- Special spell
contrebasse@76 358 existsValidEntries = true
contrebasse@76 359 noSkipped = menuAddItem(reagent.macro,itemID,reagent) and noSkipped
contrebasse@29 360 else
contrebasse@76 361 -- Standard tradeskill spell
contrebasse@93 362 if not reagent.spellName or reagent.spellName == A.currentTradeSkill then
contrebasse@76 363 existsValidEntries = true
contrebasse@76 364 noSkipped = menuAddItem(A.craft,itemID,reagent) and noSkipped
contrebasse@76 365 end
contrebasse@29 366 end -- if
contrebasse@3 367 end -- for
contrebasse@3 368
contrebasse@76 369 -- do not show an empty menu
contrebasse@76 370 if not existsValidEntries then
contrebasse@76 371 return false
contrebasse@76 372 end
contrebasse@76 373
contrebasse@3 374 MenuFrame:SetHeight(89 + numActiveEntries*(MENU_ENTRY_HEIGHT+2))
contrebasse@3 375
contrebasse@3 376 MenuFrame:ClearAllPoints()
contrebasse@3 377 MenuFrame:SetPoint("TOPLEFT",TradeSkillFrame,"TOPRIGHT",-2,14)
contrebasse@3 378
contrebasse@40 379 -- Update counts and set actions
contrebasse@19 380 MenuFrame.updateCounts()
contrebasse@3 381
contrebasse@3 382 MenuFrame:Show()
contrebasse@34 383
contrebasse@76 384 if not noSkipped then
contrebasse@34 385 MenuFrame:SetScript("OnUpdate",reopen)
contrebasse@34 386 end
contrebasse@3 387 end