diff --git a/BearEmoteStatistics.lua b/BearEmoteStatistics.lua index cfa09cd..fce8892 100644 --- a/BearEmoteStatistics.lua +++ b/BearEmoteStatistics.lua @@ -1,40 +1,78 @@ +local FILTERED_BEAR_SENT_KEYS = {} +local FILTERED_BEAR_RECEIVED_KEYS = {} + +local function GetFallbackBearEmotePath() + return "Interface\\AddOns\\BearEmotes\\Emotes\\beargun.tga:28:28" +end + +local function BuildBearStatTextureString(fullEmotePath) + local animdata = BearEmotes_animation_metadata[fullEmotePath] + if animdata ~= nil then + return BearEmotes_BuildEmoteFrameStringWithDimensions(fullEmotePath, animdata, 0, 16, 16) + end + + local size = string.match(fullEmotePath, ":(.*)") + if size == nil then + return "|T" .. fullEmotePath .. ":16:16|t" + end + return "|T" .. string.gsub(fullEmotePath, size, "16:16") .. "|t" +end + +local function ApplyBearStatsFilter(searchText) + if searchText == nil or searchText == "" then + FILTERED_BEAR_SENT_KEYS = BearEmoteSentStatKeys + FILTERED_BEAR_RECEIVED_KEYS = BearEmoteRecievedStatKeys + return + end + + local pattern = "^.*" .. searchText:lower() .. ".*" + + FILTERED_BEAR_SENT_KEYS = {} + for i = 1, #BearEmoteSentStatKeys do + if string.find(BearEmoteSentStatKeys[i]:lower(), pattern) == 1 then + FILTERED_BEAR_SENT_KEYS[#FILTERED_BEAR_SENT_KEYS + 1] = BearEmoteSentStatKeys[i]; + end + end + + FILTERED_BEAR_RECEIVED_KEYS = {} + for i = 1, #BearEmoteRecievedStatKeys do + if string.find(BearEmoteRecievedStatKeys[i]:lower(), pattern) == 1 then + FILTERED_BEAR_RECEIVED_KEYS[#FILTERED_BEAR_RECEIVED_KEYS + 1] = BearEmoteRecievedStatKeys[i]; + end + end +end + function BearStatsScreen_OnLoad() - BearEmoteSentStatKeys = {} - local n = 0; local totalEmotesSent = 0; - for k,v in pairs(BearEmoteStatistics) do - if BearEmotes_defaultpack[k] ~= nil and v[2] > 0 then -- Only add if the emote still exsists - n=n+1; + for k, v in pairs(BearEmoteStatistics) do + if BearEmotes_defaultpack[k] ~= nil and v[2] > 0 then totalEmotesSent = totalEmotesSent + v[2]; - BearEmoteSentStatKeys[n]=k; + BearEmoteSentStatKeys[#BearEmoteSentStatKeys + 1] = k; end end BearStatsScreenSentListTitle:SetText("Sent " .. totalEmotesSent .. " emotes") - - --Sort the sent stats list by usage table.sort(BearEmoteSentStatKeys, function(left, right) return BearEmoteStatistics[left][2] > BearEmoteStatistics[right][2] end); BearEmoteRecievedStatKeys = {} - local n = 0; local totalEmotesSeen = 0; - for k,v in pairs(BearEmoteStatistics) do - if BearEmotes_defaultpack[k] ~= nil and v[3] > 0 then -- Only add if the emote still exsists - n=n+1; + for k, v in pairs(BearEmoteStatistics) do + if BearEmotes_defaultpack[k] ~= nil and v[3] > 0 then totalEmotesSeen = totalEmotesSeen + v[3]; - BearEmoteRecievedStatKeys[n]=k; + BearEmoteRecievedStatKeys[#BearEmoteRecievedStatKeys + 1] = k; end end - BearStatsScreenSeenListTitle:SetText("Seen " .. totalEmotesSeen .. " emotes") - --Sort the seen stats list by nr of times seen + BearStatsScreenSeenListTitle:SetText("Seen " .. totalEmotesSeen .. " emotes") table.sort(BearEmoteRecievedStatKeys, function(left, right) return BearEmoteStatistics[left][3] > BearEmoteStatistics[right][3] end); + ApplyBearStatsFilter(BearStatsScreen.searchBox and BearStatsScreen.searchBox:GetText() or "") + BearStatsScreen:SetBackdrop({ bgFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', edgeFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', @@ -46,44 +84,73 @@ function BearStatsScreen_OnLoad() right = 0, top = 0, bottom = 0 - } + } }) - BearStatsScreen.closeButton = CreateFrame('Button', "BearStatsCloseButton", BearStatsScreen, 'UIPanelCloseButtonNoScripts') - BearStatsScreen.closeButton:SetScript('OnClick', function() BearStatsScreen:Hide() end) - BearStatsScreen.closeButton:SetPoint('TOPRIGHT', 0, 2) + if not BearStatsScreen.closeButton then + BearStatsScreen.closeButton = CreateFrame('Button', "BearStatsCloseButton", BearStatsScreen, 'UIPanelCloseButtonNoScripts') + BearStatsScreen.closeButton:SetScript('OnClick', function() BearStatsScreen:Hide() end) + BearStatsScreen.closeButton:SetPoint('TOPRIGHT', 0, 2) + end local engineeringGemTexture = "Interface\\ItemSocketingFrame\\UI-EngineeringSockets"; - local emoteBorderTex = {tex=engineeringGemTexture, w=43, h=43, left=0.01562500, right=0.68750000, top=0.41210938, bottom=0.49609375, r=1, g=1, b=1, CBx=49, CBy=47, CBLeft=0.01562500, CBRight=0.78125000, CBTop=0.22070313, CBBottom=0.31250000, OBx=49, OBy=47, OBLeft=0.01562500, OBRight=0.78125000, OBTop=0.31640625, OBBottom=0.40820313}; - local topEmoteBorder = BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 1); - topEmoteBorder:SetTexture(emoteBorderTex.tex); - topEmoteBorder:SetWidth(emoteBorderTex.w * 2); - topEmoteBorder:SetHeight(emoteBorderTex.h * 2); - topEmoteBorder:SetTexCoord(emoteBorderTex.left, emoteBorderTex.right, emoteBorderTex.top, emoteBorderTex.bottom); - topEmoteBorder:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 128, -108) - topEmoteBorder:Show(); - - local topSentImagePath = BearEmotes_defaultpack[BearEmoteSentStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\1337.tga"; + local emoteBorderTex = {tex = engineeringGemTexture, w = 43, h = 43, left = 0.01562500, right = 0.68750000, top = 0.41210938, bottom = 0.49609375}; + + if not BearStatsScreen.topSentEmoteBorder then + BearStatsScreen.topSentEmoteBorder = BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 1); + BearStatsScreen.topSentEmoteBorder:SetTexture(emoteBorderTex.tex); + BearStatsScreen.topSentEmoteBorder:SetWidth(emoteBorderTex.w * 2); + BearStatsScreen.topSentEmoteBorder:SetHeight(emoteBorderTex.h * 2); + BearStatsScreen.topSentEmoteBorder:SetTexCoord(emoteBorderTex.left, emoteBorderTex.right, emoteBorderTex.top, emoteBorderTex.bottom); + BearStatsScreen.topSentEmoteBorder:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 128, -108) + BearStatsScreen.topSentEmoteBorder:Show(); + end + + if not BearStatsScreen.topSeenEmoteBorder then + BearStatsScreen.topSeenEmoteBorder = BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 1); + BearStatsScreen.topSeenEmoteBorder:SetTexture(emoteBorderTex.tex); + BearStatsScreen.topSeenEmoteBorder:SetWidth(emoteBorderTex.w * 2); + BearStatsScreen.topSeenEmoteBorder:SetHeight(emoteBorderTex.h * 2); + BearStatsScreen.topSeenEmoteBorder:SetTexCoord(emoteBorderTex.left, emoteBorderTex.right, emoteBorderTex.top, emoteBorderTex.bottom); + BearStatsScreen.topSeenEmoteBorder:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 384, -108) + BearStatsScreen.topSeenEmoteBorder:Show(); + end + + local topSentImagePath = BearEmotes_defaultpack[BearEmoteSentStatKeys[1]] or GetFallbackBearEmotePath(); local animdata = BearEmotes_animation_metadata[topSentImagePath] BearStatsScreen.topSentEmoteTexture = BearStatsScreen.topSentEmoteTexture or BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 2); - local topEmoteTexture = BearStatsScreen.topSentEmoteTexture - if animdata ~= nil then - topEmoteTexture:SetTexture(topSentImagePath); - topEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, 0)) + BearStatsScreen.topSentEmoteTexture:SetTexture(topSentImagePath); + BearStatsScreen.topSentEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, 0)) else local size = string.match(topSentImagePath, ":(.*)") if size then topSentImagePath = string.gsub(topSentImagePath, size, "") end + BearStatsScreen.topSentEmoteTexture:SetTexture(topSentImagePath); + end + BearStatsScreen.topSentEmoteTexture:SetWidth(70); + BearStatsScreen.topSentEmoteTexture:SetHeight(70); + BearStatsScreen.topSentEmoteTexture:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 128, -108) + BearStatsScreen.topSentEmoteTexture:Show(); - topEmoteTexture:SetTexture(topSentImagePath); + local topSeenImagePath = BearEmotes_defaultpack[BearEmoteRecievedStatKeys[1]] or GetFallbackBearEmotePath(); + animdata = BearEmotes_animation_metadata[topSeenImagePath] + BearStatsScreen.topSeenEmoteTexture = BearStatsScreen.topSeenEmoteTexture or BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 2); + if animdata ~= nil then + BearStatsScreen.topSeenEmoteTexture:SetTexture(topSeenImagePath); + BearStatsScreen.topSeenEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, 0)) + else + local size = string.match(topSeenImagePath, ":(.*)") + if size then + topSeenImagePath = string.gsub(topSeenImagePath, size, "") + end + BearStatsScreen.topSeenEmoteTexture:SetTexture(topSeenImagePath); end - - topEmoteTexture:SetWidth(70); - topEmoteTexture:SetHeight(70); - topEmoteTexture:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 128, -108) - topEmoteTexture:Show(); + BearStatsScreen.topSeenEmoteTexture:SetWidth(70); + BearStatsScreen.topSeenEmoteTexture:SetHeight(70); + BearStatsScreen.topSeenEmoteTexture:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 384, -108) + BearStatsScreen.topSeenEmoteTexture:Show(); if #BearEmoteSentStatKeys >= 1 and BearEmoteStatistics[BearEmoteSentStatKeys[1]][2] > 0 then BearStatsScreenTopSentText:SetText(BearEmoteSentStatKeys[1] .. " sent " .. BearEmoteStatistics[BearEmoteSentStatKeys[1]][2] .. "x") @@ -97,105 +164,74 @@ function BearStatsScreen_OnLoad() BearStatsScreenTopRecievedText:SetText("No emotes seen yet"); end - topEmoteBorder = BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 1); - topEmoteBorder:SetTexture(emoteBorderTex.tex); - topEmoteBorder:SetWidth(emoteBorderTex.w * 2); - topEmoteBorder:SetHeight(emoteBorderTex.h * 2); - topEmoteBorder:SetTexCoord(emoteBorderTex.left, emoteBorderTex.right, emoteBorderTex.top, emoteBorderTex.bottom); - topEmoteBorder:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 384, -108) - topEmoteBorder:Show(); - - local topSeenImagePath = BearEmotes_defaultpack[BearEmoteRecievedStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\1337.tga"; - local animdata = BearEmotes_animation_metadata[topSeenImagePath] - - BearStatsScreen.topSeenEmoteTexture = BearStatsScreen.topSeenEmoteTexture or BearStatsScreen:CreateTexture(nil, "BACKGROUND", nil, 2); - topEmoteTexture = BearStatsScreen.topSeenEmoteTexture; - - if animdata ~= nil then - topEmoteTexture:SetTexture(topSeenImagePath); - topEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, 0)) - else - local size = string.match(topSeenImagePath, ":(.*)") - if size then - topSeenImagePath = string.gsub(topSeenImagePath, size, "") - end - - topEmoteTexture:SetTexture(topSeenImagePath); + if not BearStatsScreen.searchBox then + BearStatsScreen.searchBox = CreateFrame("EditBox", "BearStatsSearchBox", BearStatsScreen, "InputBoxTemplate") + BearStatsScreen.searchBox:SetFrameStrata("DIALOG") + BearStatsScreen.searchBox:SetSize(150, 16) + BearStatsScreen.searchBox:SetAutoFocus(false) + BearStatsScreen.searchBox:SetText("") + BearStatsScreen.searchBox:SetPoint("TOPLEFT", 55, -185) + BearStatsScreen.searchBox:HookScript("OnTextChanged", function(editbox) + ApplyBearStatsFilter(editbox:GetText()); + BearStatsSentScrollBar_Update(); + BearStatsRecievedScrollBar_Update(); + end) end - topEmoteTexture:SetWidth(70); - topEmoteTexture:SetHeight(70); - topEmoteTexture:SetPoint('CENTER', BearStatsScreen, "TOPLEFT", 384, -108) - topEmoteTexture:Show(); - - --Instantiate the scroll list entries - for i=2, 17 do - local bearStatSentScrollEntry = CreateFrame('Button', "BearStatsSentEntry"..i, BearStatsScreen, 'BearStatsEntryTemplate') - bearStatSentScrollEntry:SetPoint("TOPLEFT", "BearStatsSentEntry"..(i-1), "BOTTOMLEFT", 0, 0); + if not BearStatsScreen.entriesInitialized then + for i = 2, 17 do + local bearStatSentScrollEntry = CreateFrame('Button', "BearStatsSentEntry" .. i, BearStatsScreen, 'BearStatsEntryTemplate') + bearStatSentScrollEntry:SetPoint("TOPLEFT", "BearStatsSentEntry" .. (i - 1), "BOTTOMLEFT", 0, 0); - local bearStatRecievedScrollEntry = CreateFrame('Button', "BearStatsRecievedEntry"..i, BearStatsScreen, 'BearStatsEntryTemplate') - bearStatRecievedScrollEntry:SetPoint("TOPLEFT", "BearStatsRecievedEntry"..(i-1), "BOTTOMLEFT", 0, 0); - --print("constructed BearStatsSentEntry" .. i .. " (parent BearStatsSentEntry" ..(i-1) ) + local bearStatRecievedScrollEntry = CreateFrame('Button', "BearStatsRecievedEntry" .. i, BearStatsScreen, 'BearStatsEntryTemplate') + bearStatRecievedScrollEntry:SetPoint("TOPLEFT", "BearStatsRecievedEntry" .. (i - 1), "BOTTOMLEFT", 0, 0); + end + BearStatsScreen.entriesInitialized = true end BearStatsScreen:Show() BearStatsSentScrollBar:Show() BearStatsRecievedScrollBar:Show() + BearStatsSentScrollBar_Update() + BearStatsRecievedScrollBar_Update() end function BearStatsSentScrollBar_Update() local nrOfItemsVisible = 17 - local lineplusoffset; -- an index into our data calculated from the scroll offset - - FauxScrollFrame_Update(BearStatsSentScrollBar,#BearEmoteSentStatKeys,nrOfItemsVisible,16); - for line=1, nrOfItemsVisible do - lineplusoffset = line + FauxScrollFrame_GetOffset(BearStatsSentScrollBar); - if lineplusoffset <= #BearEmoteSentStatKeys then - local cEmote = BearEmoteSentStatKeys[lineplusoffset]; - local fullEmotePath = BearEmotes_defaultpack[cEmote]; - local animdata = BearEmotes_animation_metadata[fullEmotePath] - local texturestr = nil - if animdata ~= nil then - texturestr = BearEmotes_BuildEmoteFrameStringWithDimensions(fullEmotePath, animdata, 0, 16, 16) + local filteredStatKeys = FILTERED_BEAR_SENT_KEYS or BearEmoteSentStatKeys + + FauxScrollFrame_Update(BearStatsSentScrollBar, #filteredStatKeys, nrOfItemsVisible, 16); + for line = 1, nrOfItemsVisible do + local lineplusoffset = line + FauxScrollFrame_GetOffset(BearStatsSentScrollBar); + if lineplusoffset <= #filteredStatKeys then + local cEmote = filteredStatKeys[lineplusoffset]; + local fullEmotePath = BearEmotes_defaultpack[cEmote]; + local texturestr = BuildBearStatTextureString(fullEmotePath) + + getglobal("BearStatsSentEntry" .. line):SetText("|cFFfce703" .. lineplusoffset .. ".|r " .. texturestr .. " |cFF00FF00" .. cEmote .. "|r sent: " .. BearEmoteStatistics[cEmote][2] .. "x"); + getglobal("BearStatsSentEntry" .. line):Show(); else - local size = string.match(fullEmotePath, ":(.*)") - texturestr = "|T"..string.gsub(fullEmotePath, size, "16:16").."|t" + getglobal("BearStatsSentEntry" .. line):Hide(); end - - getglobal("BearStatsSentEntry"..line):SetText("|cFFfce703" .. lineplusoffset ..".|r ".. texturestr .." " .. " |cFF00FF00"..cEmote.."|r sent: " .. BearEmoteStatistics[cEmote][2] .. "x"); - getglobal("BearStatsSentEntry"..line):Show(); - - else - getglobal("BearStatsSentEntry"..line):Hide(); - end end end function BearStatsRecievedScrollBar_Update() local nrOfItemsVisible = 17 - local lineplusoffset; -- an index into our data calculated from the scroll offset - - FauxScrollFrame_Update(BearStatsRecievedScrollBar,#BearEmoteRecievedStatKeys,nrOfItemsVisible,16); - for line=1, nrOfItemsVisible do - lineplusoffset = line + FauxScrollFrame_GetOffset(BearStatsRecievedScrollBar); - if lineplusoffset <= #BearEmoteRecievedStatKeys then - local cEmote = BearEmoteRecievedStatKeys[lineplusoffset]; - local fullEmotePath = BearEmotes_defaultpack[cEmote] - - local animdata = BearEmotes_animation_metadata[fullEmotePath] - local texturestr = nil - if animdata ~= nil then - texturestr = BearEmotes_BuildEmoteFrameStringWithDimensions(fullEmotePath, animdata, 0, 16, 16) + local filteredStatKeys = FILTERED_BEAR_RECEIVED_KEYS or BearEmoteRecievedStatKeys + + FauxScrollFrame_Update(BearStatsRecievedScrollBar, #filteredStatKeys, nrOfItemsVisible, 16); + for line = 1, nrOfItemsVisible do + local lineplusoffset = line + FauxScrollFrame_GetOffset(BearStatsRecievedScrollBar); + if lineplusoffset <= #filteredStatKeys then + local cEmote = filteredStatKeys[lineplusoffset]; + local fullEmotePath = BearEmotes_defaultpack[cEmote] + local texturestr = BuildBearStatTextureString(fullEmotePath) + + getglobal("BearStatsRecievedEntry" .. line):SetText("|cFFfce703" .. lineplusoffset .. ".|r " .. texturestr .. " |cFF00FF00" .. cEmote .. "|r seen: " .. BearEmoteStatistics[cEmote][3] .. "x"); + getglobal("BearStatsRecievedEntry" .. line):Show(); else - local size = string.match(fullEmotePath, ":(.*)") - texturestr = "|T"..string.gsub(fullEmotePath, size, "16:16").."|t" + getglobal("BearStatsRecievedEntry" .. line):Hide(); end - - getglobal("BearStatsRecievedEntry"..line):SetText("|cFFfce703" .. lineplusoffset ..".|r ".. texturestr .." " .. " |cFF00FF00"..cEmote.."|r seen: " .. BearEmoteStatistics[cEmote][3] .. "x"); - getglobal("BearStatsRecievedEntry"..line):Show(); - - else - getglobal("BearStatsRecievedEntry"..line):Hide(); - end - end -end \ No newline at end of file + end +end diff --git a/BearEmotes.lua b/BearEmotes.lua index 4075237..1bda1b9 100644 --- a/BearEmotes.lua +++ b/BearEmotes.lua @@ -1,6 +1,14 @@ local LDB = LibStub("LibDataBroker-1.1") local LDBIcon = LibStub("LibDBIcon-1.0") local LibDD = LibStub:GetLibrary("LibUIDropDownMenu-4.0") +local isMidnight = (select(4, GetBuildInfo()) >= 120000) +local InChatMessagingLockdown = (C_ChatInfo and C_ChatInfo.InChatMessagingLockdown) or function() + return false +end +local issecretvalue = issecretvalue or function() + return false +end +local addonName, addonTable = ... BearEmoticons_Settings = { ["CHAT_MSG_COMMUNITIES_CHANNEL"] = true, -- 1 @@ -61,6 +69,7 @@ local origsettings = { ["ENABLE_CLICKABLEEMOTES"] = true, ["ENABLE_AUTOCOMPLETE"] = true, ["ENABLE_ANIMATEDEMOTES"] = true, + ["AUTOCOMPLETE_CONFIRM_WITH_TAB"] = false, ["FAVEMOTES"] = { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -68,6 +77,13 @@ local origsettings = { } }; +local accept_stat_updates = false +local iconregistered = false +local autocompleteInited = false +local Broker_BearEmotes +local BearEmotes_N_CHATFRAMES = 0 +local _G = getfenv(0) + local function BearEmotes_MinimapButton_OnClick(btn) if IsShiftKeyDown() then BearStatsScreen_OnLoad(); @@ -245,7 +261,7 @@ function BearEmoticons_LoadMiniMapDropdown(self, level, menuList) end function BearEmoticons_Dropdown_OnClick(self, arg1, arg2, arg3) - if (ACTIVE_CHAT_EDIT_BOX ~= nil) then + if (ACTIVE_CHAT_EDIT_BOX ~= nil) and not InChatMessagingLockdown() then ACTIVE_CHAT_EDIT_BOX:Insert(self.value); end end @@ -260,13 +276,39 @@ function SendMail(recipient, subject, msg, ...) end end -local scm = SendChatMessage; -function SendChatMessage(msg, ...) - if msg ~= nil then - if BearEmoticons_Settings["ENABLE_CLICKABLEEMOTES"] then - msg = BearEmotes_Message_StripEscapes(msg) +if isMidnight then + EventRegistry:RegisterCallback( + "ChatFrame.OnEditBoxPreSendText", + function(self, editBox) + if not BearEmoticons_Settings["ENABLE_CLICKABLEEMOTES"] then + return + end + + local msg = editBox:GetText() + if not msg or issecretvalue(msg) or msg:match("^%s*$") then + return + end + + local newMsg = BearEmotes_Message_StripEscapes(msg) + if newMsg ~= msg then + if InChatMessagingLockdown() then + print("Can't send emotes during combat - Midnight messaging restrictions in effect.") + return + end + editBox:SetText(newMsg) + end + end, + addonTable + ) +else + local scm = C_ChatInfo.SendChatMessage; + function C_ChatInfo.SendChatMessage(msg, ...) + if msg ~= nil then + if BearEmoticons_Settings["ENABLE_CLICKABLEEMOTES"] then + msg = BearEmotes_Message_StripEscapes(msg) + end + scm(msg, ...); end - scm(msg, ...); end end @@ -334,11 +376,6 @@ function BearEmoticons_MessageFilter(self, event, message, ...) return false, message, ... end -local accept_stat_updates = false; -local iconregistered = false -local autocompleteInited = false -local Broker_BearEmotes -local _G = getfenv(0) function BearEmoticons_OnEvent(self, event, ...) if (event == "ADDON_LOADED" and select(1, ...) == "BearEmotes") then for k, v in pairs(origsettings) do @@ -347,7 +384,8 @@ function BearEmoticons_OnEvent(self, event, ...) end end - BearEmotesAnimatorUpdateFrame = CreateFrame("Frame", "BearEmotesAnimator_EventFrame", UIParent) + BearEmotesUpdateFrame = CreateFrame("Frame", "BearEmotes_EventFrame", UIParent) + BearEmotesUpdateFrame:SetScript('OnUpdate', BearEmotes_Update) BearEmoticons_EnableAnimatedEmotes(BearEmoticons_Settings["ENABLE_ANIMATEDEMOTES"]) -- layout is BearEmoteStatistics[emote] = {nrTimesAutoCompleted, nrTimesSent, nrTimesSeen} @@ -356,6 +394,7 @@ function BearEmoticons_OnEvent(self, event, ...) BearEmoticons_UpdateChatFilters(); BearEmoticons_SetLargeEmotes(BearEmoticons_Settings["LARGEEMOTES"]); BearEmoticons_SetClickableEmotes(BearEmoticons_Settings["ENABLE_CLICKABLEEMOTES"]); + BearEmoticons_InitChannelSettings(); -- TODO: Waiting 1 second is kinda arbitrary, find a nicer solution. -- We don't accept Emote stat updates before ElvUI has posted it's chat history @@ -377,9 +416,72 @@ function BearEmoticons_OnEvent(self, event, ...) end BearEmoticons_SetMinimapButton(BearEmoticons_Settings["MINIMAPBUTTON"]) - + AllBearEmoteNames = {}; BearEmoticons_SetAutoComplete(BearEmoticons_Settings["ENABLE_AUTOCOMPLETE"]) + elseif (event == "ADDON_LOADED" and select(1, ...) == "WIM" and BearEmoticons_Settings["ENABLE_AUTOCOMPLETE"]) then + local module = WIM.CreateModule("BearEmotes", true); + function module:OnWindowCreated(win) + local editbox = win.widgets.msg_box + editbox:SetScript("OnKeyDown", editbox:GetScript("OnKeyDown") or function() end) + + local suggestionList = AllBearEmoteNames; + local maxButtonCount = 20; + local autocompletesettings = { + perWord = true, + activationChar = ':', + closingChar = ':', + minChars = 2, + fuzzyMatch = true, + onSuggestionApplied = function(suggestion) + BearUpdateEmoteStats(suggestion, true, false, false); + end, + renderSuggestionFN = BearEmoticons_RenderSuggestionFN, + suggestionBiasFN = function(suggestion, text) + if BearEmoteStatistics[suggestion] ~= nil then + return BearEmoteStatistics[suggestion][1] * 5 + end + return 0; + end, + interceptOnEnterPressed = true, + addSpace = true, + useTabToConfirm = BearEmoticons_Settings["AUTOCOMPLETE_CONFIRM_WITH_TAB"], + useArrowButtons = true, + } + + SetupAutoComplete(editbox, suggestionList, maxButtonCount, autocompletesettings); + end + end +end + +function BearEmoticons_InitChannelSettings() + local channels = { + "CHAT_MSG_GUILD", + "CHAT_MSG_PARTY", + "CHAT_MSG_PARTY_LEADER", + "CHAT_MSG_PARTY_GUIDE", + "CHAT_MSG_RAID", + "CHAT_MSG_RAID_LEADER", + "CHAT_MSG_RAID_WARNING", + "CHAT_MSG_SAY", + "CHAT_MSG_YELL", + "CHAT_MSG_WHISPER", + "CHAT_MSG_WHISPER_INFORM", + "CHAT_MSG_CHANNEL", + "CHAT_MSG_BN_WHISPER", + "CHAT_MSG_BN_WHISPER_INFORM", + "CHAT_MSG_BN_CONVERSATION", + "CHAT_MSG_INSTANCE_CHAT", + "CHAT_MSG_INSTANCE_CHAT_LEADER", + "MAIL" + } + + for i = 1, #channels do + local channel = channels[i]; + local frame = getglobal("BearEmoticonsOptionsControlsPanel" .. channel); + if frame ~= nil then + frame:SetChecked(BearEmoticons_Settings[channel]); + end end end @@ -404,9 +506,13 @@ function BearEmoticons_RenderSuggestionFN(text) end local function setAllBearFav(value) - for n, _ in ipairs(BearEmoticons_Settings["FAVEMOTES"]) do + for n, category in ipairs(BearEmotes_dropdown_options) do BearEmoticons_Settings["FAVEMOTES"][n] = value; - getglobal("favCheckButton_" .. BearEmotes_dropdown_options[n][1] .. "Bear"):SetChecked(value); + + local checkbox = getglobal("favCheckButton_" .. category[1] .. "Bear"); + if checkbox ~= nil then + checkbox:SetChecked(value); + end end end @@ -437,31 +543,71 @@ function BearEmoticons_OptionsWindow_OnShow(self) getglobal("$autocompleteUseTabToComplete").tooltipText = "This will disable cycling the selected suggestion with tab, the arrow keys will still work."; - favall = CreateFrame("CheckButton", "favall_GlobalNameBear", BearEmoticonsOptionsControlsPanel, "UIPanelButtonTemplate"); + if favframe_GlobalNameBear ~= nil then + for index, category in ipairs(BearEmotes_dropdown_options) do + local checkbox = getglobal("favCheckButton_" .. category[1] .. "Bear"); + if checkbox ~= nil then + checkbox:SetChecked(BearEmoticons_Settings["FAVEMOTES"][index]); + end + end + return + end + + local favall = CreateFrame("CheckButton", "favall_GlobalNameBear", BearEmoticonsOptionsControlsPanel, "UIPanelButtonTemplate"); favall:SetWidth(85); - favall:SetScript("OnClick", function(self, arg1) + favall:SetScript("OnClick", function() setAllBearFav(true); end) - favall:SetPoint("TOPLEFT", 17, -350); favall:SetText("Check all"); favall.tooltip = "Check all boxes below."; - favnone = CreateFrame("CheckButton", "favall_GlobalNameBear", BearEmoticonsOptionsControlsPanel, "UIPanelButtonTemplate"); + local favnone = CreateFrame("CheckButton", "favnone_GlobalNameBear", BearEmoticonsOptionsControlsPanel, "UIPanelButtonTemplate"); favnone:SetWidth(85); - favnone:SetScript("OnClick", function(self, arg1) + favnone:SetScript("OnClick", function() setAllBearFav(false); end) - favnone:SetPoint("TOPLEFT", 130, -350); favnone:SetText("Check none"); favnone.tooltip = "Uncheck all boxes below."; - favnone = CreateFrame("CheckButton", "favnone_GlobalNameBear", favall_GlobalName, "UIRadioButtonTemplate"); - - favframe = CreateFrame("Frame", "favframe_GlobalNameBear", favall_GlobalName); + local favframe = CreateFrame("Frame", "favframe_GlobalNameBear", favall_GlobalNameBear); favframe:SetPoint("TOPLEFT", 0, -24); favframe:SetSize(590, 175); + + local first = true; + local itemcnt = 0; + local anchor; + for index, category in ipairs(BearEmotes_dropdown_options) do + local favCheckButton = CreateFrame( + "CheckButton", + "favCheckButton_" .. category[1] .. "Bear", + favframe_GlobalNameBear, + "ChatConfigCheckButtonTemplate" + ); + + if first then + first = false; + favCheckButton:SetPoint("TOPLEFT", 0, 0); + else + favCheckButton:SetParent(getglobal("favCheckButton_" .. anchor .. "Bear")); + if ((itemcnt % 10) ~= 0) then + favCheckButton:SetPoint("TOPLEFT", 0, -16); + else + favCheckButton:SetPoint("TOPLEFT", 110, 9 * 16); + end + end + + itemcnt = itemcnt + 1; + anchor = category[1]; + + getglobal(favCheckButton:GetName() .. "Text"):SetText(category[1]); + favCheckButton:SetChecked(BearEmoticons_Settings["FAVEMOTES"][index]); + favCheckButton.tooltip = "Checked boxes will show in the dropdown list."; + favCheckButton:SetScript("OnClick", function(button) + BearEmoticons_Settings["FAVEMOTES"][index] = button:GetChecked() and true or false; + end); + end end function BearEmoticons_SetMinimapButton(state) @@ -481,8 +627,8 @@ end function BearEmoticons_SetConfirmWithTab(state) BearEmoticons_Settings["AUTOCOMPLETE_CONFIRM_WITH_TAB"] = state; - for i=1, NUM_CHAT_WINDOWS do - local frame = _G["ChatFrame"..i] + for _, frameName in pairs(CHAT_FRAMES) do + local frame = _G[frameName] local editbox = frame.editBox; if editbox ~= nil and editbox.settings ~= nil then @@ -501,15 +647,31 @@ end function BearEmoticons_EnableAnimatedEmotes(state) BearEmoticons_Settings["ENABLE_ANIMATEDEMOTES"] = state; - if(state) then - BearEmotesAnimatorUpdateFrame:SetScript('OnUpdate', BearEmotesAnimator_OnUpdate); - else - BearEmotesAnimatorUpdateFrame:SetScript('OnUpdate', nil); +end + +function BearEmotes_Update(self, elapsed) + local nChatFrames = #CHAT_FRAMES; + if nChatFrames ~= BearEmotes_N_CHATFRAMES then + BearEmotes_N_CHATFRAMES = nChatFrames + BearEmotes_SetupChatFrames(); + end + + if BearEmoticons_Settings["ENABLE_ANIMATEDEMOTES"] then + BearEmotesAnimator_OnUpdate(self, elapsed); + end +end + +function BearEmotes_SetupChatFrames() + for _, frameName in pairs(CHAT_FRAMES) do + local frame = _G[frameName] + + frame:HookScript("OnHyperlinkEnter", BearEmoticons_OnHyperlinkEnter) + frame:HookScript("OnHyperlinkLeave", BearEmoticons_OnHyperlinkLeave) end end --pass false or nil to leave a value as is, otherwise it gets incremented by one {nrTimesAutoCompleted, nrTimesSent, nrTimesSeen} -local function BearUpdateEmoteStats(emote, nrTimesAutoCompleted, nrTimesSent, nrTimesSeen) +function BearUpdateEmoteStats(emote, nrTimesAutoCompleted, nrTimesSent, nrTimesSeen) if BearEmoteStatistics[emote] == nil then BearEmoteStatistics[emote] = {0, 0, 0}; @@ -530,7 +692,7 @@ function BearEmoticons_SetAutoComplete(state) if BearEmoticons_Settings["ENABLE_AUTOCOMPLETE"] and not autocompleteInited then AllBearEmoteNames = {}; - local i = 0; + local i = 1; for k, v in pairs(BearEmotes_defaultpack) do --Some values in emoticons don't have a corresponding key in BearEmotes_defaultpack --we need to filter these out because we don't have an emote to show for these @@ -553,8 +715,8 @@ function BearEmoticons_SetAutoComplete(state) --Sort the list alphabetically table.sort(AllBearEmoteNames) - for i=1, NUM_CHAT_WINDOWS do - local frame = _G["ChatFrame"..i] + for _, frameName in pairs(CHAT_FRAMES) do + local frame = _G[frameName] local editbox = frame.editBox; local suggestionList = AllBearEmoteNames; @@ -619,3 +781,55 @@ function BearEmoticons_SetType(chattype, state) BearEmoticons_Settings[chattype] = state; BearEmoticons_UpdateChatFilters(); end + +function BearEmoticons_RegisterPack(name, newEmoticons, pack) + for k, v in pairs(newEmoticons) do + BearEmotes_emoticons[k] = v + end + + for k, v in pairs(pack) do + BearEmotes_defaultpack[k] = v + end +end + +BearEmotes = BearEmotes or {}; +function BearEmotes:AddCategory(name, emotes) + local category = {name}; + + for _, emote in ipairs(emotes) do + table.insert(category, emote); + end + + local nextCategoryIndex = (#BearEmotes_dropdown_options + 1); + BearEmotes_dropdown_options[nextCategoryIndex] = category; + BearEmoticons_Settings["FAVEMOTES"][nextCategoryIndex] = true; +end + +function BearEmotes:AddEmote(id, name, path) + BearEmotes_defaultpack[id] = path; + BearEmotes_emoticons[name] = id; +end + +BearEmotes_HoverMessageInfo = nil; +function BearEmoticons_OnHyperlinkEnter(frame, link, message, fontstring, ...) + local linkType, linkContent = link:match("^([^:]+):(.+)") + if (linkType == "tel") then + BearEmotes_HoverMessageInfo = fontstring and fontstring.messageInfo or nil; + + GameTooltip:SetOwner(frame, "ANCHOR_CURSOR"); + GameTooltip:SetText(linkContent, 255, 210, 0); + GameTooltip:Show(); + end +end + +function BearEmoticons_OnHyperlinkLeave(frame, ...) + GameTooltip:Hide() + BearEmotes_HoverMessageInfo = nil +end + +local oldsethyperlink = ItemRefTooltip.SetHyperlink +function ItemRefTooltip:SetHyperlink(link) + if (string.sub(link, 1, 3) ~= "tel") then + oldsethyperlink(self, link) + end +end diff --git a/BearEmotes.toc b/BearEmotes.toc index d2dbd1e..a113154 100644 --- a/BearEmotes.toc +++ b/BearEmotes.toc @@ -1,9 +1,10 @@ -## Interface: 100207 -## Title: |TInterface\Addons\BearEmotes\Emotes\BearGigaChad:0|tBear Emotes|TInterface\Addons\BearEmotes\Emotes\BearLaugh:0|t +## Interface: 120001 +## Title: |TInterface\Addons\BearEmotes\Emotes\beargun:0|tBear Emotes|TInterface\Addons\BearEmotes\Emotes\bearlaugh:0|t +## IconTexture: Interface\AddOns\BearEmotes\Emotes\beargun.tga ## Author: Mandl -## Notes: Adds Bear emotes to your chat. Built on top of TwitchEmotes +## Notes: Adds Bear emotes to your chat. Built on top of TwitchEmotes and updated for newer Midnight-compatible behavior. ## Version: v2 -## SavedVariables: BearEmoticons_Settings +## SavedVariables: BearEmoticons_Settings, BearEmoteStatistics ## OptionalDeps: LibStub, LibUIDropDownMenu Libs\load_libs.xml @@ -13,4 +14,4 @@ BearEmotesAnimator.lua BearEmotes.lua BearEmoteStatistics.lua UI\BearEmotes.xml -UI\BearEmoteStats.xml \ No newline at end of file +UI\BearEmoteStats.xml diff --git a/BearEmotesAnimator.lua b/BearEmotesAnimator.lua index acd9694..0510af4 100644 --- a/BearEmotesAnimator.lua +++ b/BearEmotesAnimator.lua @@ -1,13 +1,16 @@ local BEAREMOTES_TimeSinceLastUpdate = 0 local BEAREMOTES_T = 0; +local issecretvalue = issecretvalue or function() + return false +end function BearEmotesAnimator_OnUpdate(self, elapsed) if (BEAREMOTES_TimeSinceLastUpdate >= 0.033) then -- Update animated emotes in chat windows - for i = 1, NUM_CHAT_WINDOWS do - for _, visibleLine in ipairs(_G["ChatFrame" .. i].visibleLines) do - if(_G["ChatFrame" .. i]:IsShown() and visibleLine.messageInfo ~= BearEmotes_HoverMessageInfo) then + for _, frameName in pairs(CHAT_FRAMES) do + for _, visibleLine in ipairs(_G[frameName].visibleLines) do + if (_G[frameName]:IsShown() and visibleLine.messageInfo ~= BearEmotes_HoverMessageInfo) then BearEmotesAnimator_UpdateEmoteInFontString(visibleLine, 28, 28); end end @@ -27,69 +30,56 @@ function BearEmotesAnimator_OnUpdate(self, elapsed) end -- Update animated emotes in statistics screen - if(BearStatsScreen:IsVisible()) then - - local topSentImagePath = BearEmotes_defaultpack[BearEmoteSentStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\1337.tga"; + if (BearStatsScreen:IsVisible()) then + local topSentImagePath = BearEmotes_defaultpack[BearEmoteSentStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\beargun.tga:28:28"; local animdata = BearEmotes_animation_metadata[topSentImagePath:match("(Interface\\AddOns\\BearEmotes\\Emotes.-.tga)")] - - if(animdata ~= nil) then + if (animdata ~= nil) then local cFrame = BearEmotes_GetCurrentFrameNum(animdata) - BearStatsScreen.topSentEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, cFrame)) + BearStatsScreen.topSentEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, cFrame)) end - - local topSeenImagePath = BearEmotes_defaultpack[BearEmoteRecievedStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\1337.tga"; - local animdata = BearEmotes_animation_metadata[topSeenImagePath:match("(Interface\\AddOns\\BearEmotes\\Emotes.-.tga)")] - if(animdata ~= nil) then + local topSeenImagePath = BearEmotes_defaultpack[BearEmoteRecievedStatKeys[1]] or "Interface\\AddOns\\BearEmotes\\Emotes\\beargun.tga:28:28"; + animdata = BearEmotes_animation_metadata[topSeenImagePath:match("(Interface\\AddOns\\BearEmotes\\Emotes.-.tga)")] + if (animdata ~= nil) then local cFrame = BearEmotes_GetCurrentFrameNum(animdata) - BearStatsScreen.topSeenEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, cFrame)) + BearStatsScreen.topSeenEmoteTexture:SetTexCoord(BearEmotes_GetTexCoordsForFrame(animdata, cFrame)) end - - for line=1, 17 do - local sentEntry = getglobal("BearStatsSentEntry"..line) - local recievedEntry = getglobal("BearStatsRecievedEntry"..line) + for line = 1, 17 do + local sentEntry = getglobal("BearStatsSentEntry" .. line) + local recievedEntry = getglobal("BearStatsRecievedEntry" .. line) - if(sentEntry:IsVisible()) then + if (sentEntry:IsVisible()) then BearEmotesAnimator_UpdateEmoteInFontString(sentEntry, 16, 16); end - if(recievedEntry:IsVisible()) then + if (recievedEntry:IsVisible()) then BearEmotesAnimator_UpdateEmoteInFontString(recievedEntry, 16, 16); end end end - BEAREMOTES_TimeSinceLastUpdate = 0; end BEAREMOTES_T = BEAREMOTES_T + elapsed - BEAREMOTES_TimeSinceLastUpdate = BEAREMOTES_TimeSinceLastUpdate + - elapsed; + BEAREMOTES_TimeSinceLastUpdate = BEAREMOTES_TimeSinceLastUpdate + elapsed; end local function escpattern(x) return ( - --x:gsub('%%', '%%%%') - --:gsub('^%^', '%%^') - --:gsub('%$$', '%%$') - --:gsub('%(', '%%(') - --:gsub('%)', '%%)') - --:gsub('%.', '%%.') - --:gsub('%[', '%%[') - --:gsub('%]', '%%]') - --:gsub('%*', '%%*') - x:gsub('%+', '%%+') - :gsub('%-', '%%-') - --:gsub('%?', '%%?')) - ) + x:gsub('%+', '%%+') + :gsub('%-', '%%-') + ) end --- This will update the texture escapesequence of an animated emote --- if it exsists in the contents of the fontstring +-- This will update the texture escape sequence of an animated emote +-- if it exists in the contents of the fontstring. function BearEmotesAnimator_UpdateEmoteInFontString(fontstring, widthOverride, heightOverride) local txt = fontstring:GetText(); + if issecretvalue(txt) == true then + return + end if (txt ~= nil) then for emoteTextureString in txt:gmatch("(|TInterface\\AddOns\\BearEmotes\\Emotes.-|t)") do local imagepath = emoteTextureString:match("|T(Interface\\AddOns\\BearEmotes\\Emotes.-.tga).-|t") @@ -98,17 +88,18 @@ function BearEmotesAnimator_UpdateEmoteInFontString(fontstring, widthOverride, h if (animdata ~= nil) then local framenum = BearEmotes_GetCurrentFrameNum(animdata); local nTxt; - if(widthOverride ~= nil or heightOverride ~= nil) then - nTxt = txt:gsub(escpattern(emoteTextureString), - BearEmotes_BuildEmoteFrameStringWithDimensions( - imagepath, animdata, framenum, widthOverride, heightOverride)) + if (widthOverride ~= nil or heightOverride ~= nil) then + nTxt = txt:gsub( + escpattern(emoteTextureString), + BearEmotes_BuildEmoteFrameStringWithDimensions(imagepath, animdata, framenum, widthOverride, heightOverride) + ) else - nTxt = txt:gsub(escpattern(emoteTextureString), - BearEmotes_BuildEmoteFrameString( - imagepath, animdata, framenum)) + nTxt = txt:gsub( + escpattern(emoteTextureString), + BearEmotes_BuildEmoteFrameString(imagepath, animdata, framenum) + ) end - -- If we're updating a chat message we need to alter the messageInfo as wel if (fontstring.messageInfo ~= nil) then fontstring.messageInfo.message = nTxt end @@ -119,19 +110,25 @@ function BearEmotesAnimator_UpdateEmoteInFontString(fontstring, widthOverride, h end end - - function BearEmotes_GetAnimData(imagepath) return BearEmotes_animation_metadata[imagepath] end function BearEmotes_GetCurrentFrameNum(animdata) + if (animdata.pingpong) then + local vframen = math.floor((BEAREMOTES_T * animdata.framerate) % ((animdata.nFrames * 2) - 1)); + if vframen > animdata.nFrames then + vframen = animdata.nFrames - (vframen % animdata.nFrames) + end + return vframen + end + return math.floor((BEAREMOTES_T * animdata.framerate) % animdata.nFrames); end function BearEmotes_GetTexCoordsForFrame(animdata, framenum) - local fHeight = 1/animdata.nFrames - return 0, 1 ,framenum * fHeight, (framenum * fHeight) + fHeight + local fHeight = animdata.frameHeight; + return 0, 1, framenum * fHeight / animdata.imageHeight, ((framenum * fHeight) + fHeight) / animdata.imageHeight end function BearEmotes_BuildEmoteFrameString(imagepath, animdata, framenum) @@ -139,22 +136,20 @@ function BearEmotes_BuildEmoteFrameString(imagepath, animdata, framenum) local bottom = top + animdata.frameHeight; local emoteStr = "|T" .. imagepath .. ":" .. animdata.frameWidth .. ":" .. - animdata.frameHeight .. ":0:0:" .. animdata.imageWidth .. - ":" .. animdata.imageHeight .. ":0:" .. - animdata.frameWidth .. ":" .. top .. ":" .. bottom .. - "|t"; + animdata.frameHeight .. ":0:0:" .. animdata.imageWidth .. + ":" .. animdata.imageHeight .. ":0:" .. + animdata.frameWidth .. ":" .. top .. ":" .. bottom .. + "|t"; return emoteStr end -function BearEmotes_BuildEmoteFrameStringWithDimensions(imagepath, animdata, - framenum, framewidth, - frameheight) +function BearEmotes_BuildEmoteFrameStringWithDimensions(imagepath, animdata, framenum, framewidth, frameheight) local top = framenum * animdata.frameHeight; local bottom = top + animdata.frameHeight; local emoteStr = "|T" .. imagepath .. ":" .. framewidth .. ":" .. - frameheight .. ":0:0:" .. animdata.imageWidth .. ":" .. - animdata.imageHeight .. ":0:" .. animdata.frameWidth .. - ":" .. top .. ":" .. bottom .. "|t"; + frameheight .. ":0:0:" .. animdata.imageWidth .. ":" .. + animdata.imageHeight .. ":0:" .. animdata.frameWidth .. + ":" .. top .. ":" .. bottom .. "|t"; return emoteStr -end \ No newline at end of file +end diff --git a/DropdownItems.lua b/DropdownItems.lua index 654516a..8a1f1f0 100644 --- a/DropdownItems.lua +++ b/DropdownItems.lua @@ -1,9 +1,9 @@ -- 45 per menu max BearEmotes_dropdown_options = { [01] = { - "bearahegao", "bearangy", "bearawe", "bearbear", "bearbench", "bearbongo", "bearbonk", "bearbutterfly", "bearchefkiss", "bearchrist", "bearcomfy", "bearconcern", "bearcool", "Bearcopium", "bearcopter", "bearcringe", "bearcro", "bearcrodex", "bearcrosux", "bearcrown", "bearcry", "beardoubt", "beardrool", "bearfacepalm", "bearfingerguns", "bearfrench", "beargamer", "beargasp", "beargigachad", "beargiggle", "beargun", "bearhands", "bearheart", "bearhmmm", "bearhug", "bearhungry", "bearkekw", "bearknife", "bearlaugh", "bearlook", "bearmadge", "bearmoney", "bearmplus", "bearnotes", "bearnotlikethis" + "Bear Emotes 1", "bearahegao", "bearangy", "bearawe", "bearbear", "bearbench", "bearbongo", "bearbonk", "bearbutterfly", "bearchefkiss", "bearchrist", "bearcomfy", "bearconcern", "bearcool", "Bearcopium", "bearcopter", "bearcringe", "bearcro", "bearcrodex", "bearcrosux", "bearcrown", "bearcry", "beardoubt", "beardrool", "bearfacepalm", "bearfingerguns", "bearfrench", "beargamer", "beargasp", "beargigachad", "beargiggle", "beargun", "bearhands", "bearheart", "bearhmmm", "bearhug", "bearhungry", "bearkekw", "bearknife", "bearlaugh", "bearlook", "bearmadge", "bearmoney", "bearmplus", "bearnotes", "bearnotlikethis" }, [02] = { - "bearpepe", "bearpepega", "bearpi", "bearpikachu", "bearping", "bearpog", "bearpoint", "bearpopcorn", "bearpray", "bearprot", "bearrevenj", "bearriot", "bearsadcry", "bearsadge", "bearshrug", "bearsignsimp", "bearsigntoxicgreen", "bearsip", "bearsleep", "bearsmart", "bearspreadsheet", "bearsquint", "bearstonks", "bearstrong", "bearsus", "beartaunt", "bearthief", "bearthonk", "bearthumbsup", "beartimi", "beartinfoil", "beartrumpet", "bearupsidedown", "bearuwu", "bearwagonhappy", "bearwagonsad", "bearwallpeak", "bearwicked", "bearwings", "feelsbearman" + "Bear Emotes 2", "bearpepe", "bearpepega", "bearpi", "bearpikachu", "bearping", "bearpog", "bearpoint", "bearpopcorn", "bearpray", "bearprot", "bearrevenj", "bearriot", "bearsadcry", "bearsadge", "bearshrug", "bearsignsimp", "bearsigntoxicgreen", "bearsip", "bearsleep", "bearsmart", "bearspreadsheet", "bearsquint", "bearstonks", "bearstrong", "bearsus", "beartaunt", "bearthief", "bearthonk", "bearthumbsup", "beartimi", "beartinfoil", "beartrumpet", "bearupsidedown", "bearuwu", "bearwagonhappy", "bearwagonsad", "bearwallpeak", "bearwicked", "bearwings", "feelsbearman" } -}; \ No newline at end of file +}; diff --git a/UI/BearEmoteStats.xml b/UI/BearEmoteStats.xml index 3dbee80..395aeb6 100644 --- a/UI/BearEmoteStats.xml +++ b/UI/BearEmoteStats.xml @@ -75,6 +75,16 @@ + + + + + + + + + + @@ -165,4 +175,4 @@ - \ No newline at end of file + diff --git a/UI/BearEmotes.xml b/UI/BearEmotes.xml index 36c5d3b..0720d1a 100644 --- a/UI/BearEmotes.xml +++ b/UI/BearEmotes.xml @@ -88,7 +88,13 @@ Revert PowaBarSliderTemplate to inherit from OptionsSliderTemplate if it's fixed self.name = "BearEmotes"; - InterfaceOptions_AddCategory(self); + if SettingsPanel then + self:SetParent(SettingsPanel); + local category = Settings.RegisterCanvasLayoutCategory(self, self.name) + Settings.RegisterAddOnCategory(category) + else + InterfaceOptions_AddCategory(self); + end self:RegisterEvent("ADDON_LOADED"); self:SetScript("OnEvent",BearEmoticons_OnEvent); @@ -532,7 +538,8 @@ Revert PowaBarSliderTemplate to inherit from OptionsSliderTemplate if it's fixed - HideUIPanel(InterfaceOptionsFrame); + if InterfaceOptionsFrame then HideUIPanel(InterfaceOptionsFrame); end + if SettingsPanel then HideUIPanel(SettingsPanel); end HideUIPanel(GameMenuFrame); BearStatsScreen_OnLoad(); @@ -607,4 +614,4 @@ Revert PowaBarSliderTemplate to inherit from OptionsSliderTemplate if it's fixed - \ No newline at end of file + diff --git a/libs/Lib-EditBox-AutoComplete/Lib-EditBox-AutoComplete.lua b/libs/Lib-EditBox-AutoComplete/Lib-EditBox-AutoComplete.lua index da1e782..e4f33f2 100644 --- a/libs/Lib-EditBox-AutoComplete/Lib-EditBox-AutoComplete.lua +++ b/libs/Lib-EditBox-AutoComplete/Lib-EditBox-AutoComplete.lua @@ -28,364 +28,381 @@ local maximumButtonCount = 5; -- end -- end local old_ChatEdit_GetNextTellTarget = ChatEdit_GetNextTellTarget; +local InChatMessagingLockdown = (C_ChatInfo and C_ChatInfo.InChatMessagingLockdown) or function() + return false +end function SetupAutoComplete(editbox, valueList, maxButtonCount, settings) - editbox.old_OnEnterPressed = editbox.old_OnEnterPressed or - editbox:GetScript("OnEnterPressed") - editbox.old_OnEscPressed = editbox.old_OnEscPressed or - editbox:GetScript("OnEscapePressed") - editbox.old_OnTabPressed = editbox.old_OnTabPressed or - editbox:GetScript("OnTabPressed") - editbox.old_OnKeyDown = editbox.old_OnKeyDown or - editbox:GetScript("OnKeyDown") - editbox.old_OnEditFocusLost = editbox.old_OnEditFocusLost or - editbox:GetScript("OnEditFocusLost") - - local defaultsettings = { - perWord = false, - activationChar = '', - closingChar = '', - minChars = 0, - fuzzyMatch = false, - onSuggestionApplied = nil, - renderSuggestionFN = nil, - suggestionBiasFN = nil, - interceptOnEnterPressed = false, - addSpace = false, - useTabToConfirm = false, - useArrowButtons = false - } - - editbox.settings = defaultsettings; - - if settings ~= nil then - for k, v in pairs(settings) do editbox.settings[k] = v end - end - - editbox.valueList = valueList or {} - editbox.buttonCount = maxButtonCount or 10; - editbox.addHighlightedText = true - - EditBoxAutoCompleteBox:SetScript("OnHide", function(self) + editbox.old_OnEnterPressed = editbox.old_OnEnterPressed or + editbox:GetScript("OnEnterPressed") + editbox.old_OnEscPressed = editbox.old_OnEscPressed or + editbox:GetScript("OnEscapePressed") + editbox.old_OnTabPressed = editbox.old_OnTabPressed or + editbox:GetScript("OnTabPressed") + editbox.old_OnKeyDown = editbox.old_OnKeyDown or + editbox:GetScript("OnKeyDown") + editbox.old_OnEditFocusLost = editbox.old_OnEditFocusLost or + editbox:GetScript("OnEditFocusLost") + + local defaultsettings = { + perWord = false, + activationChar = '', + closingChar = '', + minChars = 0, + fuzzyMatch = false, + onSuggestionApplied = nil, + renderSuggestionFN = nil, + suggestionBiasFN = nil, + interceptOnEnterPressed = false, + addSpace = false, + useTabToConfirm = false, + useArrowButtons = false + } + + editbox.settings = defaultsettings; + + if settings ~= nil then + for k, v in pairs(settings) do editbox.settings[k] = v end + end + + editbox.valueList = valueList or {} + editbox.buttonCount = maxButtonCount or 10; + editbox.addHighlightedText = true + + EditBoxAutoCompleteBox:SetScript("OnHide", function(self) ChatEdit_GetNextTellTarget = old_ChatEdit_GetNextTellTarget; - BearEmotesResumeElvUIHistory(self.parent); - end); - - -- This should happen once globally, not for each autocomplete textbox - EditBoxAutoCompleteBox.mouseInside = false; - EditBoxAutoCompleteBox:SetScript("OnEnter", function(self) - EditBoxAutoCompleteBox.mouseInside = true; - end); - EditBoxAutoCompleteBox:SetScript("OnLeave", function(self) - EditBoxAutoCompleteBox.mouseInside = false; - end); - - editbox:HookScript("OnTabPressed", function(editbox) - if (editbox.settings.useTabToConfirm) then - EditBoxAutoComplete_OnEnterPressed(editbox) - else - EditBoxAutoComplete_IncrementSelection(editbox, IsShiftKeyDown()); - end - end); - - if (settings.useArrowButtons) then - editbox:SetScript("OnKeyDown", function(editbox, key) - - if (EditBoxAutoCompleteBox:IsShown() and (EditBoxAutoCompleteBox.parent == editbox)) then - if key == "TAB" then - ChatEdit_GetNextTellTarget = function() - return "", ""; - end - end - end - - if key == "ENTER" then - EditBoxAutoComplete_OnEnterPressed(editbox) - end - - if EditBoxAutoComplete_OnArrowPressed(editbox, key) then - BearEmotesPauseElvUIHistory(editbox); - else - editbox.old_OnKeyDown(editbox, key) - end - - end); - end - - editbox:HookScript("OnTextChanged", function(editbox, changedByUser) - EditBoxAutoComplete_OnTextChanged(editbox, changedByUser) - end) - - editbox:HookScript("OnChar", function(editbox, char) - - if (char == editbox.settings.closingChar and - editbox:GetUTF8CursorPosition() == #editbox:GetText() and - editbox:GetUTF8CursorPosition() > 1) then - - EditBoxAutoComplete_OnEnterPressed(editbox) - else - EditBoxAutoComplete_OnChar(editbox); - end - - end) - - editbox:SetScript("OnEditFocusLost", function(editbox) - if not EditBoxAutoCompleteBox.mouseInside then - EditBoxAutoComplete_HideIfAttachedTo(editbox) - EditBox_ClearHighlight(editbox) - editbox.old_OnEditFocusLost(editbox) - end - end) - - editbox:SetScript("OnEscapePressed", function(editbox) - if not EditBoxAutoComplete_OnEscapePressed(editbox) then - editbox.old_OnEscPressed(editbox) - - if AceGUI then - AceGUI:ClearFocus(editbox.obj) - else - editbox:ClearFocus() - end - end - end) + BearEmotesResumeElvUIHistory(self.parent); + end); + + -- This should happen once globally, not for each autocomplete textbox + EditBoxAutoCompleteBox.mouseInside = false; + EditBoxAutoCompleteBox:SetScript("OnEnter", function(self) + EditBoxAutoCompleteBox.mouseInside = true; + end); + EditBoxAutoCompleteBox:SetScript("OnLeave", function(self) + EditBoxAutoCompleteBox.mouseInside = false; + end); + + editbox:HookScript("OnTabPressed", function(editbox) + if (editbox.settings.useTabToConfirm) then + EditBoxAutoComplete_OnEnterPressed(editbox) + else + EditBoxAutoComplete_IncrementSelection(editbox, IsShiftKeyDown()); + end + end); + + if (settings.useArrowButtons) then + editbox:SetScript("OnKeyDown", function(editbox, key) + + if (EditBoxAutoCompleteBox:IsShown() and (EditBoxAutoCompleteBox.parent == editbox)) then + if key == "TAB" then + ChatEdit_GetNextTellTarget = function() + return "", ""; + end + end + end + + if key == "ENTER" then + EditBoxAutoComplete_OnEnterPressed(editbox) + end + + if EditBoxAutoComplete_OnArrowPressed(editbox, key) then + BearEmotesPauseElvUIHistory(editbox); + else + if editbox.old_OnKeyDown ~= nil then + editbox.old_OnKeyDown(editbox, key) + end + end + + end); + end + + editbox:HookScript("OnTextChanged", function(editbox, changedByUser) + local isRestricted, lockdownReason = InChatMessagingLockdown() + if not isRestricted then + EditBoxAutoComplete_OnTextChanged(editbox, changedByUser) + end + end) + + editbox:HookScript("OnChar", function(editbox, char) + + if (char == editbox.settings.closingChar and + editbox:GetUTF8CursorPosition() == #editbox:GetText() and + editbox:GetUTF8CursorPosition() > 1) then + + EditBoxAutoComplete_OnEnterPressed(editbox) + else + EditBoxAutoComplete_OnChar(editbox); + end + + end) + + editbox:SetScript("OnEditFocusLost", function(editbox) + if not EditBoxAutoCompleteBox.mouseInside then + EditBoxAutoComplete_HideIfAttachedTo(editbox) + EditBox_ClearHighlight(editbox) + editbox.old_OnEditFocusLost(editbox) + end + end) + + editbox:SetScript("OnEscapePressed", function(editbox) + if not EditBoxAutoComplete_OnEscapePressed(editbox) then + editbox.old_OnEscPressed(editbox) + + if AceGUI then + AceGUI:ClearFocus(editbox.obj) + else + editbox:ClearFocus() + end + end + end) end --todo: rename function BearEmotesPauseElvUIHistory(editbox) - if editbox.historyLines then - -- If we captured the arrowkeys and ElvUI added historyLines to this editbox - -- we save the historyLines and set the ElvUI var to nil - -- ElvUI hooks onto the onKeyDown event, temporarily removing the historyLines - -- prevents the chat editbox's content by being replaced by elvui when this hook runs - -- we restore the historyLines when the autocomplete dialog closes - - -- print("Will back up " .. #editbox.historyLines .. " lines") - editbox.PreservedHistoryLines = editbox.historyLines - editbox.historyLines = nil - end + if editbox.historyLines then + -- If we captured the arrowkeys and ElvUI added historyLines to this editbox + -- we save the historyLines and set the ElvUI var to nil + -- ElvUI hooks onto the onKeyDown event, temporarily removing the historyLines + -- prevents the chat editbox's content by being replaced by elvui when this hook runs + -- we restore the historyLines when the autocomplete dialog closes + + -- print("Will back up " .. #editbox.historyLines .. " lines") + editbox.PreservedHistoryLines = editbox.historyLines + editbox.historyLines = nil + end end --todo: rename function BearEmotesResumeElvUIHistory(editbox) - if editbox ~= nil and editbox.PreservedHistoryLines ~= nil then - -- print("restored " .. #editbox.PreservedHistoryLines .. " lines") - editbox.historyLines = editbox.PreservedHistoryLines; - end + if editbox ~= nil and editbox.PreservedHistoryLines ~= nil then + -- print("restored " .. #editbox.PreservedHistoryLines .. " lines") + editbox.historyLines = editbox.PreservedHistoryLines; + end end function EditBoxAutoComplete_GetAutoCompleteButton(index) - local buttonName = "EditBoxAutoCompleteButton" .. index; - if not _G[buttonName] then - local btn = CreateFrame("Button", buttonName, EditBoxAutoCompleteBox, - "EditBoxAutoCompleteButtonTemplate") - btn:SetPoint("TOPLEFT", EditBoxAutoComplete_GetAutoCompleteButton(index - 1), "BOTTOMLEFT", - 0, 0) - btn:SetScript("OnEnter", function(self) - EditBoxAutoCompleteBox.mouseInside = true; - end) - btn:SetScript("OnLeave", function(self) - EditBoxAutoCompleteBox.mouseInside = false; - end) - _G[buttonName] = btn - EditBoxAutoCompleteBox.existingButtonCount = max(index, - EditBoxAutoCompleteBox.existingButtonCount or - 1) - end - return _G[buttonName]; + local buttonName = "EditBoxAutoCompleteButton" .. index; + if not _G[buttonName] then + local btn = CreateFrame("Button", buttonName, EditBoxAutoCompleteBox, + "EditBoxAutoCompleteButtonTemplate") + btn:SetPoint("TOPLEFT", EditBoxAutoComplete_GetAutoCompleteButton(index - 1), "BOTTOMLEFT", + 0, 0) + btn:SetScript("OnEnter", function(self) + EditBoxAutoCompleteBox.mouseInside = true; + end) + btn:SetScript("OnLeave", function(self) + EditBoxAutoCompleteBox.mouseInside = false; + end) + _G[buttonName] = btn + EditBoxAutoCompleteBox.existingButtonCount = max(index, + EditBoxAutoCompleteBox.existingButtonCount or + 1) + end + return _G[buttonName]; end local function GetEditBoxAutoCompleteResults(text, valueList, fuzzyMatch) - local results = {} - local resultsCount = 1 - - pcall(function() - for i, value in ipairs(valueList) do - pcall(function() - - local pattern = text:lower(); - if fuzzyMatch then - pattern = "^.*" .. text:lower() .. ".*"; - end - - if string.find(value:lower(), pattern) == 1 then - results[resultsCount] = value; - resultsCount = resultsCount + 1 - end - end) - end - end) - - return results; + local results = {} + local resultsCount = 1 + + pcall(function() + for i, value in ipairs(valueList) do + pcall(function() + + local pattern = text:lower(); + if fuzzyMatch then + pattern = "^.*" .. text:lower() .. ".*"; + end + + if string.find(value:lower(), pattern) == 1 then + results[resultsCount] = value; + resultsCount = resultsCount + 1 + end + end) + end + end) + + return results; end function EditBoxAutoComplete_OnLoad(self) - self:SetBackdrop({ - bgFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', - edgeFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', - tile = true, - tileSize = 32, - edgeSize = 1, - insets = {left = 0, right = 0, top = 0, bottom = 0} - }) - AutoCompleteInstructions:SetText("|cffbbbbbb" .. PRESS_TAB .. "|r"); + self:SetBackdrop({ + bgFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', + edgeFile = 'Interface\\DialogFrame\\UI-DialogBox-Background-Dark', + tile = true, + tileSize = 32, + edgeSize = 1, + insets = {left = 0, right = 0, top = 0, bottom = 0} + }) + AutoCompleteInstructions:SetText("|cffbbbbbb" .. PRESS_TAB .. "|r"); end function EditBoxAutoComplete_Update(parent, text, cursorPosition) - local self = EditBoxAutoCompleteBox; - local attachPoint; - local origText = text - - if (not self:IsShown()) then - self.currentResults = {} - self.resultOffset = 0 - end - - if parent.settings.perWord then - local words = {} - local newSentence = "" - - for word in string.gmatch(parent:GetText(), "([^%s]+)") do - if word then table.insert(words, word) end - end - - if (string.sub(origText, -1) ~= " ") then - text = words[#words] -- Only use last word - else - text = "" - end - - end - - if (not text or text == "") then - EditBoxAutoComplete_HideIfAttachedTo(parent); - return; - end - - if (text ~= nil and parent.settings.activationChar ~= "") then - if (#text < 2 or string.sub(text, 1, 1) ~= - parent.settings.activationChar) then - EditBoxAutoComplete_HideIfAttachedTo(parent); - return; - else - text = string.sub(text, 2) -- Remove the activation char - end - end - - if (#text < parent.settings.minChars) then - EditBoxAutoComplete_HideIfAttachedTo(parent); - return; - end - - if (cursorPosition <= strlen(origText)) then - - self:SetParent(parent); - if (self.parent ~= parent) then - EditBoxAutoComplete_SetSelectedIndex(self, 0); - self.parentArrows = parent:GetAltArrowKeyMode(); - end - parent:SetAltArrowKeyMode(false); - local height = EditBoxAutoComplete_GetAutoCompleteButton(1):GetHeight() * maximumButtonCount - if (parent:GetBottom() - height <= (AUTOCOMPLETE_DEFAULT_Y_OFFSET + 10)) then -- 10 is a magic number from the offset of AutoCompleteButton1. - attachPoint = "ABOVE"; - else - attachPoint = "BELOW"; - end - if ((self.parent ~= parent) or (self.attachPoint ~= attachPoint)) then - if (attachPoint == "ABOVE") then - self:ClearAllPoints(); - self:SetPoint("BOTTOMLEFT", parent, "TOPLEFT", - parent.autoCompleteXOffset or 0, - parent.autoCompleteYOffset or - -AUTOCOMPLETE_DEFAULT_Y_OFFSET); - elseif (attachPoint == "BELOW") then - self:ClearAllPoints(); - self:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", - parent.autoCompleteXOffset or 0, - parent.autoCompleteYOffset or - AUTOCOMPLETE_DEFAULT_Y_OFFSET); - end - self.attachPoint = attachPoint; - end - - self.parent = parent; - local possibilities = GetEditBoxAutoCompleteResults(text, - parent.valueList, - parent.settings - .fuzzyMatch); - if (not possibilities) then possibilities = {}; end - - if (parent.settings.fuzzyMatch) then - -- We sort the possibilities here according to the following criteria - - -- 1. amount of characters in text vs the total in the possibility(match) (weight 100) - -- 2. how early in we match (weight 50) - -- 3. how many matching characters (case sensitive) (weight 25) - - local baseSortingFN = function(match, text) - local matchingChars = 0; - local cleanmatch = match:gsub("[" .. - parent.settings.activationChar .. - parent.settings.closingChar .. - "]", "") - local index, _, _ = - string.find(cleanmatch:lower(), text:lower()) - - -- Check how many characters actually match (case sensitive) - for i = index, index + #text do - if (string.sub(text, i - (index - 1), i - (index - 1)) == - string.sub(cleanmatch, i, i)) then - matchingChars = matchingChars + 1; - end - end - - return (25 * (1 - (matchingChars / #text))) + (50 * index) + - (25 * (1 - (#text / #cleanmatch))) - end - - if parent.settings.suggestionBiasFN ~= nil then - table.sort(possibilities, function(left, right) - return baseSortingFN(left, text) - - parent.settings.suggestionBiasFN(left, text) < - baseSortingFN(right, text) - - parent.settings.suggestionBiasFN(right, text) - end) - else - table.sort(possibilities, function(left, right) - return - baseSortingFN(left, text) < baseSortingFN(right, text) - end) - end - end - - self.currentResults = possibilities - EditBoxAutoComplete_UpdateResults(self, possibilities); - else - EditBoxAutoComplete_HideIfAttachedTo(parent); - end + local self = EditBoxAutoCompleteBox; + local attachPoint; + local origText = text + + if (not self:IsShown()) then + self.currentResults = {} + self.resultOffset = 0 + end + + if parent.settings.perWord then + local words = {} + local newSentence = "" + + for word in string.gmatch(parent:GetText(), "([^%s]+)") do + if word then table.insert(words, word) end + end + + if (string.sub(origText, -1) ~= " ") then + text = words[#words] -- Only use last word + else + text = "" + end + + end + + if (not text or text == "") then + EditBoxAutoComplete_HideIfAttachedTo(parent); + return; + end + + if (text ~= nil and parent.settings.activationChar ~= "") then + if (#text < 2 or string.sub(text, 1, 1) ~= + parent.settings.activationChar) then + EditBoxAutoComplete_HideIfAttachedTo(parent); + return; + else + text = string.sub(text, 2) -- Remove the activation char + end + end + + if (#text < parent.settings.minChars) then + EditBoxAutoComplete_HideIfAttachedTo(parent); + return; + end + + if (cursorPosition <= strlen(origText)) then + + self:SetParent(parent); + if (self.parent ~= parent) then + EditBoxAutoComplete_SetSelectedIndex(self, 0); + self.parentArrows = parent:GetAltArrowKeyMode(); + end + parent:SetAltArrowKeyMode(false); + local height = EditBoxAutoComplete_GetAutoCompleteButton(1):GetHeight() * maximumButtonCount + if (parent:GetBottom() - height <= (AUTOCOMPLETE_DEFAULT_Y_OFFSET + 10)) then -- 10 is a magic number from the offset of AutoCompleteButton1. + attachPoint = "ABOVE"; + else + attachPoint = "BELOW"; + end + if ((self.parent ~= parent) or (self.attachPoint ~= attachPoint)) then + if (attachPoint == "ABOVE") then + self:ClearAllPoints(); + self:SetPoint("BOTTOMLEFT", parent, "TOPLEFT", + parent.autoCompleteXOffset or 0, + parent.autoCompleteYOffset or + -AUTOCOMPLETE_DEFAULT_Y_OFFSET); + elseif (attachPoint == "BELOW") then + self:ClearAllPoints(); + self:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", + parent.autoCompleteXOffset or 0, + parent.autoCompleteYOffset or + AUTOCOMPLETE_DEFAULT_Y_OFFSET); + end + self.attachPoint = attachPoint; + end + + self.parent = parent; + local possibilities = GetEditBoxAutoCompleteResults(text, + parent.valueList, + parent.settings + .fuzzyMatch); + if (not possibilities) then possibilities = {}; end + + if (parent.settings.fuzzyMatch) then + -- We sort the possibilities here according to the following criteria + + -- 1. amount of characters in text vs the total in the possibility(match) (weight 100) + -- 2. how early in we match (weight 50) + -- 3. how many matching characters (case sensitive) (weight 25) + + local baseSortingFN = function(match, text) + local matchingChars = 0; + local cleanmatch = match; + local cleantext = text; + if(parent.settings.activationChar ~= '' or parent.settings.closingChar ~= '') then + cleanmatch = match:gsub("[" .. + parent.settings.activationChar .. + parent.settings.closingChar .. + "]", "") + cleantext = text:gsub("[" .. + parent.settings.activationChar .. + parent.settings.closingChar .. + "]", "") + end + + local index, _, _ = + string.find(cleanmatch:lower(), cleantext:lower()) + + -- Check how many characters actually match (case sensitive) + for i = index, index + #cleantext do + if (string.sub(cleantext, i - (index - 1), i - (index - 1)) == + string.sub(cleanmatch, i, i)) then + matchingChars = matchingChars + 1; + end + end + + return (25 * (1 - (matchingChars / #cleantext))) + (50 * index) + + (25 * (1 - (#cleantext / #cleanmatch))) + end + + if parent.settings.suggestionBiasFN ~= nil then + table.sort(possibilities, function(left, right) + return baseSortingFN(left, text) - + parent.settings.suggestionBiasFN(left, text) < + baseSortingFN(right, text) - + parent.settings.suggestionBiasFN(right, text) + end) + else + table.sort(possibilities, function(left, right) + return + baseSortingFN(left, text) < baseSortingFN(right, text) + end) + end + end + + self.currentResults = possibilities + EditBoxAutoComplete_UpdateResults(self, possibilities); + else + EditBoxAutoComplete_HideIfAttachedTo(parent); + end end function EditBoxAutoComplete_HideIfAttachedTo(parent) - local self = EditBoxAutoCompleteBox; - if (self.parent == parent) then - if (self.parentArrows) then - parent:SetAltArrowKeyMode(self.parentArrows); - self.parentArrows = nil; - end - BearEmotesResumeElvUIHistory(parent); - self.parent = nil; - - self:Hide(); - end + local self = EditBoxAutoCompleteBox; + if (self.parent == parent) then + if (self.parentArrows) then + parent:SetAltArrowKeyMode(self.parentArrows); + self.parentArrows = nil; + end + BearEmotesResumeElvUIHistory(parent); + self.parent = nil; + + self:Hide(); + end end function EditBoxAutoComplete_SetSelectedIndex(self, index) - self.selectedIndex = index; - for i = 1, maximumButtonCount do - EditBoxAutoComplete_GetAutoCompleteButton(i):UnlockHighlight(); - end - if (index ~= 0) then EditBoxAutoComplete_GetAutoCompleteButton(index):LockHighlight(); end + self.selectedIndex = index; + for i = 1, maximumButtonCount do + EditBoxAutoComplete_GetAutoCompleteButton(i):UnlockHighlight(); + end + if (index ~= 0) then EditBoxAutoComplete_GetAutoCompleteButton(index):LockHighlight(); end end function EditBoxAutoComplete_GetSelectedIndex(self) return self.selectedIndex; end @@ -393,235 +410,239 @@ function EditBoxAutoComplete_GetSelectedIndex(self) return self.selectedIndex; e function EditBoxAutoComplete_GetNumResults(self) return self.numResults; end function EditBoxAutoComplete_UpdateResults(self, results, indexOffset) - local indexOffset = indexOffset or 0 - local totalReturns = #results - indexOffset; - local numReturns = min(totalReturns, maximumButtonCount); - local maxWidth = 150; - - for i = 1, numReturns do - local button = EditBoxAutoComplete_GetAutoCompleteButton(i) - button.name = Ambiguate(results[i + indexOffset], "none"); - - if (self.parent.settings.renderSuggestionFN ~= nil) then - local text = self.parent.settings.renderSuggestionFN(results[i + - indexOffset]) - button:SetText(text); - else - button:SetText(results[i + indexOffset]); - end - - maxWidth = max(maxWidth, button:GetFontString():GetWidth() + 30); - button:Enable(); - button:Show(); - end - - for i = numReturns + 1, EditBoxAutoCompleteBox.existingButtonCount do - EditBoxAutoComplete_GetAutoCompleteButton(i):Hide(); - end - - if (numReturns > 0) then - maxWidth = max(maxWidth, AutoCompleteInstructions:GetStringWidth() + 30); - self:SetHeight(numReturns * AutoCompleteButton1:GetHeight() + 35); - self:SetWidth(maxWidth); - self:Show(); - EditBoxAutoComplete_SetSelectedIndex(self, 1); - else - self:Hide(); - end - - if (totalReturns > maximumButtonCount) then - local button = EditBoxAutoComplete_GetAutoCompleteButton(maximumButtonCount); - button:SetText(CONTINUED); - button:Disable(); - self.numResults = numReturns - 1; - else - self.numResults = numReturns; - end + local indexOffset = indexOffset or 0 + local totalReturns = #results - indexOffset; + local numReturns = min(totalReturns, maximumButtonCount); + local maxWidth = 150; + + for i = 1, numReturns do + local button = EditBoxAutoComplete_GetAutoCompleteButton(i) + button.name = Ambiguate(results[i + indexOffset], "none"); + + if (self.parent.settings.renderSuggestionFN ~= nil) then + local text = self.parent.settings.renderSuggestionFN(results[i + + indexOffset]) + button:SetText(text); + else + button:SetText(results[i + indexOffset]); + end + + maxWidth = max(maxWidth, button:GetFontString():GetWidth() + 30); + button:Enable(); + button:Show(); + end + + for i = numReturns + 1, EditBoxAutoCompleteBox.existingButtonCount do + EditBoxAutoComplete_GetAutoCompleteButton(i):Hide(); + end + + if (numReturns > 0) then + maxWidth = max(maxWidth, AutoCompleteInstructions:GetStringWidth() + 30); + self:SetHeight(numReturns * AutoCompleteButton1:GetHeight() + 35); + self:SetWidth(maxWidth); + self:Show(); + EditBoxAutoComplete_SetSelectedIndex(self, 1); + else + self:Hide(); + end + + if (totalReturns > maximumButtonCount) then + local button = EditBoxAutoComplete_GetAutoCompleteButton(maximumButtonCount); + button:SetText(CONTINUED); + button:Disable(); + self.numResults = numReturns - 1; + else + self.numResults = numReturns; + end end function EditBoxAutoComplete_IncrementSelection(editBox, up) - local autoComplete = EditBoxAutoCompleteBox; - autoComplete.resultOffset = autoComplete.resultOffset or 0; - - if (autoComplete:IsShown() and autoComplete.parent == editBox) then - local selectedIndex = EditBoxAutoComplete_GetSelectedIndex(autoComplete); - local numReturns = EditBoxAutoComplete_GetNumResults(autoComplete); - if (up) then - local nextNum = selectedIndex; - if selectedIndex == 1 then - if autoComplete.resultOffset > 0 then - autoComplete.resultOffset = autoComplete.resultOffset - 1 - EditBoxAutoComplete_UpdateResults(autoComplete, - autoComplete.currentResults, - autoComplete.resultOffset) - else - autoComplete.resultOffset = - #autoComplete.currentResults - numReturns - nextNum = numReturns - EditBoxAutoComplete_UpdateResults(autoComplete, - autoComplete.currentResults, - autoComplete.resultOffset) - end - else - nextNum = selectedIndex - 1; - end - EditBoxAutoComplete_SetSelectedIndex(autoComplete, nextNum); - else - -- print("Down " .. selectedIndex .. " " .. #autoComplete.currentResults .. " " .. (autoComplete.resultOffset or "NIL")) - local nextNum = selectedIndex; - if selectedIndex == numReturns then - if #autoComplete.currentResults - autoComplete.resultOffset > - numReturns then - autoComplete.resultOffset = autoComplete.resultOffset + 1 - EditBoxAutoComplete_UpdateResults(autoComplete, - autoComplete.currentResults, - autoComplete.resultOffset) - else - autoComplete.resultOffset = 0 - nextNum = 1 - EditBoxAutoComplete_UpdateResults(autoComplete, - autoComplete.currentResults, - autoComplete.resultOffset) - end - else - nextNum = selectedIndex + 1; - end - - EditBoxAutoComplete_SetSelectedIndex(autoComplete, nextNum) - end - return true; - end - return false; + local autoComplete = EditBoxAutoCompleteBox; + autoComplete.resultOffset = autoComplete.resultOffset or 0; + + if (autoComplete:IsShown() and autoComplete.parent == editBox) then + local selectedIndex = EditBoxAutoComplete_GetSelectedIndex(autoComplete); + local numReturns = EditBoxAutoComplete_GetNumResults(autoComplete); + if (up) then + local nextNum = selectedIndex; + if selectedIndex == 1 then + if autoComplete.resultOffset > 0 then + autoComplete.resultOffset = autoComplete.resultOffset - 1 + EditBoxAutoComplete_UpdateResults(autoComplete, + autoComplete.currentResults, + autoComplete.resultOffset) + else + autoComplete.resultOffset = + #autoComplete.currentResults - numReturns + nextNum = numReturns + EditBoxAutoComplete_UpdateResults(autoComplete, + autoComplete.currentResults, + autoComplete.resultOffset) + end + else + nextNum = selectedIndex - 1; + end + EditBoxAutoComplete_SetSelectedIndex(autoComplete, nextNum); + else + -- print("Down " .. selectedIndex .. " " .. #autoComplete.currentResults .. " " .. (autoComplete.resultOffset or "NIL")) + local nextNum = selectedIndex; + if selectedIndex == numReturns then + if #autoComplete.currentResults - autoComplete.resultOffset > + numReturns then + autoComplete.resultOffset = autoComplete.resultOffset + 1 + EditBoxAutoComplete_UpdateResults(autoComplete, + autoComplete.currentResults, + autoComplete.resultOffset) + else + autoComplete.resultOffset = 0 + nextNum = 1 + EditBoxAutoComplete_UpdateResults(autoComplete, + autoComplete.currentResults, + autoComplete.resultOffset) + end + else + nextNum = selectedIndex + 1; + end + + EditBoxAutoComplete_SetSelectedIndex(autoComplete, nextNum) + end + return true; + end + return false; end function EditBoxAutoComplete_OnTabPressed(editBox) - return EditBoxAutoComplete_IncrementSelection(editBox, IsShiftKeyDown()) + return EditBoxAutoComplete_IncrementSelection(editBox, IsShiftKeyDown()) end function EditBoxAutoComplete_OnArrowPressed(self, key) - if (key == "UP") then - return EditBoxAutoComplete_IncrementSelection(self, true); - elseif (key == "DOWN") then - return EditBoxAutoComplete_IncrementSelection(self, false); - end + if (key == "UP") then + return EditBoxAutoComplete_IncrementSelection(self, true); + elseif (key == "DOWN") then + return EditBoxAutoComplete_IncrementSelection(self, false); + end end function EditBoxAutoComplete_OnEnterPressed(self) - local autoComplete = EditBoxAutoCompleteBox; - if (autoComplete:IsShown() and (autoComplete.parent == self) and - (EditBoxAutoComplete_GetSelectedIndex(autoComplete) ~= 0)) then - - EditBoxAutoCompleteButton_OnClick( - EditBoxAutoComplete_GetAutoCompleteButton(EditBoxAutoComplete_GetSelectedIndex( - autoComplete))); - return true; - end - return false; + local isRestricted, lockdownReason = InChatMessagingLockdown() + if isRestricted then + return false; + end + local autoComplete = EditBoxAutoCompleteBox; + if (autoComplete:IsShown() and (autoComplete.parent == self) and + (EditBoxAutoComplete_GetSelectedIndex(autoComplete) ~= 0)) then + + EditBoxAutoCompleteButton_OnClick( + EditBoxAutoComplete_GetAutoCompleteButton(EditBoxAutoComplete_GetSelectedIndex( + autoComplete))); + return true; + end + return false; end function EditBoxAutoComplete_OnTextChanged(self, userInput) - maximumButtonCount = self.buttonCount; - if (userInput) then - EditBoxAutoComplete_Update(self, self:GetText(), - self:GetUTF8CursorPosition()); - end - if (self:GetText() == "") then - EditBoxAutoComplete_HideIfAttachedTo(self); - end + maximumButtonCount = self.buttonCount; + if (userInput) then + EditBoxAutoComplete_Update(self, self:GetText(), + self:GetUTF8CursorPosition()); + end + if (self:GetText() == "") then + EditBoxAutoComplete_HideIfAttachedTo(self); + end end function EditBoxAutoComplete_AddHighlightedText(editBox, text) - local editBoxText = editBox:GetText(); - local utf8Position = editBox:GetUTF8CursorPosition(); - local possibilities = GetEditBoxAutoCompleteResults(text); - - if (possibilities and possibilities[1]) then - -- We're going to be setting the text programatically which will clear the userInput flag on the editBox. So we want to manually update the dropdown before we change the text. - EditBoxAutoComplete_Update(editBox, editBoxText, utf8Position); - local newText = string.gsub(editBoxText, AUTOCOMPLETE_SIMPLE_REGEX, - string.format( - AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, - possibilities[1], string.match( - editBoxText, - AUTOCOMPLETE_SIMPLE_REGEX)), 1) - editBox:SetText(newText); - editBox:HighlightText(strlen(editBoxText), strlen(newText)); -- This won't work if there is more after the name, but we aren't enabling this for normal chat (yet). Please fix me when we do. - editBox:SetCursorPosition(strlen(editBoxText)); - end + local editBoxText = editBox:GetText(); + local utf8Position = editBox:GetUTF8CursorPosition(); + local possibilities = GetEditBoxAutoCompleteResults(text); + + if (possibilities and possibilities[1]) then + -- We're going to be setting the text programatically which will clear the userInput flag on the editBox. So we want to manually update the dropdown before we change the text. + EditBoxAutoComplete_Update(editBox, editBoxText, utf8Position); + local newText = string.gsub(editBoxText, AUTOCOMPLETE_SIMPLE_REGEX, + string.format( + AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, + possibilities[1], string.match( + editBoxText, + AUTOCOMPLETE_SIMPLE_REGEX)), 1) + editBox:SetText(newText); + editBox:HighlightText(strlen(editBoxText), strlen(newText)); -- This won't work if there is more after the name, but we aren't enabling this for normal chat (yet). Please fix me when we do. + editBox:SetCursorPosition(strlen(editBoxText)); + end end function EditBoxAutoComplete_OnChar(self) - local autoComplete = EditBoxAutoCompleteBox; - if (autoComplete:IsShown() and autoComplete.parent == self) then - if (self.addHighlightedText and self:GetUTF8CursorPosition() == - strlenutf8(self:GetText())) then - EditBoxAutoComplete_AddHighlightedText(self, self:GetText()); - return true; - end - end - - return false; + local autoComplete = EditBoxAutoCompleteBox; + if (autoComplete:IsShown() and autoComplete.parent == self) then + if (self.addHighlightedText and self:GetUTF8CursorPosition() == + strlenutf8(self:GetText())) then + EditBoxAutoComplete_AddHighlightedText(self, self:GetText()); + return true; + end + end + + return false; end function EditBoxAutoComplete_OnEditFocusLost(self) - EditBoxAutoComplete_HideIfAttachedTo(self); + EditBoxAutoComplete_HideIfAttachedTo(self); end function EditBoxAutoComplete_OnEscapePressed(self) - local autoComplete = EditBoxAutoCompleteBox; - if (autoComplete:IsShown() and autoComplete.parent == self) then - EditBoxAutoComplete_HideIfAttachedTo(self); - return true; - end - return false; + local autoComplete = EditBoxAutoCompleteBox; + if (autoComplete:IsShown() and autoComplete.parent == self) then + EditBoxAutoComplete_HideIfAttachedTo(self); + return true; + end + return false; end function EditBoxAutoCompleteButton_OnClick(self) - local autoComplete = self:GetParent(); - local editBox = autoComplete.parent; - local editBoxText = editBox:GetText(); - local newText; - - if (editBox.command) then - newText = editBox.command .. " " .. self.name; - else - newText = string.gsub(editBoxText, AUTOCOMPLETE_SIMPLE_REGEX, - string.format(AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, - self.name, string.match(editBoxText, - AUTOCOMPLETE_SIMPLE_REGEX)), - 1); - end - - if editBox.settings.perWord then - local words = {} - local newSentence = "" - - for word in string.gmatch(editBoxText, "([^%s]+)") do - table.insert(words, word) - end - - for i = 1, (#words - 1) do - newSentence = newSentence .. words[i] .. " " - end - - newSentence = newSentence .. newText - if (editBox.settings.addSpace) then - newSentence = newSentence .. " " - end - - editBox:SetText(newSentence); - -- When we change the text, we move to the end, so we'll be consistent and move to the end if we don't change it as well. - editBox:SetCursorPosition(strlen(newSentence)); - else - editBox:SetText(newText); - -- When we change the text, we move to the end, so we'll be consistent and move to the end if we don't change it as well. - editBox:SetCursorPosition(strlen(newText)); - end - - autoComplete:Hide(); - - if editBox.settings.onSuggestionApplied ~= nil then - editBox.settings.onSuggestionApplied(self.name); - end + local autoComplete = self:GetParent(); + local editBox = autoComplete.parent; + local editBoxText = editBox:GetText(); + local newText; + + if (editBox.command) then + newText = editBox.command .. " " .. self.name; + else + newText = string.gsub(editBoxText, AUTOCOMPLETE_SIMPLE_REGEX, + string.format(AUTOCOMPLETE_SIMPLE_FORMAT_REGEX, + self.name, string.match(editBoxText, + AUTOCOMPLETE_SIMPLE_REGEX)), + 1); + end + + if editBox.settings.perWord then + local words = {} + local newSentence = "" + + for word in string.gmatch(editBoxText, "([^%s]+)") do + table.insert(words, word) + end + + for i = 1, (#words - 1) do + newSentence = newSentence .. words[i] .. " " + end + + newSentence = newSentence .. newText + if (editBox.settings.addSpace) then + newSentence = newSentence .. " " + end + + editBox:SetText(newSentence); + -- When we change the text, we move to the end, so we'll be consistent and move to the end if we don't change it as well. + editBox:SetCursorPosition(strlen(newSentence)); + else + editBox:SetText(newText); + -- When we change the text, we move to the end, so we'll be consistent and move to the end if we don't change it as well. + editBox:SetCursorPosition(strlen(newText)); + end + + autoComplete:Hide(); + + if editBox.settings.onSuggestionApplied ~= nil then + editBox.settings.onSuggestionApplied(self.name); + end end diff --git a/libs/LibUIDropDownMenu/LibUIDropDownMenu.lua b/libs/LibUIDropDownMenu/LibUIDropDownMenu.lua index d289bca..908eba4 100644 --- a/libs/LibUIDropDownMenu/LibUIDropDownMenu.lua +++ b/libs/LibUIDropDownMenu/LibUIDropDownMenu.lua @@ -1,4 +1,4 @@ --- $Id: LibUIDropDownMenu.lua 91 2022-02-13 14:57:00Z arithmandar $ +-- $Id: LibUIDropDownMenu.lua 135 2024-02-05 16:50:14Z arithmandar $ -- ---------------------------------------------------------------------------- -- Localized Lua globals. -- ---------------------------------------------------------------------------- @@ -18,7 +18,7 @@ local GameTooltip_SetTitle, GameTooltip_AddInstructionLine, GameTooltip_AddNorma -- ---------------------------------------------------------------------------- local MAJOR_VERSION = "LibUIDropDownMenu-4.0" -local MINOR_VERSION = 90000 + tonumber(("$Rev: 91 $"):match("%d+")) +local MINOR_VERSION = 90000 + tonumber(("$Rev: 135 $"):match("%d+")) local LibStub = _G.LibStub @@ -27,17 +27,22 @@ local lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) if not lib then return end -- Determine WoW TOC Version -local WoWClassicEra, WoWClassicTBC, WoWRetail -local wowtocversion = select(4, GetBuildInfo()) -if wowtocversion < 20000 then +local WoWClassicEra, WoWClassicTBC, WoWWOTLKC, WoWRetail +local wowversion = select(4, GetBuildInfo()) +if wowversion < 20000 then WoWClassicEra = true -elseif wowtocversion > 19999 and wowtocversion < 90000 then +elseif wowversion < 30000 then WoWClassicTBC = true -else +elseif wowversion < 40000 then + WoWWOTLKC = true +elseif wowversion > 90000 then WoWRetail = true + +else + -- n/a end -if WoWClassicEra or WoWClassicTBC then +if WoWClassicEra or WoWClassicTBC or WoWWOTLKC then GameTooltip = _G.GameTooltip tooltip = GameTooltip else -- Retail @@ -47,11 +52,9 @@ else -- Retail end -- ////////////////////////////////////////////////////////////// -L_UIDROPDOWNMENU_MINBUTTONS = 8; +L_UIDROPDOWNMENU_MINBUTTONS = 8; -- classic only L_UIDROPDOWNMENU_MAXBUTTONS = 1; --- For Classic checkmarks, this is the additional padding that we give to the button text. -L_UIDROPDOWNMENU_CLASSIC_CHECK_PADDING = 4; -L_UIDROPDOWNMENU_MAXLEVELS = 2; +L_UIDROPDOWNMENU_MAXLEVELS = 3; L_UIDROPDOWNMENU_BUTTON_HEIGHT = 16; L_UIDROPDOWNMENU_BORDER_HEIGHT = 15; -- The current open menu @@ -66,10 +69,14 @@ L_UIDROPDOWNMENU_MENU_VALUE = nil; L_UIDROPDOWNMENU_SHOW_TIME = 2; -- Default dropdown text height L_UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = nil; +-- For Classic checkmarks, this is the additional padding that we give to the button text. +L_UIDROPDOWNMENU_CLASSIC_CHECK_PADDING = 4; +-- Default dropdown width padding +L_UIDROPDOWNMENU_DEFAULT_WIDTH_PADDING = 25; -- List of open menus L_OPEN_DROPDOWNMENUS = {}; -local L_DropDownList1, L_DropDownList2 +local L_DropDownList1, L_DropDownList2, L_DropDownList3 local delegateFrame = CreateFrame("FRAME"); delegateFrame:SetScript("OnAttributeChanged", function(self, attribute, value) @@ -107,50 +114,238 @@ function lib:UIDropDownMenu_InitializeHelper(frame) end frame:SetHeight(L_UIDROPDOWNMENU_BUTTON_HEIGHT * 2); end + +function lib:UIDropDownMenuButton_ShouldShowIconTooltip(self) + if self.Icon and (self.iconTooltipTitle or self.iconTooltipText) and (self.icon or self.mouseOverIcon) then + return GetMouseFocus() == self.Icon; + end + return false; +end + + -- ////////////////////////////////////////////////////////////// -- L_UIDropDownMenuButtonTemplate local function create_MenuButton(name, parent) + -- UIDropDownMenuButton Scripts BEGIN + local function button_OnEnter(self) + if ( self.hasArrow ) then + local level = self:GetParent():GetID() + 1; + local listFrame = _G["L_DropDownList"..level]; + if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint(1)) ~= self ) then + lib:ToggleDropDownMenu(self:GetParent():GetID() + 1, self.value, nil, nil, nil, nil, self.menuList, self, nil, self.menuListDisplayMode); + end + else + lib:CloseDropDownMenus(self:GetParent():GetID() + 1); + end + self.Highlight:Show(); + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then + lib:UIDropDownMenu_StopCounting(self:GetParent()); + end + -- To check: do we need special handle for classic since there is no UIDropDownMenuButton_ShouldShowIconTooltip()? + -- if ( self.tooltipTitle and not self.noTooltipWhileEnabled ) then + if ( self.tooltipTitle and not self.noTooltipWhileEnabled and not lib:UIDropDownMenuButton_ShouldShowIconTooltip(self)) then + if ( self.tooltipOnButton ) then + tooltip:SetOwner(self, "ANCHOR_RIGHT"); + GameTooltip_SetTitle(tooltip, self.tooltipTitle); + if self.tooltipInstruction then + GameTooltip_AddInstructionLine(tooltip, self.tooltipInstruction); + end + if self.tooltipText then + GameTooltip_AddNormalLine(tooltip, self.tooltipText, true); + end + if self.tooltipWarning then + GameTooltip_AddColoredLine(tooltip, self.tooltipWarning, RED_FONT_COLOR, true); + end + if self.tooltipBackdropStyle then + SharedTooltip_SetBackdropStyle(tooltip, self.tooltipBackdropStyle); + end + tooltip:Show(); + end + end + + if ( self.mouseOverIcon ~= nil ) then + self.Icon:SetTexture(self.mouseOverIcon); + self.Icon:Show(); + end + if (WoWRetail) then + GetValueOrCallFunction(self, "funcOnEnter", self); + if self.NewFeature then + self.NewFeature:Hide(); + end + end + end + + local function button_OnLeave(self) + self.Highlight:Hide(); + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then + lib:UIDropDownMenu_StartCounting(self:GetParent()); + end + + tooltip:Hide(); + + if ( self.mouseOverIcon ~= nil ) then + if ( self.icon ~= nil ) then + self.Icon:SetTexture(self.icon); + else + self.Icon:Hide(); + end + end + + if (WoWRetail) then + GetValueOrCallFunction(self, "funcOnLeave", self); + end + end + + local function button_OnClick(self, button) + local checked = self.checked; + if ( type (checked) == "function" ) then + checked = checked(self); + end + + if ( self.keepShownOnClick ) then + if not self.notCheckable then + if ( checked ) then + _G[self:GetName().."Check"]:Hide(); + _G[self:GetName().."UnCheck"]:Show(); + checked = false; + else + _G[self:GetName().."Check"]:Show(); + _G[self:GetName().."UnCheck"]:Hide(); + checked = true; + end + end + else + self:GetParent():Hide(); + end + + if ( type (self.checked) ~= "function" ) then + self.checked = checked; + end + + -- saving this here because func might use a dropdown, changing this self's attributes + local playSound = true; + if ( self.noClickSound ) then + playSound = false; + end + + local func = self.func; + if ( func ) then + func(self, self.arg1, self.arg2, checked, button); + else + return; + end + + if ( playSound ) then + PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON); + end + end + -- UIDropDownMenuButton Scripts END + + -- UIDropDownMenuButtonIcon Script BEGIN + local function icon_OnClick(self, button) + local buttonParent = self:GetParent() + if not buttonParent then + return + end + button_OnClick(buttonParent, button) + end + + local function icon_OnEnter(self) + local button = self:GetParent(); + if not button then + return; + end + + local shouldShowIconTooltip = lib:UIDropDownMenuButton_ShouldShowIconTooltip(button); + + if shouldShowIconTooltip then + tooltip:SetOwner(button, "ANCHOR_RIGHT"); + if button.iconTooltipTitle then + GameTooltip_SetTitle(tooltip, button.iconTooltipTitle); + end + if button.iconTooltipText then + GameTooltip_AddNormalLine(tooltip, button.iconTooltipText, true); + end + if button.iconTooltipBackdropStyle then + SharedTooltip_SetBackdropStyle(tooltip, button.iconTooltipBackdropStyle); + end + tooltip:Show(); + end + button_OnEnter(button); + end + + local function icon_OnLeave(self) + local button = self:GetParent(); + if not button then + return; + end + + button_OnLeave(button); + end + + local function icon_OnMouseUp(self, button) + if ( button == "LeftButton" ) then + icon_OnClick(self, button) + end + end + -- UIDropDownMenuButtonIcon Script END + + -- Button Frame local f = CreateFrame("Button", name, parent or nil) f:SetWidth(100) f:SetHeight(16) f:SetFrameLevel(f:GetParent():GetFrameLevel()+2) - f.Highlight = f:CreateTexture(name.."Highlight", "BACKGROUND") + f.Highlight = f:CreateTexture( name and (name.."Highlight") or nil, "BACKGROUND") f.Highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") f.Highlight:SetBlendMode("ADD") f.Highlight:SetAllPoints() f.Highlight:Hide() - f.Check = f:CreateTexture(name.."Check", "ARTWORK") + f.Check = f:CreateTexture( name and (name.."Check") or nil, "ARTWORK") f.Check:SetTexture("Interface\\Common\\UI-DropDownRadioChecks") f.Check:SetSize(16, 16) f.Check:SetPoint("LEFT", f, 0, 0) f.Check:SetTexCoord(0, 0.5, 0.5, 1) - f.UnCheck = f:CreateTexture(name.."UnCheck", "ARTWORK") + f.UnCheck = f:CreateTexture( name and (name.."UnCheck") or nil, "ARTWORK") f.UnCheck:SetTexture("Interface\\Common\\UI-DropDownRadioChecks") f.UnCheck:SetSize(16, 16) f.UnCheck:SetPoint("LEFT", f, 0, 0) f.UnCheck:SetTexCoord(0.5, 1, 0.5, 1) - f.Icon = f:CreateTexture(name.."Icon", "ARTWORK") - f.Icon:SetSize(16, 16) - f.Icon:SetPoint("RIGHT", f, 0, 0) - f.Icon:Hide() + -- Icon Texture + local fIcon + fIcon = f:CreateTexture( name and (name.."Icon") or nil, "ARTWORK") + fIcon:SetSize(16, 16) + fIcon:SetPoint("RIGHT", f, 0, 0) + fIcon:Hide() + if (WoWRetail) then + fIcon:SetScript("OnEnter", function(self) + icon_OnEnter(self) + end) + fIcon:SetScript("OnLeave", function(self) + icon_OnLeave(self) + end) + fIcon:SetScript("OnMouseUp", function(self, button) + icon_OnMouseUp(self, button) + end) + end + f.Icon = fIcon -- ColorSwatch local fcw - fcw = CreateFrame("Button", name.."ColorSwatch", f, BackdropTemplateMixin and DropDownMenuButtonMixin and "BackdropTemplate,ColorSwatchTemplate" or BackdropTemplateMixin and "BackdropTemplate" or nil) + fcw = CreateFrame("Button", name and (name.."ColorSwatch") or nil, f, BackdropTemplateMixin and DropDownMenuButtonMixin and "BackdropTemplate,ColorSwatchTemplate" or BackdropTemplateMixin and "BackdropTemplate" or nil) fcw:SetPoint("RIGHT", f, -6, 0) fcw:Hide() if not DropDownMenuButtonMixin then fcw:SetSize(16, 16) - fcw.SwatchBg = fcw:CreateTexture(name.."ColorSwatchSwatchBg", "BACKGROUND") + fcw.SwatchBg = fcw:CreateTexture( name and (name.."ColorSwatchSwatchBg") or nil, "BACKGROUND") fcw.SwatchBg:SetVertexColor(1, 1, 1) fcw.SwatchBg:SetWidth(14) fcw.SwatchBg:SetHeight(14) fcw.SwatchBg:SetPoint("CENTER", fcw, 0, 0) - local button1NormalTexture = fcw:CreateTexture(name.."ColorSwatchNormalTexture") + local button1NormalTexture = fcw:CreateTexture( name and (name.."ColorSwatchNormalTexture") or nil) button1NormalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") button1NormalTexture:SetAllPoints() fcw:SetNormalTexture(button1NormalTexture) @@ -171,12 +366,11 @@ local function create_MenuButton(name, parent) f.ColorSwatch = fcw -- ExpandArrow - local fea = CreateFrame("Button", name.."ExpandArrow", f) - + local fea = CreateFrame("Button", name and (name.."ExpandArrow") or nil, f) fea:SetSize(16, 16) fea:SetPoint("RIGHT", f, 0, 0) fea:Hide() - local button2NormalTexture = fea:CreateTexture(name.."ExpandArrowNormalTexture") + local button2NormalTexture = fea:CreateTexture( name and (name.."ExpandArrowNormalTexture") or nil) button2NormalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") button2NormalTexture:SetAllPoints() fea:SetNormalTexture(button2NormalTexture) @@ -203,13 +397,13 @@ local function create_MenuButton(name, parent) f.ExpandArrow = fea -- InvisibleButton - local fib = CreateFrame("Button", name.."InvisibleButton", f) + local fib = CreateFrame("Button", name and (name.."InvisibleButton") or nil, f) fib:Hide() fib:SetPoint("TOPLEFT", f, 0, 0) fib:SetPoint("BOTTOMLEFT", f, 0, 0) fib:SetPoint("RIGHT", fcw, "LEFT", 0, 0) fib:SetScript("OnEnter", function(self, motion) - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then lib:UIDropDownMenu_StopCounting(self:GetParent():GetParent()); end lib:CloseDropDownMenus(self:GetParent():GetParent():GetID() + 1); @@ -227,121 +421,36 @@ local function create_MenuButton(name, parent) if parent.tooltipWarning then GameTooltip_AddColoredLine(tooltip, parent.tooltipWarning, RED_FONT_COLOR, true); end + if parent.tooltipBackdropStyle then + SharedTooltip_SetBackdropStyle(tooltip, parent.tooltipBackdropStyle); + end tooltip:Show(); end end end) fib:SetScript("OnLeave", function(self, motion) - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then lib:UIDropDownMenu_StartCounting(self:GetParent():GetParent()); end tooltip:Hide(); end) f.invisibleButton = fib - - -- UIDropDownMenuButton Scripts - local function button_OnEnter(self) - if ( self.hasArrow ) then - local level = self:GetParent():GetID() + 1; - local listFrame = _G["L_DropDownList"..level]; - if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then - lib:ToggleDropDownMenu(self:GetParent():GetID() + 1, self.value, nil, nil, nil, nil, self.menuList, self); - end - else - lib:CloseDropDownMenus(self:GetParent():GetID() + 1); - end - self.Highlight:Show(); - if (WoWClassicEra or WoWClassicTBC) then - lib:UIDropDownMenu_StopCounting(self:GetParent()); - end - - if ( self.tooltipTitle and not self.noTooltipWhileEnabled ) then - if ( self.tooltipOnButton ) then - tooltip:SetOwner(self, "ANCHOR_RIGHT"); - GameTooltip_SetTitle(tooltip, self.tooltipTitle); - if self.tooltipText then - GameTooltip_AddNormalLine(tooltip, self.tooltipText, true); - end - tooltip:Show(); - end - end - - if ( self.mouseOverIcon ~= nil ) then - self.Icon:SetTexture(self.mouseOverIcon); - self.Icon:Show(); - end - if (WoWRetail) then - GetValueOrCallFunction(self, "funcOnEnter", self); - end - end - - local function button_OnLeave(self) - self.Highlight:Hide(); - if (WoWClassicEra or WoWClassicTBC) then - lib:UIDropDownMenu_StartCounting(self:GetParent()); - end - - tooltip:Hide(); - - if ( self.mouseOverIcon ~= nil ) then - if ( self.icon ~= nil ) then - self.Icon:SetTexture(self.icon); - else - self.Icon:Hide(); - end - end - - if (WoWRetail) then - GetValueOrCallFunction(self, "funcOnLeave", self); - end - end - - local function button_OnClick(self) - local checked = self.checked; - if ( type (checked) == "function" ) then - checked = checked(self); - end - - if ( self.keepShownOnClick ) then - if not self.notCheckable then - if ( checked ) then - _G[self:GetName().."Check"]:Hide(); - _G[self:GetName().."UnCheck"]:Show(); - checked = false; - else - _G[self:GetName().."Check"]:Show(); - _G[self:GetName().."UnCheck"]:Hide(); - checked = true; - end - end - else - self:GetParent():Hide(); - end - - if ( type (self.checked) ~= "function" ) then - self.checked = checked; - end - - -- saving this here because func might use a dropdown, changing this self's attributes - local playSound = true; - if ( self.noClickSound ) then - playSound = false; - end - - local func = self.func; - if ( func ) then - func(self, self.arg1, self.arg2, checked); - else - return; - end - - if ( playSound ) then - PlaySound(SOUNDKIT.U_CHAT_SCROLL_BUTTON); - end + + -- NewFeature + if (WoWRetail) then + local fnf = CreateFrame("Frame", name and (name.."NewFeature") or nil, f, "NewFeatureLabelTemplate"); + fnf:SetFrameStrata("HIGH"); + fnf:SetScale(0.8); + fnf:SetFrameLevel(100); + fnf:SetSize(1, 1); + fnf:Hide(); + + f.NewFeature = fnf; end - f:SetScript("OnClick", function(self, button, down) - button_OnClick(self, button, down) + -- MenuButton scripts + f:SetScript("OnClick", function(self, button) + button_OnClick(self, button) end) f:SetScript("OnEnter", function(self, motion) button_OnEnter(self) @@ -356,7 +465,7 @@ local function create_MenuButton(name, parent) self.invisibleButton:Show() end) - local text1 = f:CreateFontString(name.."NormalText") + local text1 = f:CreateFontString( name and (name.."NormalText") or nil) f:SetFontString(text1) text1:SetPoint("LEFT", f, -5, 0) f:SetNormalFontObject("GameFontHighlightSmallLeft") @@ -368,57 +477,73 @@ end -- ////////////////////////////////////////////////////////////// -- L_UIDropDownListTemplate -local BACKDROP_DIALOG_DARK = { +local function creatre_DropDownList(name, parent) + -- This has been removed from Backdrop.lua, so we added the definition here. + local BACKDROP_DIALOG_DARK = { bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, + tileEdge = true, tileSize = 32, edgeSize = 32, - insets = { left = 11, right = 12, top = 12, bottom = 9, }, -} --- This has been removed from Backdrop.lua, so we added the definition here. -local BACKDROP_TOOLTIP_16_16_5555 = { - bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", - edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, - tileEdge = true, - tileSize = 16, - edgeSize = 16, - insets = { left = 5, right = 5, top = 5, bottom = 5 }, -} - -local function creatre_DropDownList(name, parent) - local f = _G[name] or CreateFrame("Button", name) + insets = { left = 11, right = 12, top = 12, bottom = 11, }, + } + local BACKDROP_TOOLTIP_16_16_5555 = { + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, + tileEdge = true, + tileSize = 16, + edgeSize = 16, + insets = { left = 5, right = 5, top = 5, bottom = 5 }, + } + + local f = name and _G[name] or CreateFrame("Button", name) f:SetParent(parent or nil) f:Hide() f:SetFrameStrata("DIALOG") f:EnableMouse(true) - local fbd = _G[name.."Backdrop"] or CreateFrame("Frame", name.."Backdrop", f, BackdropTemplateMixin and "BackdropTemplate" or nil) + local fbd = name and _G[name.."Backdrop"] or CreateFrame("Frame", name and (name.."Backdrop") or nil, f, BackdropTemplateMixin and "DialogBorderDarkTemplate" or nil) fbd:SetAllPoints() - fbd:SetBackdrop(BACKDROP_DIALOG_DARK) + fbd.backdropInfo = BACKDROP_DIALOG_DARK f.Backdrop = fbd - local fmb = _G[name.."MenuBackdrop"] or CreateFrame("Frame", name.."MenuBackdrop", f, BackdropTemplateMixin and "BackdropTemplate" or nil) + local fmb = name and _G[name.."MenuBackdrop"] or CreateFrame("Frame", name and (name.."MenuBackdrop") or nil, f, TooltipBackdropTemplateMixin and "TooltipBackdropTemplate" or nil) fmb:SetAllPoints() - fmb:SetBackdrop(BACKDROP_TOOLTIP_16_16_5555) + fmb.backdropInfo = BACKDROP_TOOLTIP_16_16_5555 fmb:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b) fmb:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) f.MenuBackdrop = fmb - f.Button1 = _G[name.."Button1"] or create_MenuButton(name.."Button1", f) + f.Button1 = name and _G[name.."Button1"] or create_MenuButton(name and (name.."Button1") or nil, f) -- to replace the inherits of "UIDropDownMenuButtonTemplate" f.Button1:SetID(1) + + -- Checking if NewFeature exists or not + if (WoWRetail) then + if not f.Button1.NewFeature then + local fnf = CreateFrame("Frame", name and (name.."NewFeature") or nil, f, "NewFeatureLabelTemplate"); + fnf:SetFrameStrata("HIGH"); + fnf:SetScale(0.8); + fnf:SetFrameLevel(100); + fnf:SetSize(1, 1); + fnf:Hide(); + + f.Button1.NewFeature = fnf; + end + end + f:SetScript("OnClick", function(self) self:Hide() end) f:SetScript("OnEnter", function(self, motion) - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then lib:UIDropDownMenu_StopCounting(self, motion) end end) f:SetScript("OnLeave", function(self, motion) - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then lib:UIDropDownMenu_StartCounting(self, motion) end end) @@ -428,7 +553,7 @@ local function creatre_DropDownList(name, parent) lib:UIDropDownMenu_RefreshDropDownSize(self); self.shouldRefresh = false; end - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then if ( not self.showTimer or not self.isCounting ) then return; elseif ( self.showTimer < 0 ) then @@ -455,12 +580,13 @@ local function creatre_DropDownList(name, parent) if (not self.noResize) then self:SetWidth(self.maxWidth+25); end - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then self.showTimer = nil; end if ( self:GetID() > 1 ) then self.parent = _G["L_DropDownList"..(self:GetID() - 1)]; end + EventRegistry:TriggerEvent("UIDropDownMenu.Show", self); end) f:SetScript("OnHide", function(self) local id = self:GetID() @@ -468,6 +594,10 @@ local function creatre_DropDownList(name, parent) self.onHide(id+1); self.onHide = nil; end + if ( self.baseFrameStrata ) then + self:SetFrameStrata(self.baseFrameStrata); + self.baseFrameStrata = nil; + end lib:CloseDropDownMenus(id+1); L_OPEN_DROPDOWNMENUS[id] = nil; if (id == 1) then @@ -475,6 +605,7 @@ local function creatre_DropDownList(name, parent) end lib:UIDropDownMenu_ClearCustomFrames(self); + EventRegistry:TriggerEvent("UIDropDownMenu.Hide"); end) return f @@ -491,63 +622,64 @@ local function create_DropDownMenu(name, parent) f = CreateFrame("Frame", name, parent or nil) end - if not name then name = "" end + --if not name then name = "" end f:SetSize(40, 32) - f.Left = f:CreateTexture(name.."Left", "ARTWORK") + f.Left = f:CreateTexture( name and (name.."Left") or nil, "ARTWORK") f.Left:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") f.Left:SetSize(25, 64) f.Left:SetPoint("TOPLEFT", f, 0, 17) f.Left:SetTexCoord(0, 0.1953125, 0, 1) - f.Middle = f:CreateTexture(name.."Middle", "ARTWORK") + f.Middle = f:CreateTexture( name and (name.."Middle") or nil, "ARTWORK") f.Middle:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") f.Middle:SetSize(115, 64) f.Middle:SetPoint("LEFT", f.Left, "RIGHT") f.Middle:SetTexCoord(0.1953125, 0.8046875, 0, 1) - f.Right = f:CreateTexture(name.."Right", "ARTWORK") + f.Right = f:CreateTexture( name and (name.."Right") or nil, "ARTWORK") f.Right:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") f.Right:SetSize(25, 64) f.Right:SetPoint("LEFT", f.Middle, "RIGHT") f.Right:SetTexCoord(0.8046875, 1, 0, 1) - f.Text = f:CreateFontString(name.."Text", "ARTWORK", "GameFontHighlightSmall") + f.Text = f:CreateFontString( name and (name.."Text") or nil, "ARTWORK", "GameFontHighlightSmall") f.Text:SetWordWrap(false) f.Text:SetJustifyH("RIGHT") f.Text:SetSize(0, 10) f.Text:SetPoint("RIGHT", f.Right, -43, 2) - f.Icon = f:CreateTexture(name.."Icon", "OVERLAY") + f.Icon = f:CreateTexture( name and (name.."Icon") or nil, "OVERLAY") f.Icon:Hide() f.Icon:SetSize(16, 16) f.Icon:SetPoint("LEFT", 30, 2) - f.Button = CreateFrame("Button", name.."Button", f) + -- // UIDropDownMenuButtonScriptTemplate + f.Button = CreateFrame("Button", name and (name.."Button") or nil, f) f.Button:SetMotionScriptsWhileDisabled(true) f.Button:SetSize(24, 24) f.Button:SetPoint("TOPRIGHT", f.Right, -16, -18) - f.Button.NormalTexture = f.Button:CreateTexture(name.."NormalTexture") + f.Button.NormalTexture = f.Button:CreateTexture( name and (name.."NormalTexture") or nil) f.Button.NormalTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") f.Button.NormalTexture:SetSize(24, 24) f.Button.NormalTexture:SetPoint("RIGHT", f.Button, 0, 0) f.Button:SetNormalTexture(f.Button.NormalTexture) - f.Button.PushedTexture = f.Button:CreateTexture(name.."PushedTexture") + f.Button.PushedTexture = f.Button:CreateTexture( name and (name.."PushedTexture") or nil) f.Button.PushedTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") f.Button.PushedTexture:SetSize(24, 24) f.Button.PushedTexture:SetPoint("RIGHT", f.Button, 0, 0) f.Button:SetPushedTexture(f.Button.PushedTexture) - f.Button.DisabledTexture = f.Button:CreateTexture(name.."DisabledTexture") + f.Button.DisabledTexture = f.Button:CreateTexture( name and (name.."DisabledTexture") or nil) f.Button.DisabledTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled") f.Button.DisabledTexture:SetSize(24, 24) f.Button.DisabledTexture:SetPoint("RIGHT", f.Button, 0, 0) f.Button:SetDisabledTexture(f.Button.DisabledTexture) - f.Button.HighlightTexture = f.Button:CreateTexture(name.."HighlightTexture") + f.Button.HighlightTexture = f.Button:CreateTexture( name and (name.."HighlightTexture") or nil) f.Button.HighlightTexture:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") f.Button.HighlightTexture:SetSize(24, 24) f.Button.HighlightTexture:SetPoint("RIGHT", f.Button, 0, 0) @@ -571,9 +703,9 @@ local function create_DropDownMenu(name, parent) end) f.Button:SetScript("OnMouseDown", function(self, button) if self:IsEnabled() then - local parent = self:GetParent() - lib:ToggleDropDownMenu(nil, nil, parent) - PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON) + local parent = self:GetParent() + lib:ToggleDropDownMenu(nil, nil, parent) + PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON) end end) @@ -606,14 +738,23 @@ local function create_DropDownButtons() L_DropDownList2:SetID(2) L_DropDownList2:SetSize(180, 10) + L_DropDownList3 = creatre_DropDownList("L_DropDownList3") + L_DropDownList3:SetToplevel(true) + L_DropDownList3:SetFrameStrata("FULLSCREEN_DIALOG") + L_DropDownList3:Hide() + L_DropDownList3:SetID(3) + L_DropDownList3:SetSize(180, 10) + -- UIParent integration; since we customize the name of DropDownList, we need to add it to golbal UIMenus table. --tinsert(UIMenus, "L_DropDownList1"); --tinsert(UIMenus, "L_DropDownList2"); + --tinsert(UIMenus, "L_DropDownList3"); -- Alternative by Dahk Celes (DDC) that avoids tainting UIMenus and CloseMenus() hooksecurefunc("CloseMenus", function() L_DropDownList1:Hide() L_DropDownList2:Hide() + L_DropDownList3:Hide() end) end @@ -659,6 +800,9 @@ function lib:UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, local dropDownList = _G["L_DropDownList"..level]; dropDownList.dropdown = frame; dropDownList.shouldRefresh = true; + if (WoWRetail) then + dropDownList:SetWindow(frame:GetWindow()); + end lib:UIDropDownMenu_SetDisplayMode(frame, displayMode); end @@ -690,6 +834,10 @@ function lib:UIDropDownMenu_SetDisplayMode(frame, displayMode) end end +function lib:UIDropDownMenu_SetFrameStrata(frame, frameStrata) + frame.listFrameStrata = frameStrata; +end + function lib:UIDropDownMenu_RefreshDropDownSize(self) self.maxWidth = lib:UIDropDownMenu_GetMaxButtonWidth(self); self:SetWidth(self.maxWidth + 25); @@ -735,6 +883,7 @@ info.isTitle = [nil, true] -- If it's a title the button is disabled and the f info.disabled = [nil, true] -- Disable the button and show an invisible button that still traps the mouseover event so menu doesn't time out info.tooltipWhileDisabled = [nil, 1] -- Show the tooltip, even when the button is disabled. info.hasArrow = [nil, true] -- Show the expand arrow for multilevel menus +info.arrowXOffset = [nil, NUMBER] -- Number of pixels to shift the button's icon to the left or right (positive numbers shift right, negative numbers shift left). info.hasColorSwatch = [nil, true] -- Show color swatch or not, for color selection info.r = [1 - 255] -- Red color value of the color swatch info.g = [1 - 255] -- Green color value of the color swatch @@ -751,20 +900,32 @@ info.owner = [Frame] -- Dropdown frame that "owns" the current dropdownlist info.keepShownOnClick = [nil, 1] -- Don't hide the dropdownlist after a button is clicked info.tooltipTitle = [nil, STRING] -- Title of the tooltip shown on mouseover info.tooltipText = [nil, STRING] -- Text of the tooltip shown on mouseover +info.tooltipWarning = [nil, STRING] -- Warning-style text of the tooltip shown on mouseover +info.tooltipInstruction = [nil, STRING] -- Instruction-style text of the tooltip shown on mouseover info.tooltipOnButton = [nil, 1] -- Show the tooltip attached to the button instead of as a Newbie tooltip. +info.tooltipBackdropStyle = [nil, TABLE] -- Optional Backdrop style of the tooltip shown on mouseover info.justifyH = [nil, "CENTER"] -- Justify button text info.arg1 = [ANYTHING] -- This is the first argument used by info.func info.arg2 = [ANYTHING] -- This is the second argument used by info.func info.fontObject = [FONT] -- font object replacement for Normal and Highlight -info.menuTable = [TABLE] -- This contains an array of info tables to be displayed as a child menu +info.menuList = [TABLE] -- This contains an array of info tables to be displayed as a child menu +info.menuListDisplayMode = [nil, "MENU"] -- If menuList is set, show the sub drop down with an override display mode. info.noClickSound = [nil, 1] -- Set to 1 to suppress the sound when clicking the button. The sound only plays if .func is set. info.padding = [nil, NUMBER] -- Number of pixels to pad the text on the right side +info.topPadding = [nil, NUMBER] -- Extra spacing between buttons. info.leftPadding = [nil, NUMBER] -- Number of pixels to pad the button on the left side info.minWidth = [nil, NUMBER] -- Minimum width for this line info.customFrame = frame -- Allows this button to be a completely custom frame, should inherit from UIDropDownCustomMenuEntryTemplate and override appropriate methods. info.icon = [TEXTURE] -- An icon for the button. +info.iconXOffset = [nil, NUMBER] -- Number of pixels to shift the button's icon to the left or right (positive numbers shift right, negative numbers shift left). +info.iconTooltipTitle = [nil, STRING] -- Title of the tooltip shown on icon mouseover +info.iconTooltipText = [nil, STRING] -- Text of the tooltip shown on icon mouseover +info.iconTooltipBackdropStyle = [nil, TABLE] -- Optional Backdrop style of the tooltip shown on icon mouseover info.mouseOverIcon = [TEXTURE] -- An override icon when a button is moused over. info.ignoreAsMenuSelection [nil, true] -- Never set the menu text/icon to this, even when this button is checked +info.registerForRightClick [nil, true] -- Register dropdown buttons for right clicks +info.registerForAnyClick [nil, true] -- Register dropdown buttons for any clicks +info.showNewLabel ]] -- Create (return) empty table @@ -783,8 +944,8 @@ function lib:UIDropDownMenu_CreateFrames(level, index) newList:SetID(L_UIDROPDOWNMENU_MAXLEVELS); newList:SetWidth(180) newList:SetHeight(10) - for i = WoWRetail and 1 or (L_UIDROPDOWNMENU_MINBUTTONS+1), L_UIDROPDOWNMENU_MAXBUTTONS do --- for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do +-- for i = WoWRetail and 1 or (L_UIDROPDOWNMENU_MINBUTTONS+1), L_UIDROPDOWNMENU_MAXBUTTONS do + for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do --local newButton = CreateFrame("Button", "L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS.."Button"..i, newList, "L_UIDropDownMenuButtonTemplate"); local newButton = create_MenuButton("L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS.."Button"..i, newList) newButton:SetID(i); @@ -886,6 +1047,14 @@ function lib:UIDropDownMenu_AddButton(info, level) invisibleButton:Hide(); button:Enable(); + if ( info.registerForAnyClick ) then + button:RegisterForClicks("AnyUp"); + elseif ( info.registerForRightClick ) then + button:RegisterForClicks("LeftButtonUp", "RightButtonUp"); + else + button:RegisterForClicks("LeftButtonUp"); + end + -- If not clickable then disable the button and set it white if ( info.notClickable ) then info.disabled = true; @@ -922,9 +1091,19 @@ function lib:UIDropDownMenu_AddButton(info, level) -- Set icon if ( info.icon or info.mouseOverIcon ) then icon:SetSize(16,16); - icon:SetTexture(info.icon); - icon:ClearAllPoints(); - icon:SetPoint("RIGHT", info.iconXOffset or 0, 0); + if (WoWRetail) then + if(info.icon and C_Texture.GetAtlasInfo(info.icon)) then + icon:SetAtlas(info.icon); + else + icon:SetTexture(info.icon); + end + icon:ClearAllPoints(); + icon:SetPoint("RIGHT", info.iconXOffset or 0, 0); + else + icon:SetTexture(info.icon); + icon:ClearAllPoints(); + icon:SetPoint("RIGHT"); + end if ( info.tCoordLeft ) then icon:SetTexCoord(info.tCoordLeft, info.tCoordRight, info.tCoordTop, info.tCoordBottom); @@ -975,6 +1154,7 @@ function lib:UIDropDownMenu_AddButton(info, level) if (WoWRetail) then button.iconXOffset = info.iconXOffset; button.ignoreAsMenuSelection = info.ignoreAsMenuSelection; + button.showNewLabel = info.showNewLabel; else button.classicChecks = info.classicChecks; end @@ -992,9 +1172,11 @@ function lib:UIDropDownMenu_AddButton(info, level) button.arg1 = info.arg1; button.arg2 = info.arg2; button.hasArrow = info.hasArrow; + button.arrowXOffset = info.arrowXOffset; button.hasColorSwatch = info.hasColorSwatch; button.notCheckable = info.notCheckable; button.menuList = info.menuList; + button.menuListDisplayMode = info.menuListDisplayMode; button.tooltipWhileDisabled = info.tooltipWhileDisabled; button.noTooltipWhileEnabled = info.noTooltipWhileEnabled; button.tooltipOnButton = info.tooltipOnButton; @@ -1002,8 +1184,18 @@ function lib:UIDropDownMenu_AddButton(info, level) button.padding = info.padding; button.icon = info.icon; button.mouseOverIcon = info.mouseOverIcon; + if (WoWRetail) then + button.tooltipBackdropStyle = info.tooltipBackdropStyle; + button.iconTooltipTitle = info.iconTooltipTitle; + button.iconTooltipText = info.iconTooltipText; + button.iconTooltipBackdropStyle = info.iconTooltipBackdropStyle; + button.iconXOffset = info.iconXOffset; + button.ignoreAsMenuSelection = info.ignoreAsMenuSelection; + else + button.classicChecks = info.classicChecks; + end - if ( info.value ) then + if ( info.value ~= nil ) then button.value = info.value; elseif ( info.text ) then button.value = info.text; @@ -1012,12 +1204,14 @@ function lib:UIDropDownMenu_AddButton(info, level) end local expandArrow = _G[listFrameName.."Button"..index.."ExpandArrow"]; + expandArrow:SetPoint("RIGHT", info.arrowXOffset or 0, 0); expandArrow:SetShown(info.hasArrow); expandArrow:SetEnabled(not info.disabled); -- If not checkable move everything over to the left to fill in the gap where the check would be local xPos = 5; - local yPos = -((button:GetID() - 1) * L_UIDROPDOWNMENU_BUTTON_HEIGHT) - L_UIDROPDOWNMENU_BORDER_HEIGHT; + local buttonHeight = (info.topPadding or 0) + L_UIDROPDOWNMENU_BUTTON_HEIGHT; + local yPos = -((button:GetID() - 1) * buttonHeight) - L_UIDROPDOWNMENU_BORDER_HEIGHT; local displayInfo = normalText; if (info.iconOnly) then displayInfo = icon; @@ -1063,7 +1257,7 @@ function lib:UIDropDownMenu_AddButton(info, level) if ( button:GetID() == lib:UIDropDownMenu_GetSelectedID(frame) ) then info.checked = 1; end - elseif ( lib:UIDropDownMenu_GetSelectedValue(frame) ) then + elseif ( lib:UIDropDownMenu_GetSelectedValue(frame) ~= nil ) then if ( button.value == lib:UIDropDownMenu_GetSelectedValue(frame) ) then info.checked = 1; end @@ -1084,7 +1278,7 @@ function lib:UIDropDownMenu_AddButton(info, level) uncheck:SetDesaturated(false); uncheck:SetAlpha(1); end - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then check:SetSize(16,16); uncheck:SetSize(16,16); normalText:SetPoint("LEFT", check, "RIGHT", 0, 0); @@ -1145,11 +1339,14 @@ function lib:UIDropDownMenu_AddButton(info, level) _G[listFrameName.."Button"..index.."UnCheck"]:Hide(); end button.checked = info.checked; - + if (WoWRetail and button.NewFeature) then + button.NewFeature:SetShown(button.showNewLabel); + end + -- If has a colorswatch, show it and vertex color it local colorSwatch = _G[listFrameName.."Button"..index.."ColorSwatch"]; if ( info.hasColorSwatch ) then - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then _G["L_DropDownList"..level.."Button"..index.."ColorSwatch".."NormalTexture"]:SetVertexColor(info.r, info.g, info.b); else _G["L_DropDownList"..level.."Button"..index.."ColorSwatch"].Color:SetVertexColor(info.r, info.g, info.b); @@ -1176,7 +1373,7 @@ function lib:UIDropDownMenu_AddButton(info, level) if (WoWRetail) then local customFrameCount = listFrame.customFrames and #listFrame.customFrames or 0; - local height = ((index - customFrameCount) * L_UIDROPDOWNMENU_BUTTON_HEIGHT) + (L_UIDROPDOWNMENU_BORDER_HEIGHT * 2); + local height = ((index - customFrameCount) * buttonHeight) + (L_UIDROPDOWNMENU_BORDER_HEIGHT * 2); for frameIndex = 1, customFrameCount do local frame = listFrame.customFrames[frameIndex]; height = height + frame:GetPreferredEntryHeight(); @@ -1189,6 +1386,7 @@ function lib:UIDropDownMenu_AddButton(info, level) listFrame:SetHeight((index * L_UIDROPDOWNMENU_BUTTON_HEIGHT) + (L_UIDROPDOWNMENU_BORDER_HEIGHT * 2)); end + return button; end function lib:UIDropDownMenu_CheckAddCustomFrame(self, button, info) @@ -1256,6 +1454,9 @@ function lib:UIDropDownMenu_GetButtonWidth(button) if ( button.hasArrow or button.hasColorSwatch ) then width = width + 10; end + if (WoWRetail and button.showNewLabel and button.NewFeature) then + width = width + button.NewFeature.Label:GetUnboundedStringWidth(); + end if ( button.notCheckable ) then width = width - 30; end @@ -1328,6 +1529,12 @@ function lib:UIDropDownMenu_Refresh(frame, useValue, dropdownLevel) end end + if (WoWRetail and button.NewFeature) then + local normalText = _G[button:GetName().."NormalText"]; + button.NewFeature:SetShown(button.showNewLabel); + button.NewFeature:SetPoint("LEFT", normalText, "RIGHT", 20, 0); + end + if ( button:IsShown() ) then local width = lib:UIDropDownMenu_GetButtonWidth(button); if ( width > maxWidth ) then @@ -1411,15 +1618,16 @@ function lib:UIDropDownMenu_GetSelectedID(frame) return frame.selectedID; else -- If no explicit selectedID then try to send the id of a selected value or name - local maxNum; - if (WoWClassicEra or WoWClassicTBC) then +--[[ local maxNum; + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then maxNum = L_UIDROPDOWNMENU_MAXBUTTONS else local listFrame = _G["L_DropDownList"..L_UIDROPDOWNMENU_MENU_LEVEL]; maxNum = listFrame.numButtons end - for i=1, maxNum do --- for i=1, listFrame.numButtons do + for i=1, maxNum do]] + local listFrame = _G["L_DropDownList"..L_UIDROPDOWNMENU_MENU_LEVEL]; + for i=1, listFrame.numButtons do local button = _G["L_DropDownList"..L_UIDROPDOWNMENU_MENU_LEVEL.."Button"..i]; -- See if checked or not if ( lib:UIDropDownMenu_GetSelectedName(frame) ) then @@ -1444,7 +1652,7 @@ function lib:HideDropDownMenu(level) listFrame:Hide(); end -function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay) +function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay, overrideDisplayMode) if ( not level ) then level = 1; end @@ -1579,7 +1787,8 @@ function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset _G[listFrameName.."MenuBackdrop"]:Hide(); else -- Change list box appearance depending on display mode - if ( dropDownFrame and dropDownFrame.displayMode == "MENU" ) then + local displayMode = overrideDisplayMode or (dropDownFrame and dropDownFrame.displayMode) or nil; + if ( displayMode == "MENU" ) then _G[listFrameName.."Backdrop"]:Hide(); _G[listFrameName.."MenuBackdrop"]:Show(); else @@ -1587,7 +1796,7 @@ function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset _G[listFrameName.."MenuBackdrop"]:Hide(); end end - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then dropDownFrame.menuList = menuList; end @@ -1613,6 +1822,12 @@ function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset listFrame.onHide = dropDownFrame.onHide; + -- Set the listframe frameStrata + if dropDownFrame.listFrameStrata then + listFrame.baseFrameStrata = listFrame:GetFrameStrata(); + listFrame:SetFrameStrata(dropDownFrame.listFrameStrata); + end + -- We just move level 1 enough to keep it on the screen. We don't necessarily change the anchors. if ( level == 1 ) then local offLeft = listFrame:GetLeft()/uiScale; @@ -1641,51 +1856,42 @@ function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset end else -- Determine whether the menu is off the screen or not - -- local offscreenY, offscreenX; - -- if ( (y - listFrame:GetHeight()/2) < 0 ) then - -- offscreenY = 1; - -- end - -- if ( listFrame:GetRight() > GetScreenWidth() ) then - -- offscreenX = 1; - -- end - -- if ( offscreenY and offscreenX ) then - -- point = gsub(point, "TOP(.*)", "BOTTOM%1"); - -- point = gsub(point, "(.*)LEFT", "%1RIGHT"); - -- relativePoint = gsub(relativePoint, "TOP(.*)", "BOTTOM%1"); - -- relativePoint = gsub(relativePoint, "(.*)RIGHT", "%1LEFT"); - -- xOffset = -11; - -- yOffset = -14; - -- elseif ( offscreenY ) then - -- point = gsub(point, "TOP(.*)", "BOTTOM%1"); - -- relativePoint = gsub(relativePoint, "TOP(.*)", "BOTTOM%1"); - -- xOffset = 0; - -- yOffset = -14; - -- elseif ( offscreenX ) then - -- point = gsub(point, "(.*)LEFT", "%1RIGHT"); - -- relativePoint = gsub(relativePoint, "(.*)RIGHT", "%1LEFT"); - -- xOffset = -11; - -- yOffset = 14; - -- else - -- xOffset = 0; - -- yOffset = 14; - -- end - - -- listFrame:ClearAllPoints(); - -- listFrame.parentLevel = tonumber(strmatch(anchorFrame:GetName(), "L_DropDownList(%d+)")); - -- listFrame.parentID = anchorFrame:GetID(); - -- listFrame:SetPoint(point, anchorFrame, relativePoint, xOffset, yOffset); - xOffset = -11; - yOffset = -14; - point = gsub(point, "(.*)LEFT", "%1RIGHT"); - relativePoint = gsub(relativePoint, "(.*)RIGHT", "%1LEFT"); - listFrame:SetClampedToScreen(true) + local offscreenY, offscreenX; + if ( (y - listFrame:GetHeight()/2) < 0 ) then + offscreenY = 1; + end + if ( listFrame:GetRight() > GetScreenWidth() ) then + offscreenX = 1; + end + if ( offscreenY and offscreenX ) then + point = gsub(point, "TOP(.*)", "BOTTOM%1"); + point = gsub(point, "(.*)LEFT", "%1RIGHT"); + relativePoint = gsub(relativePoint, "TOP(.*)", "BOTTOM%1"); + relativePoint = gsub(relativePoint, "(.*)RIGHT", "%1LEFT"); + xOffset = -11; + yOffset = -14; + elseif ( offscreenY ) then + point = gsub(point, "TOP(.*)", "BOTTOM%1"); + relativePoint = gsub(relativePoint, "TOP(.*)", "BOTTOM%1"); + xOffset = 0; + yOffset = -14; + elseif ( offscreenX ) then + point = gsub(point, "(.*)LEFT", "%1RIGHT"); + relativePoint = gsub(relativePoint, "(.*)RIGHT", "%1LEFT"); + xOffset = -11; + yOffset = 14; + else + xOffset = 0; + yOffset = 14; + end + listFrame:ClearAllPoints(); listFrame.parentLevel = tonumber(strmatch(anchorFrame:GetName(), "L_DropDownList(%d+)")); listFrame.parentID = anchorFrame:GetID(); listFrame:SetPoint(point, anchorFrame, relativePoint, xOffset, yOffset); end - if (WoWClassicEra or WoWClassicTBC) then + if (WoWClassicEra or WoWClassicTBC or WoWWOTLKC) then if ( autoHideDelay and tonumber(autoHideDelay)) then listFrame.showTimer = autoHideDelay; listFrame.isCounting = 1; @@ -1722,7 +1928,13 @@ local function containsMouse() result = true; end end - + -- TeeloJubeithos: + -- If the menu is open, and you click the button to close it, + -- the Global Mouse Down triggers to close it, but then the MouseDown for the button triggers to open it back up again. + -- I fixed this by adding a filter to the global mouse down check, don't count it if the mouse is still over the DropDownMenu's Button + if L_UIDROPDOWNMENU_OPEN_MENU and L_UIDROPDOWNMENU_OPEN_MENU.Button:IsMouseOver() then + result = true; + end return result; end @@ -1760,19 +1972,29 @@ function lib:UIDropDownMenu_ClearCustomFrames(self) end end +function lib:UIDropDownMenu_MatchTextWidth(frame, minWidth, maxWidth) + local frameName = frame:GetName(); + local newWidth = GetChild(frame, frameName, "Text"):GetUnboundedStringWidth() + L_UIDROPDOWNMENU_DEFAULT_WIDTH_PADDING; + + if minWidth or maxWidth then + newWidth = Clamp(newWidth, minWidth or newWidth, maxWidth or newWidth); + end + + lib:UIDropDownMenu_SetWidth(frame, newWidth); +end + function lib:UIDropDownMenu_SetWidth(frame, width, padding) local frameName = frame:GetName(); GetChild(frame, frameName, "Middle"):SetWidth(width); - local defaultPadding = 25; if ( padding ) then frame:SetWidth(width + padding); else - frame:SetWidth(width + defaultPadding + defaultPadding); + frame:SetWidth(width + L_UIDROPDOWNMENU_DEFAULT_WIDTH_PADDING + L_UIDROPDOWNMENU_DEFAULT_WIDTH_PADDING); end if ( padding ) then GetChild(frame, frameName, "Text"):SetWidth(width); else - GetChild(frame, frameName, "Text"):SetWidth(width - defaultPadding); + GetChild(frame, frameName, "Text"):SetWidth(width - L_UIDROPDOWNMENU_DEFAULT_WIDTH_PADDING); end frame.noResize = 1; end @@ -1816,18 +2038,18 @@ function lib:UIDropDownMenu_ClearAll(frame) end end -function lib:UIDropDownMenu_JustifyText(frame, justification, customXOffset) +function lib:UIDropDownMenu_JustifyText(frame, justification, customXOffset, customYOffset) local frameName = frame:GetName(); local text = GetChild(frame, frameName, "Text"); text:ClearAllPoints(); if ( justification == "LEFT" ) then - text:SetPoint("LEFT", GetChild(frame, frameName, "Left"), "LEFT", customXOffset or 27, 2); + text:SetPoint("LEFT", GetChild(frame, frameName, "Left"), "LEFT", customXOffset or 27, customYOffset or 2); text:SetJustifyH("LEFT"); elseif ( justification == "RIGHT" ) then - text:SetPoint("RIGHT", GetChild(frame, frameName, "Right"), "RIGHT", customXOffset or -43, 2); + text:SetPoint("RIGHT", GetChild(frame, frameName, "Right"), "RIGHT", customXOffset or -43, customYOffset or 2); text:SetJustifyH("RIGHT"); elseif ( justification == "CENTER" ) then - text:SetPoint("CENTER", GetChild(frame, frameName, "Middle"), "CENTER", customXOffset or -5, 2); + text:SetPoint("CENTER", GetChild(frame, frameName, "Middle"), "CENTER", customXOffset or -5, customYOffset or 2); text:SetJustifyH("CENTER"); end end @@ -1862,15 +2084,27 @@ function lib:UIDropDownMenuButton_OpenColorPicker(self, button) button = self; end L_UIDROPDOWNMENU_MENU_VALUE = button.value; - lib:OpenColorPicker(button); + if (WoWRetail) then + ColorPickerFrame:SetupColorPickerAndShow(button); + else + lib:OpenColorPicker(button); + end end function lib:UIDropDownMenu_DisableButton(level, id) - _G["L_DropDownList"..level.."Button"..id]:Disable(); + lib:UIDropDownMenu_SetDropdownButtonEnabled(_G["DropDownList"..level.."Button"..id], false); end function lib:UIDropDownMenu_EnableButton(level, id) - _G["L_DropDownList"..level.."Button"..id]:Enable(); + lib:UIDropDownMenu_SetDropdownButtonEnabled(_G["DropDownList"..level.."Button"..id], true); +end + +function lib:UIDropDownMenu_SetDropdownButtonEnabled(button, enabled) + if enabled then + button:Enable(); + else + button:Disable(); + end end function lib:UIDropDownMenu_SetButtonText(level, id, text, colorCode) @@ -1890,15 +2124,16 @@ function lib:UIDropDownMenu_SetButtonClickable(level, id) _G["L_DropDownList"..level.."Button"..id]:SetDisabledFontObject(GameFontDisableSmallLeft); end + function lib:UIDropDownMenu_DisableDropDown(dropDown) - lib:UIDropDownMenu_SetDropDownEnabled(dropDown, false); + lib:UIDropDownMenu_SetDropDownEnabled(dropDown, false, disabledtooltip); end function lib:UIDropDownMenu_EnableDropDown(dropDown) lib:UIDropDownMenu_SetDropDownEnabled(dropDown, true); end -function lib:UIDropDownMenu_SetDropDownEnabled(dropDown, enabled) +function lib:UIDropDownMenu_SetDropDownEnabled(dropDown, enabled, disabledtooltip) local dropDownName = dropDown:GetName(); local label = GetChild(dropDown, dropDownName, "Label"); if label then @@ -1918,12 +2153,32 @@ function lib:UIDropDownMenu_SetDropDownEnabled(dropDown, enabled) local button = GetChild(dropDown, dropDownName, "Button"); if button then button:SetEnabled(enabled); + + -- Clear any previously set disabledTooltip (it will be reset below if needed). + if button:GetMotionScriptsWhileDisabled() then + button:SetMotionScriptsWhileDisabled(false); + button:SetScript("OnEnter", nil); + button:SetScript("OnLeave", nil); + end end if enabled then dropDown.isDisabled = nil; else dropDown.isDisabled = 1; + + if button then + if disabledTooltip then + button:SetMotionScriptsWhileDisabled(true); + button:SetScript("OnEnter", function() + GameTooltip:SetOwner(button, "ANCHOR_RIGHT"); + GameTooltip_AddErrorLine(GameTooltip, disabledTooltip); + GameTooltip:Show(); + end); + + button:SetScript("OnLeave", GameTooltip_Hide); + end + end end end @@ -1942,20 +2197,29 @@ function lib:UIDropDownMenu_GetValue(id) end function lib:OpenColorPicker(info) - ColorPickerFrame.func = info.swatchFunc; - ColorPickerFrame.hasOpacity = info.hasOpacity; - ColorPickerFrame.opacityFunc = info.opacityFunc; - ColorPickerFrame.opacity = info.opacity; - ColorPickerFrame.previousValues = {r = info.r, g = info.g, b = info.b, opacity = info.opacity}; - ColorPickerFrame.cancelFunc = info.cancelFunc; - ColorPickerFrame.extraInfo = info.extraInfo; - -- This must come last, since it triggers a call to ColorPickerFrame.func() - ColorPickerFrame:SetColorRGB(info.r, info.g, info.b); - ShowUIPanel(ColorPickerFrame); + if (WoWRetail) then + ColorPickerFrame:SetupColorPickerAndShow(info); + else + ColorPickerFrame.func = info.swatchFunc; + ColorPickerFrame.hasOpacity = info.hasOpacity; + ColorPickerFrame.opacityFunc = info.opacityFunc; + ColorPickerFrame.opacity = info.opacity; + ColorPickerFrame.previousValues = {r = info.r, g = info.g, b = info.b, opacity = info.opacity}; + ColorPickerFrame.cancelFunc = info.cancelFunc; + ColorPickerFrame.extraInfo = info.extraInfo; + -- This must come last, since it triggers a call to ColorPickerFrame.func() + ColorPickerFrame:SetColorRGB(info.r, info.g, info.b); + ShowUIPanel(ColorPickerFrame); + end end function lib:ColorPicker_GetPreviousValues() - return ColorPickerFrame.previousValues.r, ColorPickerFrame.previousValues.g, ColorPickerFrame.previousValues.b; + if (WoWRetail) then + local r, g, b = ColorPickerFrame:GetPreviousValues(); + return r, g, b; + else + return ColorPickerFrame.previousValues.r, ColorPickerFrame.previousValues.g, ColorPickerFrame.previousValues.b; + end end -- ////////////////////////////////////////////////////////////// @@ -2005,14 +2269,14 @@ function lib.DropDownExpandArrowMixin:OnEnter() if self:IsEnabled() then local listFrame = _G["L_DropDownList"..level]; if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then - lib:ToggleDropDownMenu(level, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self); + lib:ToggleDropDownMenu(level, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self, nil, self:GetParent().menuListDisplayMode); end end end function lib.DropDownExpandArrowMixin:OnMouseDown(button) if self:IsEnabled() then - lib:ToggleDropDownMenu(self:GetParent():GetParent():GetID() + 1, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self); + lib:ToggleDropDownMenu(self:GetParent():GetParent():GetID() + 1, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self, nil, self:GetParent().menuListDisplayMode); PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON); end end @@ -2049,6 +2313,13 @@ function lib.UIDropDownCustomMenuEntryMixin:GetContextData() return self.contextData; end + +lib.ColorSwatchMixin = {} + +function lib.ColorSwatchMixin:SetColor(color) + self.Color:SetVertexColor(color:GetRGB()); +end + -- ////////////////////////////////////////////////////////////// -- L_UIDropDownCustomMenuEntryTemplate function lib:Create_UIDropDownCustomMenuEntry(name, parent)