contrebasse@0: local addonName, A = ... contrebasse@0: contrebasse@0: -- Create the menu frame contrebasse@34: local MenuFrame = CreateFrame("Frame","ReagentMaker_ExternalFrame",UIParent) contrebasse@0: MenuFrame:Hide() contrebasse@3: MenuFrame:SetSize(192,256) contrebasse@2: MenuFrame:SetFrameStrata("DIALOG") contrebasse@3: MenuFrame:EnableMouse(true) contrebasse@3: MenuFrame:SetPoint("CENTER") contrebasse@3: tinsert(UISpecialFrames,"ReagentMaker_ExternalFrame") -- make it closable with escape contrebasse@2: contrebasse@20: local SCAN_DELAY = 0.2 contrebasse@20: local t_throttle = SCAN_DELAY contrebasse@20: function MenuFrame.throttleUpdateCounts(self, t_elapsed) contrebasse@20: t_throttle = t_throttle - t_elapsed contrebasse@20: if t_throttle<0 then contrebasse@20: self:SetScript("OnUpdate", nil) contrebasse@20: contrebasse@20: -- Update counts contrebasse@20: MenuFrame.updateCounts() contrebasse@20: end contrebasse@20: end contrebasse@3: MenuFrame:SetScript("OnEvent",function(self,event,...) contrebasse@20: if event == "BAG_UPDATE" then contrebasse@20: t_throttle = SCAN_DELAY contrebasse@20: self:SetScript("OnUpdate", MenuFrame.throttleUpdateCounts) contrebasse@19: elseif event == "TRADE_SKILL_CLOSE" or event == "PLAYER_REGEN_DISABLED" then contrebasse@3: MenuFrame:Hide() contrebasse@3: end contrebasse@3: end) contrebasse@3: MenuFrame:RegisterEvent("TRADE_SKILL_CLOSE") contrebasse@3: MenuFrame:RegisterEvent("PLAYER_REGEN_ENABLED") contrebasse@20: MenuFrame:RegisterEvent("BAG_UPDATE") contrebasse@20: MenuFrame:SetScript("OnEnter",function(self) contrebasse@20: if self.reagentLink then contrebasse@20: GameTooltip:SetOwner(self) contrebasse@20: GameTooltip:SetHyperlink(self.reagentLink) contrebasse@20: GameTooltip:Show() contrebasse@20: GameTooltip:ClearAllPoints() contrebasse@20: GameTooltip:SetPoint("TOPRIGHT",self,"TOPLEFT",10,0) contrebasse@32: if self.spellLink then contrebasse@32: A.tooltipRecipe:SetOwner(GameTooltip) contrebasse@32: A.tooltipRecipe:SetHyperlink(self.spellLink) contrebasse@32: A.tooltipRecipe:Show() contrebasse@32: A.tooltipRecipe:ClearAllPoints() contrebasse@32: A.tooltipRecipe:SetPoint("TOPRIGHT",GameTooltip,"BOTTOMRIGHT") contrebasse@32: end contrebasse@20: end contrebasse@20: end) contrebasse@20: MenuFrame:SetScript("OnLeave",function() contrebasse@20: GameTooltip:Hide() contrebasse@32: A.tooltipRecipe:Hide() contrebasse@20: end) contrebasse@33: contrebasse@33: -- Hide frame when selecting a recipe which doesn't need this reagent contrebasse@33: hooksecurefunc("SelectTradeSkill",function() contrebasse@33: local selectedIndex = GetTradeSkillSelectionIndex() contrebasse@33: for reagentRecipeIndex = 1,GetTradeSkillNumReagents(selectedIndex) do contrebasse@33: local reagentID = A.link2ID(GetTradeSkillReagentItemLink(selectedIndex, reagentRecipeIndex)) contrebasse@33: if reagentID == MenuFrame.itemID or (MenuFrame.superItemID and reagentID == MenuFrame.superItemID) then contrebasse@33: return contrebasse@33: end contrebasse@33: end contrebasse@33: MenuFrame:Hide() contrebasse@33: end) contrebasse@3: A.MenuFrame = MenuFrame contrebasse@3: contrebasse@3: -- Background adaptable vertically contrebasse@3: local bg_top = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0) contrebasse@3: bg_top:SetTexture("Interface\\LootFrame\\UI-LootPanel") contrebasse@3: bg_top:SetSize(192,80) contrebasse@3: bg_top:SetPoint("TOP") contrebasse@3: bg_top:SetTexCoord(0,192/256,0,80/256) contrebasse@3: local bg_bot = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0) contrebasse@3: bg_bot:SetTexture("Interface\\LootFrame\\UI-LootPanel") contrebasse@3: bg_bot:SetSize(192,16) contrebasse@3: bg_bot:SetPoint("BOTTOM") contrebasse@3: bg_bot:SetTexCoord(0,192/256,240/256,1) contrebasse@3: local bg_mid = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,0) contrebasse@3: bg_mid:SetTexture("Interface\\LootFrame\\UI-LootPanel") contrebasse@3: bg_mid:SetWidth(192) contrebasse@3: bg_mid:SetPoint("TOP",bg_top,"BOTTOM") contrebasse@3: bg_mid:SetPoint("BOTTOM",bg_bot,"TOP") contrebasse@3: bg_mid:SetTexCoord(0,192/256,80/256,240/256) contrebasse@3: contrebasse@3: -- Bouton de fermeture contrebasse@3: local CloseButton = CreateFrame("Button",nil,MenuFrame,"UIPanelCloseButton"); contrebasse@3: CloseButton:SetPoint("TOPRIGHT",0,-10) contrebasse@3: contrebasse@3: -- Main icon contrebasse@3: local itemIcon = MenuFrame:CreateTexture(nil,"BACKGROUND",nil,-1) contrebasse@3: itemIcon:SetSize(64,64) contrebasse@3: itemIcon:SetPoint("TOPLEFT",8,-4) contrebasse@3: contrebasse@3: -- Title contrebasse@3: local TitleText = MenuFrame:CreateFontString(nil,"ARTWORK","GameFontHighlight") contrebasse@45: --TitleText:SetSize(92,14) contrebasse@45: TitleText:SetSize(92,36) contrebasse@45: TitleText:SetPoint("TOPRIGHT",CloseButton,"TOPLEFT",4,-8) contrebasse@45: TitleText:SetWordWrap(true) contrebasse@45: TitleText:SetNonSpaceWrap(false) contrebasse@45: TitleText:SetJustifyV("TOP") contrebasse@45: contrebasse@3: contrebasse@3: local MENU_ENTRY_HEIGHT = 41 contrebasse@3: local MENU_ENTRY_WIDTH = 147 contrebasse@3: local MENU_ENTRY_ICON_RATIO = 40/48 contrebasse@2: contrebasse@0: local numActiveEntries = 0 contrebasse@0: local menuEntries = {} contrebasse@0: contrebasse@3: -- Button hovering contrebasse@5: local function btnEntered(btn) contrebasse@20: if btn.numMakable and btn.numMakable>0 then contrebasse@5: btn.textureHighlight:Show() contrebasse@5: end contrebasse@3: contrebasse@20: GameTooltip:SetOwner(btn,"ANCHOR_LEFT") contrebasse@5: GameTooltip:SetHyperlink(btn.reagentLink) contrebasse@5: GameTooltip:Show() contrebasse@31: if btn.spellLink then contrebasse@31: A.tooltipRecipe:SetOwner(GameTooltip) contrebasse@31: A.tooltipRecipe:SetHyperlink(btn.spellLink) contrebasse@31: A.tooltipRecipe:Show() contrebasse@31: A.tooltipRecipe:ClearAllPoints() contrebasse@31: A.tooltipRecipe:SetPoint("TOPRIGHT",GameTooltip,"BOTTOMRIGHT") contrebasse@20: end contrebasse@3: end contrebasse@5: local function btnLeft(btn) contrebasse@5: btn.textureHighlight:Hide() contrebasse@5: GameTooltip:Hide() contrebasse@5: A.tooltipRecipe:Hide() contrebasse@3: end contrebasse@3: local function createMenuEntry() contrebasse@3: local btn = CreateFrame("Button", nil, MenuFrame, "SecureActionButtonTemplate") contrebasse@3: table.insert(menuEntries,btn) contrebasse@3: contrebasse@3: btn:Hide() contrebasse@3: btn:SetSize(MENU_ENTRY_WIDTH,MENU_ENTRY_HEIGHT) contrebasse@3: btn:SetFrameStrata("DIALOG") contrebasse@3: contrebasse@3: -- Set its position contrebasse@3: if #menuEntries>1 then contrebasse@3: btn:SetPoint("TOP",menuEntries[#menuEntries-1],"BOTTOM",0,-2) contrebasse@2: else contrebasse@3: btn:SetPoint("TOPLEFT",MenuFrame,"TOPLEFT",24,-79) contrebasse@2: end contrebasse@3: contrebasse@3: local icon = btn:CreateTexture(nil,"BACKGROUND") contrebasse@3: icon:SetPoint("TOPLEFT") contrebasse@3: icon:SetSize(39,39) contrebasse@3: btn.icon = icon contrebasse@3: contrebasse@3: local itemNameBG = btn:CreateTexture(nil,"BACKGROUND") contrebasse@3: itemNameBG:SetTexture("Interface\\QuestFrame\\UI-QuestItemNameFrame") contrebasse@3: itemNameBG:SetSize(128,64) contrebasse@3: itemNameBG:SetPoint("LEFT",icon,"RIGHT",-10,0) contrebasse@3: contrebasse@3: local itemName = btn:CreateFontString(nil,"BACKGROUND","GameFontHighlight") contrebasse@3: itemName:SetSize(90,36) contrebasse@3: itemName:SetPoint("LEFT",itemNameBG,"LEFT",15,0) contrebasse@3: itemName:SetJustifyH("LEFT") contrebasse@3: itemName:SetWordWrap(true) contrebasse@3: itemName:SetNonSpaceWrap(false) contrebasse@3: btn.itemName = itemName contrebasse@3: contrebasse@3: local textureHighlight = btn:CreateTexture(nil,"BORDER") contrebasse@3: textureHighlight:Hide() contrebasse@3: textureHighlight:SetTexture("Interface\\BUTTONS\\CheckButtonHilight") contrebasse@3: textureHighlight:SetBlendMode("ADD") contrebasse@3: textureHighlight:SetAllPoints(icon) contrebasse@3: btn.textureHighlight = textureHighlight contrebasse@5: contrebasse@5: local countDetail = btn:CreateFontString(nil,"ARTWORK","NumberFontNormal") contrebasse@5: countDetail:SetPoint("BOTTOMRIGHT",icon,"BOTTOMRIGHT",-1,1) contrebasse@5: countDetail:SetJustifyH("RIGHT") contrebasse@5: countDetail:SetJustifyV("BOTTOM") contrebasse@5: btn.countDetail = countDetail contrebasse@5: contrebasse@10: local resultNumber = btn:CreateFontString(nil,"ARTWORK","NumberFontNormal") contrebasse@11: resultNumber:SetPoint("TOPLEFT",icon,"TOPLEFT",1,-3) contrebasse@10: resultNumber:SetJustifyH("LEFT") contrebasse@10: resultNumber:SetJustifyV("TOP") contrebasse@11: resultNumber:SetFont("Fonts\\ARIALN.TTF", 12, "OUTLINE") contrebasse@10: btn.resultNumber = resultNumber contrebasse@10: contrebasse@20: btn:SetScript("OnEnter", btnEntered) contrebasse@20: btn:SetScript("OnLeave", btnLeft) contrebasse@3: contrebasse@3: return btn contrebasse@2: end contrebasse@1: contrebasse@3: local function menuCraftItem() contrebasse@3: action(itemID,reagentIndex,IsShiftKeyDown()) contrebasse@0: end contrebasse@0: contrebasse@40: local function WarnNotMakable(btn) contrebasse@40: A.Error("You do not have enough ["..btn.itemNameString.."] to craft ["..TitleText:GetText().."]") contrebasse@40: end contrebasse@40: contrebasse@40: -- Update counts and button actions contrebasse@19: function MenuFrame.updateCounts() contrebasse@3: local anyMakable contrebasse@0: for i=1,numActiveEntries do contrebasse@3: btn = menuEntries[i] contrebasse@3: local itemCount = GetItemCount(btn.reagentID) contrebasse@3: contrebasse@3: local numMakable = math.floor(itemCount/(btn.reagentsForOneRecipe or 1)) contrebasse@3: btn.countDetail:SetText(itemCount.."/"..(btn.reagentsForOneRecipe or 1)) contrebasse@3: contrebasse@3: if numMakable>0 then contrebasse@40: -- Set action contrebasse@40: if type(action)=="function" then contrebasse@40: btn:SetScript("PreClick",btn.action) contrebasse@40: btn:SetAttribute("type", nil) contrebasse@40: btn:SetAttribute("macrotext", nil) contrebasse@40: else --if type(action)=="string" then contrebasse@40: btn:SetScript("PreClick",nil) contrebasse@40: btn:SetAttribute("type", "macro") contrebasse@40: btn:SetAttribute("macrotext", btn.action..btn.itemNameString) contrebasse@40: end -- if contrebasse@40: contrebasse@3: anyMakable = true contrebasse@5: btn.countDetail:SetTextColor(1, 1, 1, 1) contrebasse@3: btn.icon:SetVertexColor(1,1,1); contrebasse@3: btn.itemName:SetTextColor(1,1,1,1) contrebasse@3: else contrebasse@5: -- Do not disable the button, to be able to show the tooltip contrebasse@40: -- Disable only the effects contrebasse@40: btn:SetScript("PreClick",WarnNotMakable) contrebasse@40: btn:SetAttribute("type", nil) contrebasse@40: btn:SetAttribute("macrotext", nil) contrebasse@40: contrebasse@5: btn.countDetail:SetTextColor(1, 0.1, 0.1, 1) contrebasse@3: btn.icon:SetVertexColor(0.5, 0.5, 0.5) contrebasse@3: btn.itemName:SetTextColor(1,1,1,0.5) contrebasse@3: end contrebasse@5: contrebasse@5: btn.numMakable = numMakable contrebasse@3: end contrebasse@3: contrebasse@5: local r,g,b = TitleText:GetTextColor() contrebasse@3: if anyMakable then contrebasse@3: itemIcon:SetVertexColor(1,1,1) contrebasse@5: TitleText:SetTextColor(r,g,b,1) contrebasse@3: else contrebasse@3: itemIcon:SetVertexColor(0.5, 0.5, 0.5) contrebasse@5: TitleText:SetTextColor(r,g,b,0.7) contrebasse@0: end contrebasse@0: end contrebasse@0: contrebasse@31: local function menuAddItem(action,itemID,reagent,spellLink) contrebasse@0: local btn contrebasse@0: -- Create a button only if necessary contrebasse@0: if numActiveEntries >= #menuEntries then contrebasse@3: btn = createMenuEntry() contrebasse@0: else contrebasse@0: btn = menuEntries[numActiveEntries+1] contrebasse@0: end contrebasse@0: contrebasse@3: -- Set text and icon contrebasse@35: local name, link, _, _, _, _, _, _, _, texture = GetItemInfo(reagent[1]) contrebasse@3: if name then contrebasse@3: btn.itemName:SetText(name) contrebasse@3: else contrebasse@34: --A.DEBUG("No item name : "..reagent[1]) contrebasse@5: return contrebasse@3: end contrebasse@0: contrebasse@3: if texture then contrebasse@3: btn.icon:SetTexture(texture) contrebasse@3: else contrebasse@34: --A.DEBUG("No item texture : "..reagent[1]) contrebasse@5: return contrebasse@3: end contrebasse@3: contrebasse@10: -- Set chance to have the item or the number of items created contrebasse@10: if reagent[3] then contrebasse@10: if reagent[3]<1 then contrebasse@10: btn.resultNumber:SetText((reagent[3]*100).."%") contrebasse@11: elseif reagent[4] and reagent[3]~=reagent[4] then contrebasse@11: btn.resultNumber:SetText(math.min(reagent[3],reagent[4]).."-"..math.max(reagent[3],reagent[4])) contrebasse@10: elseif reagent[3]>1 then contrebasse@10: btn.resultNumber:SetText(reagent[3]) contrebasse@10: end contrebasse@10: end contrebasse@10: contrebasse@3: -- Save params contrebasse@3: btn.itemID = itemID contrebasse@10: btn.reagentID = reagent[1] contrebasse@5: btn.reagentLink = link contrebasse@10: btn.reagentsForOneRecipe = reagent[2] contrebasse@31: btn.spellLink = spellLink contrebasse@40: btn.action = action contrebasse@40: btn.itemNameString = name contrebasse@0: contrebasse@3: btn:Show() contrebasse@0: contrebasse@2: -- Increase the entry number contrebasse@0: numActiveEntries = numActiveEntries + 1 contrebasse@34: contrebasse@34: -- Everything went well contrebasse@34: return true contrebasse@0: end -- function contrebasse@3: contrebasse@34: -- Function used on OnUpdate tu update the frame if there were errors the previous time contrebasse@34: local function reopen() contrebasse@34: -- Release OnUpdate frame (could conflict with BAG_UPDATE) contrebasse@34: MenuFrame:SetScript("OnUpdate",nil) contrebasse@34: contrebasse@34: -- reopen contrebasse@34: A.externalCraftWindow(MenuFrame.itemID,MenuFrame.superItemID) contrebasse@34: end contrebasse@34: contrebasse@3: -- Fill the window and open it contrebasse@33: function A.externalCraftWindow(itemID,superItemID) contrebasse@3: -- Do not open during combat contrebasse@3: if InCombatLockdown() then return end contrebasse@3: contrebasse@3: -- Save the tradeskill contrebasse@3: A.currentTradeSkill = GetTradeSkillLine() contrebasse@3: contrebasse@3: -- Close the previous menu contrebasse@3: MenuFrame:Hide() contrebasse@3: for i=1,numActiveEntries do contrebasse@3: menuEntries[i]:Hide() contrebasse@3: end contrebasse@3: numActiveEntries = 0 contrebasse@3: contrebasse@3: -- Fill the info of the reagent to make contrebasse@35: local name, link, quality, _, _, _, _, _, _, texture = GetItemInfo(itemID) contrebasse@3: SetPortraitToTexture(itemIcon, texture) contrebasse@3: TitleText:SetText(name) contrebasse@5: local color = ITEM_QUALITY_COLORS[quality] contrebasse@5: TitleText:SetTextColor(color.r, color.g, color.b) contrebasse@3: contrebasse@20: -- Save vars to show the tooltip later contrebasse@20: MenuFrame.reagentLink = link contrebasse@32: MenuFrame.spellLink = A.data[itemID].spellLink contrebasse@33: MenuFrame.itemID = itemID contrebasse@33: MenuFrame.superItemID = superItemID -- optional contrebasse@34: contrebasse@3: -- Loop over the available recipes contrebasse@34: MenuFrame.state = true contrebasse@3: for _,reagent in ipairs(A.data[itemID]) do contrebasse@29: if A.data[itemID].spell then contrebasse@29: -- Special spell contrebasse@39: MenuFrame.state = menuAddItem(A.data[itemID].spell,itemID,reagent,A.data[itemID].spellLink) and MenuFrame.state contrebasse@29: else contrebasse@29: -- Standard tradeskill spell UNTESTED contrebasse@39: MenuFrame.state = menuAddItem(A.craft,itemID,reagent) and MenuFrame.state contrebasse@29: end -- if contrebasse@3: end -- for contrebasse@3: contrebasse@3: MenuFrame:SetHeight(89 + numActiveEntries*(MENU_ENTRY_HEIGHT+2)) contrebasse@3: contrebasse@3: MenuFrame:ClearAllPoints() contrebasse@3: MenuFrame:SetPoint("TOPLEFT",TradeSkillFrame,"TOPRIGHT",-2,14) contrebasse@3: contrebasse@40: -- Update counts and set actions contrebasse@19: MenuFrame.updateCounts() contrebasse@3: contrebasse@3: MenuFrame:Show() contrebasse@34: contrebasse@34: if not MenuFrame.state then contrebasse@34: MenuFrame:SetScript("OnUpdate",reopen) contrebasse@34: end contrebasse@3: end