Quantcast

Replace the blizzard dropdown menu with a custom one to get rid of the taints once and for all

Adrian L Lange [08-18-14 - 22:58]
Replace the blizzard dropdown menu with a custom one to get rid of the taints once and for all
Filename
Broker_Equipment.lua
diff --git a/Broker_Equipment.lua b/Broker_Equipment.lua
index 5101a5b..3c1cce8 100644
--- a/Broker_Equipment.lua
+++ b/Broker_Equipment.lua
@@ -3,12 +3,18 @@ Broker_Equipment:RegisterEvent('PLAYER_LOGIN')
 Broker_Equipment:SetScript('OnEvent', function(self, event, ...) self[event](self, ...) end)
 Broker_Equipment:Hide()

-local LDB, pending
+local BACKDROP = {
+	bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
+	edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
+	insets = {top = 3, bottom = 3, left = 3, right = 3}
+}
+
+local LDB, Menu, pending

 local function UpdateDisplay()
 	if(InCombatLockdown() and pending) then
 		LDB.text = '|cffffff00' .. pending
-		LDB.icon = 'Interface\\Icons\\' .. GetEquipmentSetInfoByName(pending)
+		LDB.icon = [[Interface\Icons\]] .. GetEquipmentSetInfoByName(pending)
 	else
 		for index = 1, GetNumEquipmentSets() do
 			local name, icon, _, equipped = GetEquipmentSetInfo(index)
@@ -20,40 +26,161 @@ local function UpdateDisplay()
 		end

 		LDB.text = UNKNOWN
-		LDB.icon = [=[Interface\Icons\INV_Misc_QuestionMark]=]
+		LDB.icon = [[Interface\Icons\INV_Misc_QuestionMark]]
 	end
 end

-local function ClickDropdown(self, name)
+local function OnItemClick(self)
 	if(IsShiftKeyDown() and not pending) then
-		local dialog = StaticPopup_Show('CONFIRM_SAVE_EQUIPMENT_SET', name)
-		dialog.data = name
+		local dialog = StaticPopup_Show('CONFIRM_SAVE_EQUIPMENT_SET', self.name)
+		dialog.data = self.name
 	elseif(IsControlKeyDown() and not pending) then
-		local dialog = StaticPopup_Show('CONFIRM_DELETE_EQUIPMENT_SET', name)
-		dialog.data = name
+		local dialog = StaticPopup_Show('CONFIRM_DELETE_EQUIPMENT_SET', self.name)
+		dialog.data = self.name
 	else
 		if(InCombatLockdown()) then
 			Broker_Equipment:RegisterEvent('PLAYER_REGEN_ENABLED')
-			pending = name
+			pending = self.name

 			UpdateDisplay()
 		else
-			EquipmentManager_EquipSet(name)
+			EquipmentManager_EquipSet(pending or self.name)
 		end
 	end
+
+	Menu:Hide()
+end
+
+local function OnEnter()
+	Menu.Fader:Stop()
+end
+
+local function OnLeave()
+	Menu.Fader:Play()
+end
+
+local function OnItemEnter(self)
+	GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
+	GameTooltip:SetEquipmentSet(self.name)
+
+	OnEnter()
+end
+
+local function UpdateMenu(parent)
+	local maxWidth = 0
+
+	local numEquipmentSets = GetNumEquipmentSets()
+	for index = 1, numEquipmentSets do
+		local Item = Menu.items[index]
+		if(not Item) then
+			Item = CreateFrame('Button', nil, Menu)
+			Item:SetPoint('TOPLEFT', 11, -((index - 1) * 18) - UIDROPDOWNMENU_BORDER_HEIGHT)
+			Item:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]])
+			Item:GetHighlightTexture():SetBlendMode('ADD')
+			Item:SetScript('OnClick', OnItemClick)
+			Item:SetScript('OnEnter', OnItemEnter)
+			Item:SetScript('OnLeave', GameTooltip_Hide)
+			Item:HookScript('OnLeave', OnLeave)
+
+			local Button = CreateFrame('CheckButton', nil, Item)
+			Button:SetPoint('LEFT')
+			Button:SetSize(16, 16)
+			Button:SetNormalTexture([[Interface\Common\UI-DropDownRadioChecks]])
+			Button:GetNormalTexture():SetTexCoord(0.5, 1, 0.5, 1)
+			Button:SetCheckedTexture([[Interface\Common\UI-DropDownRadioChecks]])
+			Button:GetCheckedTexture():SetTexCoord(0, 0.5, 0.5, 1)
+			Button:EnableMouse(false)
+			Item.Button = Button
+
+			local Label = Item:CreateFontString(nil, nil, 'GameFontHighlightSmall')
+			Label:SetPoint('LEFT', 20, 0)
+			Item:SetFontString(Label)
+			Item.Label = Label
+
+			local Icon = Item:CreateTexture(nil, 'ARTWORK')
+			Icon:SetPoint('RIGHT')
+			Icon:SetSize(16, 16)
+			Item.Icon = Icon
+
+			Menu.items[index] = Item
+		else
+			Item:Show()
+		end
+
+		local name, icon, _, equipped, _, _, _, missing = GetEquipmentSetInfo(index)
+		Item.Button:SetChecked(equipped)
+		Item.Icon:SetTexture(icon)
+		Item.name = name
+
+		if(pending == name) then
+			Item:SetFormattedText('|cffffff00%s|r', name)
+		elseif(missing > 0) then
+			Item:SetFormattedText('|cffff0000%s|r', name)
+		else
+			Item:SetText(name)
+		end
+
+		local width = Item.Label:GetWidth() + 50
+		if(width > maxWidth) then
+			maxWidth = width
+		end
+	end
+
+	for index = numEquipmentSets + 1, #Menu.items do
+		Menu.items[index]:Hide()
+	end
+
+	for _, Item in next, Menu.items do
+		Item:SetSize(maxWidth, 18)
+	end
+
+	Menu:SetSize(maxWidth + 25, (numEquipmentSets * 18) + (UIDROPDOWNMENU_BORDER_HEIGHT * 2))
 end

 local function OnTooltipShow(self)
 	self:SetEquipmentSet(LDB.text)
 end

+local hooked = {}
 local function OnClick(self, button)
 	if(GameTooltip:GetOwner() == self) then
 		GameTooltip:Hide()
 	end

 	if(button ~= 'RightButton' and GetNumEquipmentSets() > 0) then
-		ToggleDropDownMenu(1, nil, Broker_Equipment, self, 0, 0)
+		if(not Menu) then
+			Menu = CreateFrame('Frame', nil, self)
+			Menu:SetPoint('TOP', self, 'BOTTOM')
+			Menu:SetBackdrop(BACKDROP)
+			Menu:SetBackdropColor(0, 0, 0)
+			Menu:SetScript('OnEnter', OnEnter)
+			Menu:SetScript('OnLeave', OnLeave)
+			Menu:Hide()
+			Menu.items = {}
+
+			local Fader = Menu:CreateAnimationGroup()
+			Fader:CreateAnimation():SetDuration(UIDROPDOWNMENU_SHOW_TIME)
+			Fader:SetScript('OnFinished', function()
+				Menu:Hide()
+			end)
+			Menu.Fader = Fader
+		end
+
+		if(Menu:IsShown()) then
+			Menu:Hide()
+		else
+			UpdateMenu(self)
+			Menu:Show()
+		end
+
+		PlaySound('igMainMenuOptionCheckBoxOn')
+
+		if(not hooked[self]) then
+			self:HookScript('OnEnter', OnEnter)
+			self:HookScript('OnLeave', OnLeave)
+
+			hooked[self] = true
+		end
 	else
 		if(not PaperDollFrame:IsVisible()) then
 			ToggleCharacter('PaperDollFrame')
@@ -70,32 +197,6 @@ local function OnClick(self, button)
 	end
 end

-local info = {}
-local function CreateDropdown()
-	for index = 1, GetNumEquipmentSets() do
-		local name, icon, _, equipped, _, _, _, missing  = GetEquipmentSetInfo(index)
-		info.func = ClickDropdown
-		info.icon = icon
-		info.arg1 = name
-		info.checked = equipped
-
-		info.tooltipTitle = 'Broker_Equipment_Hack'
-		info.tooltipText = name
-		info.tooltipWhileDisabled = true
-		info.tooltipOnButton = true
-
-		if(pending == name) then
-			info.text = string.format('|cffffff00%s|r', name)
-		elseif(missing > 0) then
-			info.text = string.format('|cffff0000%s|r', name)
-		else
-			info.text = name
-		end
-
-		UIDropDownMenu_AddButton(info)
-	end
-end
-
 function Broker_Equipment:PLAYER_LOGIN()
 	LDB = LibStub('LibDataBroker-1.1'):NewDataObject('Broker_Equipment', {
 		type = 'data source',
@@ -107,9 +208,6 @@ function Broker_Equipment:PLAYER_LOGIN()
 	self:RegisterEvent('EQUIPMENT_SETS_CHANGED')
 	self.EQUIPMENT_SETS_CHANGED = UpdateDisplay

-	self.initialize = CreateDropdown
-	self.displayMode = 'MENU'
-
 	UpdateDisplay()
 end

@@ -122,7 +220,7 @@ end
 function Broker_Equipment:PLAYER_REGEN_ENABLED()
 	self:UnregisterEvent('PLAYER_REGEN_ENABLED')

-	ClickDropdown(nil, pending)
+	OnItemClick()
 	pending = nil
 end

@@ -130,9 +228,3 @@ Broker_Equipment:SetScript('OnUpdate', function(self)
 	PaperDollFrame_SetSidebar(nil, 3)
 	self:Hide()
 end)
-
-GameTooltip:HookScript('OnShow', function(self)
-	if(GameTooltipTextLeft1:GetText() == 'Broker_Equipment_Hack') then
-		GameTooltip:SetEquipmentSet(GameTooltipTextLeft2:GetText())
-	end
-end)