Quantcast

- Fix errors due to API backdrop changes in Seasons of Mastery; upgraded dropdown to 4.0

urnati [11-21-21 - 14:35]
- Fix errors due to API backdrop changes in Seasons of Mastery; upgraded dropdown to 4.0
- Update allowed R side built-in plugins (except Vol and auto-hide)
Filename
TitanClassic/LDBToTitanClassic.lua
TitanClassic/TitanClassicUtils.lua
TitanClassic/TitanPanelClassic.lua
TitanClassic/TitanPanelClassicTemplate.lua
TitanClassic/TitanPanelClassicTemplate.xml
TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibEasyMenu.lua
TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.lua
TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.xml
TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.lua
TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.xml
TitanClassicAmmo/TitanClassicAmmo.lua
TitanClassicBag/TitanClassicBag.lua
TitanClassicClock/TitanClassicClock.lua
TitanClassicClock/TitanClassicClock.xml
TitanClassicLocation/TitanClassicLocation.lua
TitanClassicLootType/TitanClassicLootType.xml
TitanClassicPerformance/TitanClassicPerformance.lua
TitanClassicPerformance/TitanClassicPerformance.xml
TitanClassicVolume/TitanClassicVolume.lua
TitanClassicVolume/TitanClassicVolume.xml
TitanClassicXP/TitanClassicXP.lua
diff --git a/TitanClassic/LDBToTitanClassic.lua b/TitanClassic/LDBToTitanClassic.lua
index 2219327..d7a3134 100644
--- a/TitanClassic/LDBToTitanClassic.lua
+++ b/TitanClassic/LDBToTitanClassic.lua
@@ -115,30 +115,14 @@ VAR: frame
 --]]
 function LDBToTitan:TitanLDBSetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame)
 	if frame:GetName() == "GameTooltip" then
-		-- Changes for 9.1.5. The background template was removed from the GameTooltip
-		local tip_name = frame:GetName()
-
-		local tip_back_name = tip_name.."Backdrop"
-		local tip_back_frame = _G[tip_back_name] or CreateFrame("Frame", tip_back_name, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
-		tip_back_frame:SetFrameLevel(frame:GetFrameLevel() - 1) -- By creating this after the parent, need to set it behind the parent
-
-		tip_back_frame:SetAllPoints()
-		tip_back_frame:SetBackdrop(back_drop_info)
-		-- set alpha (transparency) for the Game Tooltip
-		local tool_trans = TitanPanelGetVar("TooltipTrans")
-		tip_back_frame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, tool_trans)
-		tip_back_frame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b, tool_trans)
-		frame.MenuBackdrop = tip_back_frame
-
 		frame:SetOwner(parent, "ANCHOR_NONE");
---[[
 		-- set alpha (transparency) for the Game Tooltip
 		local red, green, blue = GameTooltip:GetBackdropColor();
 		local red2, green2, blue2 = GameTooltip:GetBackdropBorderColor();
 		frame:SetBackdropColor(red,green,blue,TitanPanelGetVar("TooltipTrans"));
 		frame:SetBackdropBorderColor(red2,green2,blue2,
 			TitanPanelGetVar("TooltipTrans"));
---]]
+
 		-- set font size for the Game Tooltip
 		if not TitanPanelGetVar("DisableTooltipFont") then
 			if TitanTooltipScaleSet < 1 then
diff --git a/TitanClassic/TitanClassicUtils.lua b/TitanClassic/TitanClassicUtils.lua
index 06ff9c6..f34582a 100644
--- a/TitanClassic/TitanClassicUtils.lua
+++ b/TitanClassic/TitanClassicUtils.lua
@@ -16,6 +16,183 @@ TITAN_NOT_REGISTERED = _G["RED_FONT_COLOR_CODE"].."Not_Registered_Yet".._G["FONT
 TITAN_REGISTERED = _G["GREEN_FONT_COLOR_CODE"].."Registered".._G["FONT_COLOR_CODE_CLOSE"]
 TITAN_REGISTER_FAILED = _G["RED_FONT_COLOR_CODE"].."Failed_to_Register".._G["FONT_COLOR_CODE_CLOSE"]

+local DDM = LibStub:GetLibrary("LibUIDropDownMenu-4.0")
+
+--
+-- Wrap the drop down lib 4.0 to look like 2.0 to keep current plugins the same
+-- These need to be global to act like the older version
+--
+-- L_UIDropDownMenuDelegate_OnAttributeChanged -- Different in 4.0
+function L_UIDropDownMenu_InitializeHelper (frame)
+	DDM:UIDropDownMenu_InitializeHelper (frame)
+end
+function L_Create_UIDropDownMenu(name, parent)
+	local str = ""
+	if type(name) == "table" then
+		str = name:GetName()
+	else
+		str = name
+	end
+	return DDM:Create_UIDropDownMenu(name, parent)
+end
+function L_UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList)
+	DDM:UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList)
+end
+function L_UIDropDownMenu_SetInitializeFunction(frame, initFunction)
+	DDM:UIDropDownMenu_SetInitializeFunction(frame, initFunction)
+end
+function L_UIDropDownMenu_SetDisplayMode(frame, displayMode)
+	DDM:UIDropDownMenu_SetDisplayMode(frame, displayMode)
+end
+function L_UIDropDownMenu_RefreshDropDownSize(self)
+	DDM:UIDropDownMenu_RefreshDropDownSize(self)
+end
+--function L_UIDropDownMenu_OnUpdate(self, elapsed) -- Different in 4.0
+function L_UIDropDownMenu_StartCounting(frame)
+	DDM:UIDropDownMenu_StartCounting(frame)
+end
+function L_UIDropDownMenu_StopCounting(frame)
+	DDM:UIDropDownMenu_StopCounting(frame)
+end
+--function L_UIDropDownMenuButtonInvisibleButton_OnEnter(self)) -- Different in 4.0
+--function L_UIDropDownMenuButtonInvisibleButton_OnLeave(self)) -- Different in 4.0
+--function L_UIDropDownMenuButton_OnEnter(self) -- Different in 4.0
+--function L_UIDropDownMenuButton_OnLeave(self) -- Different in 4.0
+function L_UIDropDownMenu_CreateInfo()
+	return DDM:UIDropDownMenu_CreateInfo()
+end
+function L_UIDropDownMenu_CreateFrames(level, index)
+	DDM:UIDropDownMenu_CreateFrames(level, index)
+end
+function L_UIDropDownMenu_AddSeparator(level)
+	DDM:UIDropDownMenu_AddSeparator(level)
+end
+function L_UIDropDownMenu_AddSpace(level) -- new in 4.0
+	DDM:UIDropDownMenu_AddSpace(level)
+end
+function L_UIDropDownMenu_AddButton(info, level)
+	DDM:UIDropDownMenu_AddButton(info, level)
+end
+function L_UIDropDownMenu_CheckAddCustomFrame(self, button, info)
+	DDM:UIDropDownMenu_CheckAddCustomFrame(self, button, info)
+end
+function L_UIDropDownMenu_RegisterCustomFrame(self, customFrame)
+	DDM:UIDropDownMenu_RegisterCustomFrame(self, customFrame)
+end
+function L_UIDropDownMenu_GetMaxButtonWidth(self)
+	return DDM:UIDropDownMenu_GetMaxButtonWidth(self)
+end
+function L_UIDropDownMenu_GetButtonWidth(button)
+	return DDM:UIDropDownMenu_GetButtonWidth(button)
+end
+function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
+	DDM:UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
+end
+function L_UIDropDownMenu_RefreshAll(frame, useValue)
+	DDM:UIDropDownMenu_RefreshAll(frame, useValue)
+end
+function L_UIDropDownMenu_SetIconImage(icon, texture, info)
+	DDM:UIDropDownMenu_SetIconImage(icon, texture, info)
+end
+function L_UIDropDownMenu_SetSelectedName(frame, name, useValue)
+	DDM:UIDropDownMenu_SetSelectedName(frame, name, useValue)
+end
+function L_UIDropDownMenu_SetSelectedValue(frame, value, useValue)
+	DDM:UIDropDownMenu_SetSelectedValue(frame, value, useValue)
+end
+function L_UIDropDownMenu_SetSelectedID(frame, id, useValue)
+	DDM:UIDropDownMenu_SetSelectedID(frame, id, useValue)
+end
+function L_UIDropDownMenu_GetSelectedName(frame)
+	return DDM:UIDropDownMenu_GetSelectedName(frame)
+end
+function L_UIDropDownMenu_GetSelectedID(frame)
+	return DDM:UIDropDownMenu_GetSelectedID(frame)
+end
+function L_UIDropDownMenu_GetSelectedValue(frame)
+	return DDM:UIDropDownMenu_GetSelectedValue(frame)
+end
+--function L_UIDropDownMenuButton_OnClick(self) -- Different in 4.0
+function L_HideDropDownMenu(level)
+	DDM:HideDropDownMenu(level)
+end
+function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay)
+	DDM:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay)
+end
+function L_CloseDropDownMenus(level)
+	DDM:CloseDropDownMenus(level)
+end
+--function L_UIDropDownMenu_OnHide(self) -- Different in 4.0
+-- 4.0 has 'contains mouse' routines for retail only
+function L_UIDropDownMenu_SetWidth(frame, width, padding)
+	DDM:UIDropDownMenu_SetWidth(frame, width, padding)
+end
+function L_UIDropDownMenu_SetButtonWidth(frame, width)
+	DDMUIDropDownMenu_SetButtonWidth(frame, width)
+end
+function L_UIDropDownMenu_SetText(frame, text)
+	DDM:UIDropDownMenu_SetText(frame, text)
+end
+function L_UIDropDownMenu_GetText(frame)
+	return DDM:UIDropDownMenu_GetText(frame)
+end
+function L_UIDropDownMenu_ClearAll(frame)
+	DDM:UIDropDownMenu_ClearAll(frame)
+end
+function L_UIDropDownMenu_JustifyText(frame, justification)
+	DDM:UIDropDownMenu_JustifyText(frame, justification)
+end
+function L_UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint)
+	DDM:UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint)
+end
+function L_UIDropDownMenu_GetCurrentDropDown()
+	return DDM:UIDropDownMenu_GetCurrentDropDown()
+end
+function L_UIDropDownMenuButton_GetChecked(self)
+	return DDM:UIDropDownMenuButton_GetChecked(self)
+end
+function L_UIDropDownMenuButton_GetName(self)
+	return DDM:UIDropDownMenuButton_GetName(self)
+end
+function L_UIDropDownMenuButton_OpenColorPicker(self, button)
+	DDM:UIDropDownMenuButton_OpenColorPicker(self, button)
+end
+function L_UIDropDownMenu_DisableButton(level, id)
+	DDM:UIDropDownMenu_DisableButton(level, id)
+end
+function L_UIDropDownMenu_EnableButton(level, id)
+	DDM:UIDropDownMenu_EnableButton(level, id)
+end
+function L_UIDropDownMenu_SetButtonText(level, id, text, colorCode)
+	DDM:UIDropDownMenu_SetButtonText(level, id, text, colorCode)
+end
+function L_UIDropDownMenu_SetButtonNotClickable(level, id)
+	DDM:UIDropDownMenu_SetButtonNotClickable(level, id)
+end
+function L_UIDropDownMenu_SetButtonClickable(level, id)
+	DDM:UIDropDownMenu_SetButtonClickable(level, id)
+end
+function L_UIDropDownMenu_DisableDropDown(dropDown)
+	DDM:UIDropDownMenu_DisableDropDown(dropDown)
+end
+function L_UIDropDownMenu_EnableDropDown(dropDown)
+	DDM:UIDropDownMenu_EnableDropDown(dropDown)
+end
+function L_UIDropDownMenu_IsEnabled(dropDown)
+	return DDM:UIDropDownMenu_IsEnabled(dropDown)
+end
+function L_UIDropDownMenu_GetValue(id)
+	return DDM:UIDropDownMenu_GetValue(id)
+end
+function L_OpenColorPicker(info)
+	DDM:OpenColorPicker(info)
+end
+function L_ColorPicker_GetPreviousValues()
+	return DDM:ColorPicker_GetPreviousValues()
+end
+
+--=============
+
 --
 -- The routines labeled API are useable by addon developers
 --
@@ -811,29 +988,6 @@ function TitanPanelRightClickMenu_AddToggleColoredText(id, level)
 end

 --[[ API
-NAME: TitanPanelRightClickMenu_AddToggleRightSide
-DESC: Menu - add a toggle Right Side (localized) command at the given level in the form of a button. Titan will properly control the "DisplayOnRightSide"
-VAR: id - id of the plugin
-VAR: level - level to put the line
-OUT:  None
---]]
-function TitanPanelRightClickMenu_AddToggleRightSide(id, level)
-	-- copy of TitanPanelRightClickMenu_AddToggleVar adding a remove button
-	local info = {};
-	info.text = L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"];
-	info.value = {id, "DisplayOnRightSide"};
-	info.func = function()
-		local bar = TitanUtils_GetWhichBar(id)
-		TitanPanelRightClickMenu_ToggleVar({id, "DisplayOnRightSide"})
-		TitanPanel_RemoveButton(id);
-		TitanUtils_AddButtonOnBar(bar, id)
-	end
-	info.checked = TitanGetVar(id, "DisplayOnRightSide");
-	info.keepShownOnClick = 1;
-	L_UIDropDownMenu_AddButton(info, level);
-end
-
---[[ API
 NAME: TitanPanelRightClickMenu_AddHide
 DESC: Menu - add a Hide (localized) command at the given level in the form of a button. When clicked this will remove the plugin from the Titan bar.
 VAR: id - id of the plugin
@@ -909,6 +1063,57 @@ function TitanPanelRightClickMenu_ToggleColoredText(value)
 	TitanPanelButton_UpdateButton(value, 1);
 end

+--[[ API
+NAME: TitanPanelRightClickMenu_AddToggleRightSide
+DESC: Menu - add a toggle Right Side (localized) command at the given level in the form of a button. Titan will properly control the "DisplayOnRightSide"
+VAR: id - id of the plugin
+VAR: level - level to put the line
+OUT:  None
+--]]
+function TitanPanelRightClickMenu_AddToggleRightSide(id, level)
+    -- copy of TitanPanelRightClickMenu_AddToggleVar adding a remove button
+    local info = {};
+    info.text = L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"];
+    info.value = {id, "DisplayOnRightSide"};
+    info.func = function()
+        local bar = TitanUtils_GetWhichBar(id)
+        TitanPanelRightClickMenu_ToggleVar({id, "DisplayOnRightSide"})
+        TitanPanel_RemoveButton(id);
+        TitanUtils_AddButtonOnBar(bar, id)
+    end
+    info.checked = TitanGetVar(id, "DisplayOnRightSide");
+    info.keepShownOnClick = 1;
+    L_UIDropDownMenu_AddButton(info, level);
+end
+
+--[[ API
+NAME: TitanPanelRightClickMenu_SetCustomBackdrop
+DESC: This will set the backdrop of the given button. This is used for custom created controls such as Clock offset or Volume sliders to give a consistent look.
+VAR: frame - the control frame of the plugin
+OUT:  None
+--]]
+function TitanPanelRightClickMenu_SetCustomBackdrop(frame)
+	frame:SetBackdrop({
+		bgFile="Interface\\Tooltips\\UI-Tooltip-Background",
+		edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
+		tile = true,
+		tileEdge = true,
+		insets = { left = 1, right = 1, top = 1, bottom = 1 },
+		tileSize = 8,
+		edgeSize = 8,
+	})
+
+	frame:SetBackdropBorderColor(
+		TOOLTIP_DEFAULT_COLOR.r,
+		TOOLTIP_DEFAULT_COLOR.g,
+		TOOLTIP_DEFAULT_COLOR.b);
+	frame:SetBackdropColor(
+		TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,
+		TOOLTIP_DEFAULT_BACKGROUND_COLOR.g,
+		TOOLTIP_DEFAULT_BACKGROUND_COLOR.b
+		, 1);
+end
+
 --------------------------------------------------------------
 --
 -- Plugin manipulation routines
diff --git a/TitanClassic/TitanPanelClassic.lua b/TitanClassic/TitanPanelClassic.lua
index 67b8ff4..43999a7 100644
--- a/TitanClassic/TitanPanelClassic.lua
+++ b/TitanClassic/TitanPanelClassic.lua
@@ -326,7 +326,7 @@ NOTE:
 --]]
 function TitanPanel_PlayerEnteringWorld()
 	if Titan__InitializedPEW then
-		-- Also sync the LDB object with the Tian plugin
+		-- Also sync the LDB object with the Titan plugin
 		TitanLDBRefreshButton()
 	else
 		-- Get Profile and Saved Vars
diff --git a/TitanClassic/TitanPanelClassicTemplate.lua b/TitanClassic/TitanPanelClassicTemplate.lua
index b8e5f56..528ab24 100644
--- a/TitanClassic/TitanPanelClassicTemplate.lua
+++ b/TitanClassic/TitanPanelClassicTemplate.lua
@@ -91,21 +91,6 @@ local function TitanTooltip_AddTooltipText(text)
 	end
 end

-local back_drop_info =
-	{
-		bgFile="Interface\\Tooltips\\UI-Tooltip-Background",
-		edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
-		tile = true,
-		insets = {
-			left = 6,
-			right = 6,
-			top = 3,
-			bottom = 3,
-		},
-		tileSize = 8,
-		edgeSize = 8,
-	}
-
 --[[ local
 NAME: TitanTooltip_SetOwnerPosition
 DESC: Set both the parent and the position of GameTooltip for the plugin tooltip.
@@ -122,32 +107,15 @@ local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFram
 	if not frame then
 		frame = _G["GameTooltip"]
 	end
-	-- Changes for 9.1.5. The background template was removed from the GameTooltip
-	local tip_name = frame:GetName()
-
-	local tip_back_name = tip_name.."Backdrop"
-	local tip_back_frame = _G[tip_back_name] or CreateFrame("Frame", tip_back_name, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
-	tip_back_frame:SetFrameLevel(frame:GetFrameLevel() - 1) -- By creating this after the parent, need to set it behind the parent
-
-	tip_back_frame:SetAllPoints()
-	tip_back_frame:SetBackdrop(back_drop_info)
-	-- set alpha (transparency) for the Game Tooltip
-	local tool_trans = TitanPanelGetVar("TooltipTrans")
-	tip_back_frame:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, tool_trans)
-	tip_back_frame:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b, tool_trans)
-	frame.MenuBackdrop = tip_back_frame
-
 	frame:SetOwner(parent, "ANCHOR_NONE");
 	frame:SetPoint(anchorPoint, relativeToFrame, relativePoint,
 		xOffset, yOffset);
---[[
 	-- set alpha (transparency) for the Game Tooltip
 	local red, green, blue = frame:GetBackdropColor();
 	local red2, green2, blue2 = frame:GetBackdropBorderColor();
 	local tool_trans = TitanPanelGetVar("TooltipTrans")
 	frame:SetBackdropColor(red,green,blue,tool_trans);
 	frame:SetBackdropBorderColor(red2,green2,blue2,tool_trans);
---]]
 	-- set font size for the Game Tooltip
 	if not TitanPanelGetVar("DisableTooltipFont") then
 		if TitanTooltipScaleSet < 1 then
@@ -495,6 +463,41 @@ local function TitanPanelButton_OnDragStop(self, ChildButton)
 	end
 end

+--[[ local
+NAME: TitanTooltip_SetOwnerPosition
+DESC: Set both the parent and the position of GameTooltip for the plugin tooltip.
+VAR: parent - reference to the frame to attach the tooltip to
+VAR: anchorPoint - tooltip anchor location (side or corner) to use
+VAR: relativeToFrame - string name name of the frame, usually the plugin), to attach the tooltip to
+VAR: relativePoint - parent anchor location (side or corner) to use
+VAR: xOffset - X offset from the anchor point
+VAR: yOffset - Y offset from the anchor point
+VAR: frame - reference to the tooltip
+OUT:  None
+--]]
+local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame)
+	if not frame then
+		frame = _G["GameTooltip"]
+	end
+	frame:SetOwner(parent, "ANCHOR_NONE");
+	frame:SetPoint(anchorPoint, relativeToFrame, relativePoint,
+		xOffset, yOffset);
+	-- set alpha (transparency) for the Game Tooltip
+	local red, green, blue = frame:GetBackdropColor();
+	local red2, green2, blue2 = frame:GetBackdropBorderColor();
+	local tool_trans = TitanPanelGetVar("TooltipTrans")
+	frame:SetBackdropColor(red,green,blue,tool_trans);
+	frame:SetBackdropBorderColor(red2,green2,blue2,tool_trans);
+	-- set font size for the Game Tooltip
+	if not TitanPanelGetVar("DisableTooltipFont") then
+		if TitanTooltipScaleSet < 1 then
+		TitanTooltipOrigScale = frame:GetScale();
+		TitanTooltipScaleSet = TitanTooltipScaleSet + 1;
+		end
+		frame:SetScale(TitanPanelGetVar("TooltipFont"));
+	end
+end
+
 --[[ API
 NAME: TitanOptionSlider_TooltipText
 DESC: Set the color of the tooltip text to normal (white) with the value in green.
@@ -1048,3 +1051,23 @@ function TitanPanelButton_GetType(id)
 	return type;
 end

+--[[ Titan
+NAME: TitanOptionsSliderTemplate_OnLoad
+DESC: Loads the Backdrop for TitanOptionsSliderTemplate with new 9.0 API
+VAR: self - The frame
+--]]
+function TitanOptionsSliderTemplate_OnLoad(self)
+		self:SetBackdrop({
+			bgFile="Interface\\Buttons\\UI-SliderBar-Background",
+			edgeFile="Interface\\Buttons\\UI-SliderBar-Border",
+			tile = true,
+			insets = {
+				left = 6,
+				right = 6,
+				top = 3,
+				bottom = 3,
+			},
+			tileSize = 8,
+			edgeSize = 8,
+		})
+end
diff --git a/TitanClassic/TitanPanelClassicTemplate.xml b/TitanClassic/TitanPanelClassicTemplate.xml
index d063544..9fb1d55 100644
--- a/TitanClassic/TitanPanelClassicTemplate.xml
+++ b/TitanClassic/TitanPanelClassicTemplate.xml
@@ -2,6 +2,9 @@
 ..\FrameXML\UI.xsd">
 	<Script file="TitanPanelClassicTemplate.lua" />
 	<Button name="TitanPanelButtonTemplate" hidden="true" movable="true" virtual="true">
+		<!--
+		 inherits="BackdropTemplate" mixin="BackdropTemplateMixin"
+		-->
 		<!-- Removed on 20181229 to deal with the new LibUIDropDownMenu
 		<Frames>
 			<Frame name="$parentRightClickMenu" inherits="L_UIDropDownMenuTemplate" id="1" hidden="true">
@@ -9,7 +12,7 @@
 		</Frames>
 		-->
 		<Scripts>
-			<OnLoad>
+			<OnLoad>  <!--  inherit="prepend" -->
 				TitanPanelButton_OnLoad(self);
 			</OnLoad>
 			<OnShow>
@@ -103,13 +106,14 @@
 			<AbsDimension x="0" y="0"/>
 		</PushedTextOffset>
 	</Button>
-	<Slider name="TitanOptionsSliderTemplate" orientation="VERTICAL" virtual="true" enableMouse="true" EnableMouseWheel="true">
+	<Slider name="TitanOptionsSliderTemplate" orientation="VERTICAL" inherits="BackdropTemplate" virtual="true" enableMouse="true" EnableMouseWheel="true">
 		<Size>
 			<AbsDimension x="10" y="100"/>
 		</Size>
 		<HitRectInsets>
 			<AbsInset left="-10" right="-10" top="0" bottom="0"/>
 		</HitRectInsets>
+<!-- Removed on 20200817 to deal with the new Backdrop API for 9.0 (Shadowlands)
 		<Backdrop bgFile="Interface\Buttons\UI-SliderBar-Background" edgeFile="Interface\Buttons\UI-SliderBar-Border" tile="true">
 			<EdgeSize>
 				<AbsValue val="8"/>
@@ -121,6 +125,7 @@
 				<AbsInset left="6" right="6" top="3" bottom="3"/>
 			</BackgroundInsets>
 		</Backdrop>
+-->
 		<Layers>
 			<Layer level="ARTWORK">
 				<FontString name="$parentText" inherits="GameFontGreenSmall">
@@ -157,5 +162,9 @@
 				<AbsDimension x="32" y="32"/>
 			</Size>
 		</ThumbTexture>
-	</Slider>
+		<Scripts>
+			<OnLoad>
+				TitanOptionsSliderTemplate_OnLoad(self);
+			</OnLoad>
+		</Scripts>	</Slider>
 </Ui>
diff --git a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibEasyMenu.lua b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibEasyMenu.lua
index 5cf69f6..731b6bb 100755
--- a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibEasyMenu.lua
+++ b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibEasyMenu.lua
@@ -1,4 +1,13 @@
---$Id: LibEasyMenu.lua 30 2018-04-24 06:44:39Z arith $
+--$Id: LibEasyMenu.lua 64 2020-11-18 13:13:15Z arithmandar $
+-- //////////////////////////////////////////////////////////////
+-- Notes:
+--      Functions have been moved to under LibUIDropDownMenu.lua
+--      New function calls are as below:
+--
+--      - lib:EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay )
+--      - lib:EasyMenu_Initialize( frame, level, menuList )
+--
+-- //////////////////////////////////////////////////////////////
 -- Simplified Menu Display System
 --	This is a basic system for displaying a menu from a structure table.
 --
@@ -14,34 +23,22 @@
 --		autoHideDelay - how long until the menu disappears
 --
 --
--- ----------------------------------------------------------------------------
--- Localized Lua globals.
--- ----------------------------------------------------------------------------
-local _G = getfenv(0)
--- ----------------------------------------------------------------------------
-local MAJOR_VERSION = "LibEasyMenu"
-local MINOR_VERSION = 90000 + tonumber(("$Rev: 30 $"):match("%d+"))
-
-local LibStub = _G.LibStub
-if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
-local Lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
-if not Lib then return end
-
-function L_EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay )
+--[[
+function EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay )
 	if ( displayMode == "MENU" ) then
 		menuFrame.displayMode = displayMode;
 	end
-	L_UIDropDownMenu_Initialize(menuFrame, L_EasyMenu_Initialize, displayMode, nil, menuList);
-	L_ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList, nil, autoHideDelay);
+	UIDropDownMenu_Initialize(menuFrame, EasyMenu_Initialize, displayMode, nil, menuList);
+	ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList, nil, autoHideDelay);
 end

-function L_EasyMenu_Initialize( frame, level, menuList )
+function EasyMenu_Initialize( frame, level, menuList )
 	for index = 1, #menuList do
 		local value = menuList[index]
 		if (value.text) then
 			value.index = index;
-			L_UIDropDownMenu_AddButton( value, level );
+			UIDropDownMenu_AddButton( value, level );
 		end
 	end
 end
-
+]]
diff --git a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.lua b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.lua
index 035c2f1..d6ba8d5 100755
--- a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.lua
+++ b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.lua
@@ -1,25 +1,51 @@
--- $Id: LibUIDropDownMenu.lua 40 2018-12-23 16:14:03Z arith $
+-- $Id: LibUIDropDownMenu.lua 78 2021-06-14 08:29:17Z arithmandar $
 -- ----------------------------------------------------------------------------
 -- Localized Lua globals.
 -- ----------------------------------------------------------------------------
 local _G = getfenv(0)
 local tonumber, type, string, table = _G.tonumber, _G.type, _G.string, _G.table
+local tinsert = table.insert
 local strsub, strlen, strmatch, gsub = _G.strsub, _G.strlen, _G.strmatch, _G.gsub
 local max, match = _G.max, _G.match
 local securecall, issecure = _G.securecall, _G.issecure
 local wipe = table.wipe
 -- WoW
 local CreateFrame, GetCursorPosition, GetCVar, GetScreenHeight, GetScreenWidth, PlaySound = _G.CreateFrame, _G.GetCursorPosition, _G.GetCVar, _G.GetScreenHeight, _G.GetScreenWidth, _G.PlaySound
+local GetBuildInfo = _G.GetBuildInfo
+local GameTooltip, GetAppropriateTooltip, tooltip, GetValueOrCallFunction
+local CloseMenus, ShowUIPanel = _G.CloseMenus, _G.ShowUIPanel
+local GameTooltip_SetTitle, GameTooltip_AddInstructionLine, GameTooltip_AddNormalLine, GameTooltip_AddColoredLine = _G.GameTooltip_SetTitle, _G.GameTooltip_AddInstructionLine, _G.GameTooltip_AddNormalLine, _G.GameTooltip_AddColoredLine

 -- ----------------------------------------------------------------------------
-local MAJOR_VERSION = "LibUIDropDownMenu-2.0"
-local MINOR_VERSION = 90000 + tonumber(("$Rev: 40 $"):match("%d+"))
+local MAJOR_VERSION = "LibUIDropDownMenu-4.0"
+local MINOR_VERSION = 90000 + tonumber(("$Rev: 78 $"):match("%d+"))
+

 local LibStub = _G.LibStub
 if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
 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
+	WoWClassicEra = true
+elseif wowtocversion > 19999 and wowtocversion < 90000 then
+	WoWClassicTBC = true
+else
+	WoWRetail = true
+end
+
+if WoWClassicEra or WoWClassicTBC then
+	GameTooltip = _G.GameTooltip
+	tooltip = GameTooltip
+else -- Retail
+	GetAppropriateTooltip = _G.GetAppropriateTooltip
+	tooltip = GetAppropriateTooltip()
+	GetValueOrCallFunction = _G.GetValueOrCallFunction
+end
+
 -- //////////////////////////////////////////////////////////////
 L_UIDROPDOWNMENU_MAXBUTTONS = 1;
 L_UIDROPDOWNMENU_MAXLEVELS = 2;
@@ -40,28 +66,27 @@ L_UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = nil;
 -- List of open menus
 L_OPEN_DROPDOWNMENUS = {};

-local L_UIDropDownMenuDelegate = CreateFrame("FRAME");
+local L_DropDownList1, L_DropDownList2

-function L_UIDropDownMenuDelegate_OnAttributeChanged (self, attribute, value)
+local delegateFrame = CreateFrame("FRAME");
+delegateFrame:SetScript("OnAttributeChanged", function(self, attribute, value)
 	if ( attribute == "createframes" and value == true ) then
-		L_UIDropDownMenu_CreateFrames(self:GetAttribute("createframes-level"), self:GetAttribute("createframes-index"));
+		lib:UIDropDownMenu_CreateFrames(self:GetAttribute("createframes-level"), self:GetAttribute("createframes-index"));
 	elseif ( attribute == "initmenu" ) then
 		L_UIDROPDOWNMENU_INIT_MENU = value;
 	elseif ( attribute == "openmenu" ) then
 		L_UIDROPDOWNMENU_OPEN_MENU = value;
 	end
-end
-
-L_UIDropDownMenuDelegate:SetScript("OnAttributeChanged", L_UIDropDownMenuDelegate_OnAttributeChanged);
+end);

-function L_UIDropDownMenu_InitializeHelper (frame)
+function lib:UIDropDownMenu_InitializeHelper(frame)
 	-- This deals with the potentially tainted stuff!
 	if ( frame ~= L_UIDROPDOWNMENU_OPEN_MENU ) then
 		L_UIDROPDOWNMENU_MENU_LEVEL = 1;
 	end

 	-- Set the frame that's being intialized
-	L_UIDropDownMenuDelegate:SetAttribute("initmenu", frame);
+	delegateFrame:SetAttribute("initmenu", frame);

 	-- Hide all the buttons
 	local button, dropDownList;
@@ -79,10 +104,9 @@ function L_UIDropDownMenu_InitializeHelper (frame)
 	end
 	frame:SetHeight(L_UIDROPDOWNMENU_BUTTON_HEIGHT * 2);
 end
-
 -- //////////////////////////////////////////////////////////////
 -- L_UIDropDownMenuButtonTemplate
-local function create_UIDropDownMenuButton(name, parent)
+local function create_MenuButton(name, parent)
 	local f = CreateFrame("Button", name, parent or nil)
     f:SetWidth(100)
     f:SetHeight(16)
@@ -112,36 +136,40 @@ local function create_UIDropDownMenuButton(name, parent)
 	f.Icon:Hide()

 	-- ColorSwatch
-	local fcw = CreateFrame("Button", name.."ColorSwatch", f)
-	fcw:SetSize(16, 16)
+	local fcw
+	fcw = CreateFrame("Button", name.."ColorSwatch", f, BackdropTemplateMixin and DropDownMenuButtonMixin and "BackdropTemplate,ColorSwatchTemplate" or BackdropTemplateMixin and "BackdropTemplate" or nil)
 	fcw:SetPoint("RIGHT", f, -6, 0)
 	fcw:Hide()
-	fcw.SwatchBg = fcw:CreateTexture(name.."ColorSwatchSwatchBg", "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")
-	button1NormalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
-	button1NormalTexture:SetAllPoints()
-	fcw:SetNormalTexture(button1NormalTexture)
+	if not DropDownMenuButtonMixin then
+		fcw:SetSize(16, 16)
+		fcw.SwatchBg = fcw:CreateTexture(name.."ColorSwatchSwatchBg", "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")
+		button1NormalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
+		button1NormalTexture:SetAllPoints()
+		fcw:SetNormalTexture(button1NormalTexture)
+	end
 	fcw:SetScript("OnClick", function(self, button, down)
 		CloseMenus()
-		L_UIDropDownMenuButton_OpenColorPicker(self:GetParent())
+		lib:UIDropDownMenuButton_OpenColorPicker(self:GetParent())
 	end)
 	fcw:SetScript("OnEnter", function(self, motion)
-		L_CloseDropDownMenus(self:GetParent():GetParent():GetID() + 1)
+		lib:CloseDropDownMenus(self:GetParent():GetParent():GetID() + 1)
 		_G[self:GetName().."SwatchBg"]:SetVertexColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
-		L_UIDropDownMenu_StopCounting(self:GetParent():GetParent())
+		lib:UIDropDownMenu_StopCounting(self:GetParent():GetParent())
 	end)
 	fcw:SetScript("OnLeave", function(self, motion)
 		_G[self:GetName().."SwatchBg"]:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
-		L_UIDropDownMenu_StartCounting(self:GetParent():GetParent())
+		lib:UIDropDownMenu_StartCounting(self:GetParent():GetParent())
 	end)
 	f.ColorSwatch = fcw

 	-- ExpandArrow
 	local fea = CreateFrame("Button", name.."ExpandArrow", f)
+
 	fea:SetSize(16, 16)
 	fea:SetPoint("RIGHT", f, 0, 0)
 	fea:Hide()
@@ -149,22 +177,25 @@ local function create_UIDropDownMenuButton(name, parent)
 	button2NormalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
 	button2NormalTexture:SetAllPoints()
 	fea:SetNormalTexture(button2NormalTexture)
-	fea:SetScript("OnClick", function(self, button, down)
-		L_ToggleDropDownMenu(self:GetParent():GetParent():GetID() + 1, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self)
+	fea:SetScript("OnMouseDown", function(self, button)
+		if self:IsEnabled() then
+			lib:ToggleDropDownMenu(self:GetParent():GetParent():GetID() + 1, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self);
+			PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+		end
 	end)
 	fea:SetScript("OnEnter", function(self, motion)
 		local level =  self:GetParent():GetParent():GetID() + 1
-		L_CloseDropDownMenus(level)
+		lib:CloseDropDownMenus(level)
 		if self:IsEnabled() then
 			local listFrame = _G["L_DropDownList"..level];
 			if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then
-				L_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)
 			end
 		end
-		L_UIDropDownMenu_StopCounting(self:GetParent():GetParent())
+		lib:UIDropDownMenu_StopCounting(self:GetParent():GetParent())
 	end)
 	fea:SetScript("OnLeave", function(self, motion)
-		L_UIDropDownMenu_StartCounting(self:GetParent():GetParent())
+		lib:UIDropDownMenu_StartCounting(self:GetParent():GetParent())
 	end)
 	f.ExpandArrow = fea

@@ -175,22 +206,136 @@ local function create_UIDropDownMenuButton(name, parent)
 	fib:SetPoint("BOTTOMLEFT", f, 0, 0)
 	fib:SetPoint("RIGHT", fcw, "LEFT", 0, 0)
 	fib:SetScript("OnEnter", function(self, motion)
-		L_UIDropDownMenuButtonInvisibleButton_OnEnter(self)
+		lib:CloseDropDownMenus(self:GetParent():GetParent():GetID() + 1);
+		local parent = self:GetParent();
+		if ( parent.tooltipTitle and parent.tooltipWhileDisabled) then
+			if ( parent.tooltipOnButton ) then
+				tooltip:SetOwner(parent, "ANCHOR_RIGHT");
+				GameTooltip_SetTitle(tooltip, parent.tooltipTitle);
+				if parent.tooltipInstruction then
+					GameTooltip_AddInstructionLine(tooltip, parent.tooltipInstruction);
+				end
+				if parent.tooltipText then
+					GameTooltip_AddNormalLine(tooltip, parent.tooltipText, true);
+				end
+				if parent.tooltipWarning then
+					GameTooltip_AddColoredLine(tooltip, parent.tooltipWarning, RED_FONT_COLOR, true);
+				end
+				tooltip:Show();
+			end
+		end
 	end)
 	fib:SetScript("OnLeave", function(self, motion)
-		L_UIDropDownMenuButtonInvisibleButton_OnLeave(self)
+		lib:UIDropDownMenu_StartCounting(self:GetParent():GetParent());
+		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();
+	    	lib:UIDropDownMenu_StopCounting(self:GetParent());
+
+		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();
+		lib:UIDropDownMenu_StartCounting(self:GetParent());
+
+		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
+	end
+
 	f:SetScript("OnClick", function(self, button, down)
-		L_UIDropDownMenuButton_OnClick(self, button, down)
+		button_OnClick(self, button, down)
 	end)
 	f:SetScript("OnEnter", function(self, motion)
-		L_UIDropDownMenuButton_OnEnter(self)
+		button_OnEnter(self)
 	end)
 	f:SetScript("OnLeave", function(self, motion)
-		L_UIDropDownMenuButton_OnLeave(self)
+		button_OnLeave(self)
 	end)
 	f:SetScript("OnEnable", function(self)
 		self.invisibleButton:Hide()
@@ -211,60 +356,85 @@ end

 -- //////////////////////////////////////////////////////////////
 -- L_UIDropDownListTemplate
-local function creatre_UIDropDownList(name, parent)
-	local f = _G[name] or CreateFrame("Button", name)
-	f:SetParent(parent or nil)
-	f:Hide()
-	f:SetFrameStrata("DIALOG")
-	f:EnableMouse(true)
-
-	local fdb = _G[name.."Backdrop"] or CreateFrame("Frame", name.."Backdrop", f, BackdropTemplateMixin and "BackdropTemplate" or nil)
-	fdb:SetAllPoints()
-	fdb:SetBackdrop({
+local BACKDROP_DIALOG_DARK = {
 		bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
 		edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
 		tile = true,
 		tileSize = 32,
 		edgeSize = 32,
 		insets = { left = 11, right = 12, top = 12, bottom = 9, },
-	})
-	f.Border = fdb
+}
+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)
+	f:SetParent(parent or nil)
+	f:Hide()
+	f:SetFrameStrata("DIALOG")
+	f:EnableMouse(true)

+	--local fbd = _G[name.."Border"] or CreateFrame("Frame", name.."Border", f, BackdropTemplateMixin and "DialogBorderDarkTemplate" or nil)
+	local fbd = _G[name.."Border"] or CreateFrame("Frame", name.."Border", f, BackdropTemplateMixin and "BackdropTemplate" or nil)
+	fbd:SetAllPoints()
+	fbd:SetBackdrop(BACKDROP_DIALOG_DARK)
+	f.Border = fbd
+
+	--local fmb = _G[name.."MenuBackdrop"] or CreateFrame("Frame", name.."MenuBackdrop", f, BackdropTemplateMixin and "TooltipBackdropTemplate" or nil)
 	local fmb = _G[name.."MenuBackdrop"] or CreateFrame("Frame", name.."MenuBackdrop", f, BackdropTemplateMixin and "BackdropTemplate" or nil)
 	fmb:SetAllPoints()
-	fmb:SetBackdrop({
-		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
-		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
-		tile = true,
-		tileSize = 16,
-		edgeSize = 16,
-		insets = { left = 5, right = 4, top = 4, bottom = 4, },
-	})
+	fmb:SetBackdrop(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_UIDropDownMenuButton(name.."Button1", f)
+	f.Button1 = _G[name.."Button1"] or create_MenuButton(name.."Button1", f)
 	f.Button1:SetID(1)

 	f:SetScript("OnClick", function(self)
 		self:Hide()
 	end)
 	f:SetScript("OnEnter", function(self, motion)
-		L_UIDropDownMenu_StopCounting(self, motion)
+		lib:UIDropDownMenu_StopCounting(self, motion)
 	end)
 	f:SetScript("OnLeave", function(self, motion)
-		L_UIDropDownMenu_StartCounting(self, motion)
+		lib:UIDropDownMenu_StartCounting(self, motion)
 	end)
+	-- If dropdown is visible then see if its timer has expired, if so hide the frame
 	f:SetScript("OnUpdate", function(self, elapsed)
-		L_UIDropDownMenu_OnUpdate(self, elapsed)
+		if ( self.shouldRefresh ) then
+			lib:UIDropDownMenu_RefreshDropDownSize(self);
+			self.shouldRefresh = false;
+		end
+		if ( not self.showTimer or not self.isCounting ) then
+			return;
+		elseif ( self.showTimer < 0 ) then
+			self:Hide();
+			self.showTimer = nil;
+			self.isCounting = nil;
+		else
+			self.showTimer = self.showTimer - elapsed;
+		end
 	end)
 	f:SetScript("OnShow", function(self)
+		if ( self.onShow ) then
+			self.onShow();
+			self.onShow = nil;
+		end
+
 		for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do
 			if (not self.noResize) then
 				_G[self:GetName().."Button"..i]:SetWidth(self.maxWidth);
 			end
 		end
+
 		if (not self.noResize) then
 			self:SetWidth(self.maxWidth+25);
 		end
@@ -272,9 +442,43 @@ local function creatre_UIDropDownList(name, parent)
 		if ( self:GetID() > 1 ) then
 			self.parent = _G["L_DropDownList"..(self:GetID() - 1)];
 		end
+--[[
+		-- codes by DahkCeles
+		if (WoWClassicEra or WoWClassicTBC) then
+			self.hideTimer = self.hideTimer or C_Timer.NewTicker(L_UIDROPDOWNMENU_SHOW_TIME, function()
+				if (GetMouseFocus() ~= self) then
+					self:Hide();
+				end
+			end)
+		end
+]]
 	end)
 	f:SetScript("OnHide", function(self)
-		L_UIDropDownMenu_OnHide(self)
+		local id = self:GetID()
+		if ( self.onHide ) then
+			self.onHide(id+1);
+			self.onHide = nil;
+		end
+		lib:CloseDropDownMenus(id+1);
+		L_OPEN_DROPDOWNMENUS[id] = nil;
+		if (id == 1) then
+			L_UIDROPDOWNMENU_OPEN_MENU = nil;
+		end
+
+		if self.customFrames then
+			for index, frame in ipairs(self.customFrames) do
+				frame:Hide();
+			end
+
+			self.customFrames = nil;
+		end
+--[[
+		-- codes by DahkCeles
+		if (self.hideTimer) then
+			self.hideTimer:Cancel();
+			self.hideTimer = nil;
+		end
+]]
 	end)

 	return f
@@ -282,7 +486,7 @@ end

 -- //////////////////////////////////////////////////////////////
 -- L_UIDropDownMenuTemplate
-local function create_UIDropDownMenu(name, parent)
+local function create_DropDownMenu(name, parent)
 	local f
 	if type(name) == "table" then
 		f = name
@@ -290,6 +494,9 @@ local function create_UIDropDownMenu(name, parent)
 	else
 		f = CreateFrame("Frame", name, parent or nil)
 	end
+
+	if not name then name = "" end
+
 	f:SetSize(40, 32)

 	f.Left = f:CreateTexture(name.."Left", "ARTWORK")
@@ -366,14 +573,17 @@ local function create_UIDropDownMenu(name, parent)
 			myscript(parent)
 		end
 	end)
-	f.Button:SetScript("OnClick", function(self, button, down)
-		L_ToggleDropDownMenu(nil, nil, self:GetParent())
+	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)
+		end
 	end)

 	-- UIDropDownMenu Script
 	f:SetScript("OnHide", function(self)
-		L_CloseDropDownMenus()
+		lib:CloseDropDownMenus()
 	end)

 	return f
@@ -383,47 +593,65 @@ end

 -- //////////////////////////////////////////////////////////////
 -- Handling two frames from LibUIDropDownMenu.xml
-local L_DropDownList1, L_DropDownList2
-do
-	L_DropDownList1 = creatre_UIDropDownList("L_DropDownList1")
+local function create_DropDownButtons()
+	L_DropDownList1 = creatre_DropDownList("L_DropDownList1")
 	L_DropDownList1:SetToplevel(true)
 	L_DropDownList1:SetFrameStrata("FULLSCREEN_DIALOG")
 	L_DropDownList1:Hide()
 	L_DropDownList1:SetID(1)
 	L_DropDownList1:SetSize(180, 10)
-	local fontName, fontHeight, fontFlags = _G["L_DropDownList1Button1NormalText"]:GetFont()
+	local _, fontHeight, _ = _G["L_DropDownList1Button1NormalText"]:GetFont()
 	L_UIDROPDOWNMENU_DEFAULT_TEXT_HEIGHT = fontHeight

-	L_DropDownList2 = creatre_UIDropDownList("L_DropDownList2")
+	L_DropDownList2 = creatre_DropDownList("L_DropDownList2")
 	L_DropDownList2:SetToplevel(true)
 	L_DropDownList2:SetFrameStrata("FULLSCREEN_DIALOG")
 	L_DropDownList2:Hide()
 	L_DropDownList2:SetID(2)
 	L_DropDownList2: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");
+
+	-- Alternative by Dahk Celes (DDC) that avoids tainting UIMenus and CloseMenus()
+	hooksecurefunc("CloseMenus", function()
+		L_DropDownList1:Hide()
+		L_DropDownList2:Hide()
+	end)
+end
+
+do
+	if lib then
+		create_DropDownButtons()
+	end
 end

 -- //////////////////////////////////////////////////////////////
 -- Global function to replace L_UIDropDownMenuTemplate
-function L_Create_UIDropDownMenu(name, parent)
-    return create_UIDropDownMenu(name, parent)
+function lib:Create_UIDropDownMenu(name, parent)
+    return create_DropDownMenu(name, parent)
 end

 local function GetChild(frame, name, key)
 	if (frame[key]) then
 		return frame[key];
-	else
+	elseif name then
 		return _G[name..key];
 	end
+
+	return nil;
 end

-function L_UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList)
+function lib:UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList)
 	frame.menuList = menuList;

-	securecall("L_UIDropDownMenu_InitializeHelper", frame);
+	--securecall("initializeHelper", frame);
+	lib:UIDropDownMenu_InitializeHelper(frame)

 	-- Set the initialize function and call it.  The initFunction populates the dropdown list.
 	if ( initFunction ) then
-		L_UIDropDownMenu_SetInitializeFunction(frame, initFunction);
+		lib:UIDropDownMenu_SetInitializeFunction(frame, initFunction);
 		initFunction(frame, level, frame.menuList);
 	end

@@ -436,14 +664,14 @@ function L_UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, me
 	dropDownList.dropdown = frame;
 	dropDownList.shouldRefresh = true;

-	L_UIDropDownMenu_SetDisplayMode(frame, displayMode);
+	lib:UIDropDownMenu_SetDisplayMode(frame, displayMode);
 end

-function L_UIDropDownMenu_SetInitializeFunction(frame, initFunction)
+function lib:UIDropDownMenu_SetInitializeFunction(frame, initFunction)
 	frame.initialize = initFunction;
 end

-function L_UIDropDownMenu_SetDisplayMode(frame, displayMode)
+function lib:UIDropDownMenu_SetDisplayMode(frame, displayMode)
 	-- Change appearance based on the displayMode
 	-- Note: this is a one time change based on previous behavior.
 	if ( displayMode == "MENU" ) then
@@ -466,8 +694,8 @@ function L_UIDropDownMenu_SetDisplayMode(frame, displayMode)
 	end
 end

-function L_UIDropDownMenu_RefreshDropDownSize(self)
-	self.maxWidth = L_UIDropDownMenu_GetMaxButtonWidth(self);
+function lib:UIDropDownMenu_RefreshDropDownSize(self)
+	self.maxWidth = lib:UIDropDownMenu_GetMaxButtonWidth(self);
 	self:SetWidth(self.maxWidth + 25);

 	for i=1, L_UIDROPDOWNMENU_MAXBUTTONS, 1 do
@@ -479,28 +707,10 @@ function L_UIDropDownMenu_RefreshDropDownSize(self)
 	end
 end

--- If dropdown is visible then see if its timer has expired, if so hide the frame
-function L_UIDropDownMenu_OnUpdate(self, elapsed)
-	if ( self.shouldRefresh ) then
-		L_UIDropDownMenu_RefreshDropDownSize(self);
-		self.shouldRefresh = false;
-	end
-
-	if ( not self.showTimer or not self.isCounting ) then
-		return;
-	elseif ( self.showTimer < 0 ) then
-		self:Hide();
-		self.showTimer = nil;
-		self.isCounting = nil;
-	else
-		self.showTimer = self.showTimer - elapsed;
-	end
-end
-
 -- Start the countdown on a frame
-function L_UIDropDownMenu_StartCounting(frame)
+function lib:UIDropDownMenu_StartCounting(frame)
 	if ( frame.parent ) then
-		L_UIDropDownMenu_StartCounting(frame.parent);
+		lib:UIDropDownMenu_StartCounting(frame.parent);
 	else
 		frame.showTimer = L_UIDROPDOWNMENU_SHOW_TIME;
 		frame.isCounting = 1;
@@ -508,87 +718,14 @@ function L_UIDropDownMenu_StartCounting(frame)
 end

 -- Stop the countdown on a frame
-function L_UIDropDownMenu_StopCounting(frame)
+function lib:UIDropDownMenu_StopCounting(frame)
 	if ( frame.parent ) then
-		L_UIDropDownMenu_StopCounting(frame.parent);
+		lib:UIDropDownMenu_StopCounting(frame.parent);
 	else
 		frame.isCounting = nil;
 	end
 end

-function L_UIDropDownMenuButtonInvisibleButton_OnEnter(self)
-	L_UIDropDownMenu_StopCounting(self:GetParent():GetParent());
-	L_CloseDropDownMenus(self:GetParent():GetParent():GetID() + 1);
-	local parent = self:GetParent();
-	if ( parent.tooltipTitle and parent.tooltipWhileDisabled) then
-		if ( parent.tooltipOnButton ) then
-			GameTooltip:SetOwner(parent, "ANCHOR_RIGHT");
-			GameTooltip_SetTitle(GameTooltip, parent.tooltipTitle);
-			if parent.tooltipInstruction then
-				GameTooltip_AddInstructionLine(GameTooltip, parent.tooltipInstruction);
-			end
-			if parent.tooltipText then
-				GameTooltip_AddNormalLine(GameTooltip, parent.tooltipText, true);
-			end
-			if parent.tooltipWarning then
-				GameTooltip_AddColoredLine(GameTooltip, parent.tooltipWarning, RED_FONT_COLOR, true);
-			end
-			GameTooltip:Show();
-		else
-			GameTooltip_AddNewbieTip(parent, parent.tooltipTitle, 1.0, 1.0, 1.0, parent.tooltipText, 1);
-		end
-	end
-end
-
-function L_UIDropDownMenuButtonInvisibleButton_OnLeave(self)
-	L_UIDropDownMenu_StartCounting(self:GetParent():GetParent());
-	GameTooltip:Hide();
-end
-
-function L_UIDropDownMenuButton_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
-			L_ToggleDropDownMenu(self:GetParent():GetID() + 1, self.value, nil, nil, nil, nil, self.menuList, self);
-		end
-	else
-		L_CloseDropDownMenus(self:GetParent():GetID() + 1);
-	end
-	self.Highlight:Show();
-	L_UIDropDownMenu_StopCounting(self:GetParent());
-	if ( self.tooltipTitle and not self.noTooltipWhileEnabled ) then
-		if ( self.tooltipOnButton ) then
-			GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-			GameTooltip_SetTitle(GameTooltip, self.tooltipTitle);
-			if self.tooltipText then
-				GameTooltip_AddNormalLine(GameTooltip, self.tooltipText, true);
-			end
-			GameTooltip:Show();
-		else
-			GameTooltip_AddNewbieTip(self, self.tooltipTitle, 1.0, 1.0, 1.0, self.tooltipText, 1);
-		end
-	end
-
-	if ( self.mouseOverIcon ~= nil ) then
-		self.Icon:SetTexture(self.mouseOverIcon);
-		self.Icon:Show();
-	end
-end
-
-function L_UIDropDownMenuButton_OnLeave(self)
-	self.Highlight:Hide();
-	L_UIDropDownMenu_StartCounting(self:GetParent());
-	GameTooltip:Hide();
-
-	if ( self.mouseOverIcon ~= nil ) then
-		if ( self.icon ~= nil ) then
-			self.Icon:SetTexture(self.icon);
-		else
-			self.Icon:Hide();
-		end
-	end
-end

 --[[
 List of button attributes
@@ -628,20 +765,22 @@ info.noClickSound = [nil, 1]  --  Set to 1 to suppress the sound when clicking t
 info.padding = [nil, NUMBER] -- Number of pixels to pad the text on the right side
 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 L_UIDropDownCustomMenuEntryTemplate and override appropriate methods.
+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.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
 ]]

-function L_UIDropDownMenu_CreateInfo()
+-- Create (return) empty table
+function lib:UIDropDownMenu_CreateInfo()
 	return {};
 end

-function L_UIDropDownMenu_CreateFrames(level, index)
+function lib:UIDropDownMenu_CreateFrames(level, index)
 	while ( level > L_UIDROPDOWNMENU_MAXLEVELS ) do
 		L_UIDROPDOWNMENU_MAXLEVELS = L_UIDROPDOWNMENU_MAXLEVELS + 1;
 		--local newList = CreateFrame("Button", "L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS, nil, "L_UIDropDownListTemplate");
-		local newList = creatre_UIDropDownList("L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS)
+		local newList = creatre_DropDownList("L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS)
 		newList:SetFrameStrata("FULLSCREEN_DIALOG");
 		newList:SetToplevel(true);
 		newList:Hide();
@@ -650,7 +789,7 @@ function L_UIDropDownMenu_CreateFrames(level, index)
 		newList:SetHeight(10)
 		for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do
 			--local newButton = CreateFrame("Button", "L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS.."Button"..i, newList, "L_UIDropDownMenuButtonTemplate");
-			local newButton = create_UIDropDownMenuButton("L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS.."Button"..i, newList)
+			local newButton = create_MenuButton("L_DropDownList"..L_UIDROPDOWNMENU_MAXLEVELS.."Button"..i, newList)
 			newButton:SetID(i);
 		end
 	end
@@ -659,13 +798,13 @@ function L_UIDropDownMenu_CreateFrames(level, index)
 		L_UIDROPDOWNMENU_MAXBUTTONS = L_UIDROPDOWNMENU_MAXBUTTONS + 1;
 		for i=1, L_UIDROPDOWNMENU_MAXLEVELS do
 			--local newButton = CreateFrame("Button", "L_DropDownList"..i.."Button"..L_UIDROPDOWNMENU_MAXBUTTONS, _G["L_DropDownList"..i], "L_UIDropDownMenuButtonTemplate");
-			local newButton = create_UIDropDownMenuButton("L_DropDownList"..i.."Button"..L_UIDROPDOWNMENU_MAXBUTTONS, _G["L_DropDownList"..i])
+			local newButton = create_MenuButton("L_DropDownList"..i.."Button"..L_UIDROPDOWNMENU_MAXBUTTONS, _G["L_DropDownList"..i])
 			newButton:SetID(L_UIDROPDOWNMENU_MAXBUTTONS);
 		end
 	end
 end

-function L_UIDropDownMenu_AddSeparator(level)
+function lib:UIDropDownMenu_AddSeparator(level)
 	local separatorInfo = {
 		hasArrow = false;
 		dist = 0;
@@ -692,10 +831,22 @@ function L_UIDropDownMenu_AddSeparator(level)
 		},
 	};

-	L_UIDropDownMenu_AddButton(separatorInfo, level);
+	lib:UIDropDownMenu_AddButton(separatorInfo, level);
+end
+
+function lib:UIDropDownMenu_AddSpace(level)
+	local spaceInfo = {
+		hasArrow = false,
+		dist = 0,
+		isTitle = true,
+		isUninteractable = true,
+		notCheckable = true,
+	};
+
+	lib:UIDropDownMenu_AddButton(spaceInfo, level);
 end

-function L_UIDropDownMenu_AddButton(info, level)
+function lib:UIDropDownMenu_AddButton(info, level)
 	--[[
 	Might to uncomment this if there are performance issues
 	if ( not L_UIDROPDOWNMENU_OPEN_MENU ) then
@@ -707,12 +858,18 @@ function L_UIDropDownMenu_AddButton(info, level)
 	end

 	local listFrame = _G["L_DropDownList"..level];
-	local index = listFrame and (listFrame.numButtons + 1) or 1;
+	local index;
+	if (listFrame) then
+		index = listFrame.numButtons and (listFrame.numButtons + 1) or 1
+	else
+		index = 0
+	end
+	--local index = listFrame and (listFrame.numButtons + 1) or 1;
 	local width;

-	L_UIDropDownMenuDelegate:SetAttribute("createframes-level", level);
-	L_UIDropDownMenuDelegate:SetAttribute("createframes-index", index);
-	L_UIDropDownMenuDelegate:SetAttribute("createframes", true);
+	delegateFrame:SetAttribute("createframes-level", level);
+	delegateFrame:SetAttribute("createframes-index", index);
+	delegateFrame:SetAttribute("createframes", true);

 	listFrame = listFrame or _G["L_DropDownList"..level];
 	local listFrameName = listFrame:GetName();
@@ -809,13 +966,15 @@ function L_UIDropDownMenu_AddButton(info, level)
 		button.icon = info.icon;
 		button.iconInfo = info.iconInfo;

-		L_UIDropDownMenu_SetIconImage(icon, info.icon, info.iconInfo);
+		lib:UIDropDownMenu_SetIconImage(icon, info.icon, info.iconInfo);
 		icon:ClearAllPoints();
 		icon:SetPoint("LEFT");
 	end

 	-- Pass through attributes
 	button.func = info.func;
+	button.funcOnEnter = info.funcOnEnter;
+	button.funcOnLeave = info.funcOnLeave;
 	button.owner = info.owner;
 	button.hasOpacity = info.hasOpacity;
 	button.opacity = info.opacity;
@@ -840,6 +999,7 @@ function L_UIDropDownMenu_AddButton(info, level)
 	button.padding = info.padding;
 	button.icon = info.icon;
 	button.mouseOverIcon = info.mouseOverIcon;
+	button.ignoreAsMenuSelection = info.ignoreAsMenuSelection;

 	if ( info.value ) then
 		button.value = info.value;
@@ -893,16 +1053,16 @@ function L_UIDropDownMenu_AddButton(info, level)

 	-- See if button is selected by id or name
 	if ( frame ) then
-		if ( L_UIDropDownMenu_GetSelectedName(frame) ) then
-			if ( button:GetText() == L_UIDropDownMenu_GetSelectedName(frame) ) then
+		if ( lib:UIDropDownMenu_GetSelectedName(frame) ) then
+			if ( button:GetText() == lib:UIDropDownMenu_GetSelectedName(frame) ) then
 				info.checked = 1;
 			end
-		elseif ( L_UIDropDownMenu_GetSelectedID(frame) ) then
-			if ( button:GetID() == L_UIDropDownMenu_GetSelectedID(frame) ) then
+		elseif ( lib:UIDropDownMenu_GetSelectedID(frame) ) then
+			if ( button:GetID() == lib:UIDropDownMenu_GetSelectedID(frame) ) then
 				info.checked = 1;
 			end
-		elseif ( L_UIDropDownMenu_GetSelectedValue(frame) ) then
-			if ( button.value == L_UIDropDownMenu_GetSelectedValue(frame) ) then
+		elseif ( lib:UIDropDownMenu_GetSelectedValue(frame) ) then
+			if ( button.value == lib:UIDropDownMenu_GetSelectedValue(frame) ) then
 				info.checked = 1;
 			end
 		end
@@ -971,7 +1131,11 @@ function L_UIDropDownMenu_AddButton(info, level)
 	-- If has a colorswatch, show it and vertex color it
 	local colorSwatch = _G[listFrameName.."Button"..index.."ColorSwatch"];
 	if ( info.hasColorSwatch ) then
-		_G["L_DropDownList"..level.."Button"..index.."ColorSwatch".."NormalTexture"]:SetVertexColor(info.r, info.g, info.b);
+		if (WoWClassicEra or WoWClassicTBC) 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);
+		end
 		button.r = info.r;
 		button.g = info.g;
 		button.b = info.b;
@@ -980,15 +1144,15 @@ function L_UIDropDownMenu_AddButton(info, level)
 		colorSwatch:Hide();
 	end

-	L_UIDropDownMenu_CheckAddCustomFrame(listFrame, button, info);
+	lib:UIDropDownMenu_CheckAddCustomFrame(listFrame, button, info);

 	button:SetShown(button.customFrame == nil);

 	button.minWidth = info.minWidth;

-	width = max(L_UIDropDownMenu_GetButtonWidth(button), info.minWidth or 0);
+	width = max(lib:UIDropDownMenu_GetButtonWidth(button), info.minWidth or 0);
 	--Set maximum button width
-	if ( width > listFrame.maxWidth ) then
+	if ( width > (listFrame and listFrame.maxWidth or 0) ) then
 		listFrame.maxWidth = width;
 	end

@@ -996,7 +1160,7 @@ function L_UIDropDownMenu_AddButton(info, level)
 	listFrame:SetHeight((index * L_UIDROPDOWNMENU_BUTTON_HEIGHT) + (L_UIDROPDOWNMENU_BORDER_HEIGHT * 2));
 end

-function L_UIDropDownMenu_CheckAddCustomFrame(self, button, info)
+function lib:UIDropDownMenu_CheckAddCustomFrame(self, button, info)
 	local customFrame = info.customFrame;
 	button.customFrame = customFrame;
 	if customFrame then
@@ -1005,20 +1169,20 @@ function L_UIDropDownMenu_CheckAddCustomFrame(self, button, info)
 		customFrame:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0);
 		customFrame:Show();

-		L_UIDropDownMenu_RegisterCustomFrame(self, customFrame);
+		lib:UIDropDownMenu_RegisterCustomFrame(self, customFrame);
 	end
 end

-function L_UIDropDownMenu_RegisterCustomFrame(self, customFrame)
+function lib:UIDropDownMenu_RegisterCustomFrame(self, customFrame)
 	self.customFrames = self.customFrames or {}
 	table.insert(self.customFrames, customFrame);
 end

-function L_UIDropDownMenu_GetMaxButtonWidth(self)
+function lib:UIDropDownMenu_GetMaxButtonWidth(self)
 	local maxWidth = 0;
 	for i=1, self.numButtons do
 		local button = _G[self:GetName().."Button"..i];
-		local width = L_UIDropDownMenu_GetButtonWidth(button);
+		local width = lib:UIDropDownMenu_GetButtonWidth(button);
 		if ( width > maxWidth ) then
 			maxWidth = width;
 		end
@@ -1026,7 +1190,7 @@ function L_UIDropDownMenu_GetMaxButtonWidth(self)
 	return maxWidth;
 end

-function L_UIDropDownMenu_GetButtonWidth(button)
+function lib:UIDropDownMenu_GetButtonWidth(button)
 	local minWidth = button.minWidth or 0;
 	if button.customFrame and button.customFrame:IsShown() then
 		return math.max(minWidth, button.customFrame:GetPreferredEntryWidth());
@@ -1068,7 +1232,7 @@ function L_UIDropDownMenu_GetButtonWidth(button)
 	return math.max(minWidth, width);
 end

-function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
+function lib:UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
 	local maxWidth = 0;
 	local somethingChecked = nil;
 	if ( not dropdownLevel ) then
@@ -1084,16 +1248,16 @@ function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)

 		if(i <= listFrame.numButtons) then
 			-- See if checked or not
-			if ( L_UIDropDownMenu_GetSelectedName(frame) ) then
-				if ( button:GetText() == L_UIDropDownMenu_GetSelectedName(frame) ) then
+			if ( lib:UIDropDownMenu_GetSelectedName(frame) ) then
+				if ( button:GetText() == lib:UIDropDownMenu_GetSelectedName(frame) ) then
 					checked = 1;
 				end
-			elseif ( L_UIDropDownMenu_GetSelectedID(frame) ) then
-				if ( button:GetID() == L_UIDropDownMenu_GetSelectedID(frame) ) then
+			elseif ( lib:UIDropDownMenu_GetSelectedID(frame) ) then
+				if ( button:GetID() == lib:UIDropDownMenu_GetSelectedID(frame) ) then
 					checked = 1;
 				end
-			elseif ( L_UIDropDownMenu_GetSelectedValue(frame) ) then
-				if ( button.value == L_UIDropDownMenu_GetSelectedValue(frame) ) then
+			elseif ( lib:UIDropDownMenu_GetSelectedValue(frame) ) then
+				if ( button.value == lib:UIDropDownMenu_GetSelectedValue(frame) ) then
 					checked = 1;
 				end
 			end
@@ -1107,16 +1271,18 @@ function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
 			local checkImage = _G["L_DropDownList"..dropdownLevel.."Button"..i.."Check"];
 			local uncheckImage = _G["L_DropDownList"..dropdownLevel.."Button"..i.."UnCheck"];
 			if ( checked ) then
-				somethingChecked = true;
-				local icon = GetChild(frame, frame:GetName(), "Icon");
-				if (button.iconOnly and icon and button.icon) then
-					L_UIDropDownMenu_SetIconImage(icon, button.icon, button.iconInfo);
-				elseif ( useValue ) then
-					L_UIDropDownMenu_SetText(frame, button.value);
-					icon:Hide();
-				else
-					L_UIDropDownMenu_SetText(frame, button:GetText());
-					icon:Hide();
+				if not button.ignoreAsMenuSelection then
+					somethingChecked = true;
+					local icon = GetChild(frame, frame:GetName(), "Icon");
+					if (button.iconOnly and icon and button.icon) then
+						lib:UIDropDownMenu_SetIconImage(icon, button.icon, button.iconInfo);
+					elseif ( useValue ) then
+						lib:UIDropDownMenu_SetText(frame, button.value);
+						icon:Hide();
+					else
+						lib:UIDropDownMenu_SetText(frame, button:GetText());
+						icon:Hide();
+					end
 				end
 				button:LockHighlight();
 				checkImage:Show();
@@ -1129,36 +1295,38 @@ function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel)
 		end

 		if ( button:IsShown() ) then
-			local width = L_UIDropDownMenu_GetButtonWidth(button);
+			local width = lib:UIDropDownMenu_GetButtonWidth(button);
 			if ( width > maxWidth ) then
 				maxWidth = width;
 			end
 		end
 	end
 	if(somethingChecked == nil) then
-		L_UIDropDownMenu_SetText(frame, VIDEO_QUALITY_LABEL6);
+		lib:UIDropDownMenu_SetText(frame, VIDEO_QUALITY_LABEL6);
+		local icon = GetChild(frame, frame:GetName(), "Icon");
+		icon:Hide();
 	end
 	if (not frame.noResize) then
 		for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do
 			local button = _G["L_DropDownList"..dropdownLevel.."Button"..i];
 			button:SetWidth(maxWidth);
 		end
-		L_UIDropDownMenu_RefreshDropDownSize(_G["L_DropDownList"..dropdownLevel]);
+		lib:UIDropDownMenu_RefreshDropDownSize(_G["L_DropDownList"..dropdownLevel]);
 	end
 end

-function L_UIDropDownMenu_RefreshAll(frame, useValue)
+function lib:UIDropDownMenu_RefreshAll(frame, useValue)
 	for dropdownLevel = L_UIDROPDOWNMENU_MENU_LEVEL, 2, -1 do
 		local listFrame = _G["L_DropDownList"..dropdownLevel];
 		if ( listFrame:IsShown() ) then
-			L_UIDropDownMenu_Refresh(frame, nil, dropdownLevel);
+			lib:UIDropDownMenu_Refresh(frame, nil, dropdownLevel);
 		end
 	end
 	-- useValue is the text on the dropdown, only needs to be set once
-	L_UIDropDownMenu_Refresh(frame, useValue, 1);
+	lib:UIDropDownMenu_Refresh(frame, useValue, 1);
 end

-function L_UIDropDownMenu_SetIconImage(icon, texture, info)
+function lib:UIDropDownMenu_SetIconImage(icon, texture, info)
 	icon:SetTexture(texture);
 	if ( info.tCoordLeft ) then
 		icon:SetTexCoord(info.tCoordLeft, info.tCoordRight, info.tCoordTop, info.tCoordBottom);
@@ -1178,33 +1346,33 @@ function L_UIDropDownMenu_SetIconImage(icon, texture, info)
 	icon:Show();
 end

-function L_UIDropDownMenu_SetSelectedName(frame, name, useValue)
+function lib:UIDropDownMenu_SetSelectedName(frame, name, useValue)
 	frame.selectedName = name;
 	frame.selectedID = nil;
 	frame.selectedValue = nil;
-	L_UIDropDownMenu_Refresh(frame, useValue);
+	lib:UIDropDownMenu_Refresh(frame, useValue);
 end

-function L_UIDropDownMenu_SetSelectedValue(frame, value, useValue)
+function lib:UIDropDownMenu_SetSelectedValue(frame, value, useValue)
 	-- useValue will set the value as the text, not the name
 	frame.selectedName = nil;
 	frame.selectedID = nil;
 	frame.selectedValue = value;
-	L_UIDropDownMenu_Refresh(frame, useValue);
+	lib:UIDropDownMenu_Refresh(frame, useValue);
 end

-function L_UIDropDownMenu_SetSelectedID(frame, id, useValue)
+function lib:UIDropDownMenu_SetSelectedID(frame, id, useValue)
 	frame.selectedID = id;
 	frame.selectedName = nil;
 	frame.selectedValue = nil;
-	L_UIDropDownMenu_Refresh(frame, useValue);
+	lib:UIDropDownMenu_Refresh(frame, useValue);
 end

-function L_UIDropDownMenu_GetSelectedName(frame)
+function lib:UIDropDownMenu_GetSelectedName(frame)
 	return frame.selectedName;
 end

-function L_UIDropDownMenu_GetSelectedID(frame)
+function lib:UIDropDownMenu_GetSelectedID(frame)
 	if ( frame.selectedID ) then
 		return frame.selectedID;
 	else
@@ -1213,12 +1381,12 @@ function L_UIDropDownMenu_GetSelectedID(frame)
 		for i=1, listFrame.numButtons do
 			local button = _G["L_DropDownList"..L_UIDROPDOWNMENU_MENU_LEVEL.."Button"..i];
 			-- See if checked or not
-			if ( L_UIDropDownMenu_GetSelectedName(frame) ) then
-				if ( button:GetText() == L_UIDropDownMenu_GetSelectedName(frame) ) then
+			if ( lib:UIDropDownMenu_GetSelectedName(frame) ) then
+				if ( button:GetText() == lib:UIDropDownMenu_GetSelectedName(frame) ) then
 					return i;
 				end
-			elseif ( L_UIDropDownMenu_GetSelectedValue(frame) ) then
-				if ( button.value == L_UIDropDownMenu_GetSelectedValue(frame) ) then
+			elseif ( lib:UIDropDownMenu_GetSelectedValue(frame) ) then
+				if ( button.value == lib:UIDropDownMenu_GetSelectedValue(frame) ) then
 					return i;
 				end
 			end
@@ -1226,71 +1394,26 @@ function L_UIDropDownMenu_GetSelectedID(frame)
 	end
 end

-function L_UIDropDownMenu_GetSelectedValue(frame)
+function lib:UIDropDownMenu_GetSelectedValue(frame)
 	return frame.selectedValue;
 end

-function L_UIDropDownMenuButton_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
-end
-
-function L_HideDropDownMenu(level)
+function lib:HideDropDownMenu(level)
 	local listFrame = _G["L_DropDownList"..level];
 	listFrame:Hide();
 end

-function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay)
+function lib:ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay)
 	if ( not level ) then
 		level = 1;
 	end
-	L_UIDropDownMenuDelegate:SetAttribute("createframes-level", level);
-	L_UIDropDownMenuDelegate:SetAttribute("createframes-index", 0);
-	L_UIDropDownMenuDelegate:SetAttribute("createframes", true);
+	delegateFrame:SetAttribute("createframes-level", level);
+	delegateFrame:SetAttribute("createframes-index", 0);
+	delegateFrame:SetAttribute("createframes", true);
 	L_UIDROPDOWNMENU_MENU_LEVEL = level;
 	L_UIDROPDOWNMENU_MENU_VALUE = value;
-	local listFrame = _G["L_DropDownList"..level];
 	local listFrameName = "L_DropDownList"..level;
+	local listFrame = _G[listFrameName];
 	local tempFrame;
 	local point, relativePoint, relativeTo;
 	if ( not dropDownFrame ) then
@@ -1323,7 +1446,7 @@ function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset,
 		-- Display stuff
 		-- Level specific stuff
 		if ( level == 1 ) then
-			L_UIDropDownMenuDelegate:SetAttribute("openmenu", dropDownFrame);
+			delegateFrame:SetAttribute("openmenu", dropDownFrame);
 			listFrame:ClearAllPoints();
 			-- If there's no specified anchorName then use left side of the dropdown menu
 			if ( not anchorName ) then
@@ -1408,19 +1531,21 @@ function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset,

 		-- Change list box appearance depending on display mode
 		if ( dropDownFrame and dropDownFrame.displayMode == "MENU" ) then
-			_G[listFrameName.."Backdrop"]:Hide();
+			_G[listFrameName.."Border"]:Hide();
 			_G[listFrameName.."MenuBackdrop"]:Show();
 		else
-			_G[listFrameName.."Backdrop"]:Show();
+			_G[listFrameName.."Border"]:Show();
 			_G[listFrameName.."MenuBackdrop"]:Hide();
 		end
 		dropDownFrame.menuList = menuList;
-		L_UIDropDownMenu_Initialize(dropDownFrame, dropDownFrame.initialize, nil, level, menuList);
+		lib:UIDropDownMenu_Initialize(dropDownFrame, dropDownFrame.initialize, nil, level, menuList);
 		-- If no items in the drop down don't show it
 		if ( listFrame.numButtons == 0 ) then
 			return;
 		end

+		listFrame.onShow = dropDownFrame.listFrameOnShow;
+
 		-- Check to see if the dropdownlist is off the screen, if it is anchor it to the top of the dropdown button
 		listFrame:Show();
 		-- Hack since GetCenter() is returning coords relative to 1024x768
@@ -1504,37 +1629,63 @@ function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset,
 	end
 end

-function L_CloseDropDownMenus(level)
+function lib:CloseDropDownMenus(level)
 	if ( not level ) then
 		level = 1;
 	end
 	for i=level, L_UIDROPDOWNMENU_MAXLEVELS do
 		_G["L_DropDownList"..i]:Hide();
 	end
+	-- yes, we also want to close the menus which created by built-in UIDropDownMenus
+	for i=level, UIDROPDOWNMENU_MAXLEVELS do
+		_G["DropDownList"..i]:Hide();
+	end
 end

-function L_UIDropDownMenu_OnHide(self)
-	local id = self:GetID()
-	if ( self.onHide ) then
-		self.onHide(id+1);
-		self.onHide = nil;
+local function containsMouse()
+	local result = false
+
+	for i = 1, L_UIDROPDOWNMENU_MAXLEVELS do
+		local dropdown = _G["L_DropDownList"..i];
+		if dropdown:IsShown() and dropdown:IsMouseOver() then
+			result = true;
+		end
 	end
-	L_CloseDropDownMenus(id+1);
-	L_OPEN_DROPDOWNMENUS[id] = nil;
-	if (id == 1) then
-		L_UIDROPDOWNMENU_OPEN_MENU = nil;
+	for i = 1, UIDROPDOWNMENU_MAXLEVELS do
+		local dropdown = _G["DropDownList"..i];
+		if dropdown:IsShown() and dropdown:IsMouseOver() then
+			result = true;
+		end
 	end

-	if self.customFrames then
-		for index, frame in ipairs(self.customFrames) do
-			frame:Hide();
+
+	return result;
+end
+
+function lib:containsMouse()
+	containsMouse()
+end
+
+-- GLOBAL_MOUSE_DOWN event is only available in retail, not classic
+function lib:UIDropDownMenu_HandleGlobalMouseEvent(button, event)
+	if event == "GLOBAL_MOUSE_DOWN" and (button == "LeftButton" or button == "RightButton") then
+		if not containsMouse() then
+			lib:CloseDropDownMenus();
 		end
+	end
+end
+
+-- hooking UIDropDownMenu_HandleGlobalMouseEvent
+do
+	if lib and WoWRetail then
+		hooksecurefunc("UIDropDownMenu_HandleGlobalMouseEvent", function(button, event)
+			lib:UIDropDownMenu_HandleGlobalMouseEvent(button, event)
+		end)

-		self.customFrames = nil;
 	end
 end

-function L_UIDropDownMenu_SetWidth(frame, width, padding)
+function lib:UIDropDownMenu_SetWidth(frame, width, padding)
 	local frameName = frame:GetName();
 	GetChild(frame, frameName, "Middle"):SetWidth(width);
 	local defaultPadding = 25;
@@ -1551,7 +1702,7 @@ function L_UIDropDownMenu_SetWidth(frame, width, padding)
 	frame.noResize = 1;
 end

-function L_UIDropDownMenu_SetButtonWidth(frame, width)
+function lib:UIDropDownMenu_SetButtonWidth(frame, width)
 	local frameName = frame:GetName();
 	if ( width == "TEXT" ) then
 		width = GetChild(frame, frameName, "Text"):GetWidth();
@@ -1561,22 +1712,22 @@ function L_UIDropDownMenu_SetButtonWidth(frame, width)
 	frame.noResize = 1;
 end

-function L_UIDropDownMenu_SetText(frame, text)
+function lib:UIDropDownMenu_SetText(frame, text)
 	local frameName = frame:GetName();
 	GetChild(frame, frameName, "Text"):SetText(text);
 end

-function L_UIDropDownMenu_GetText(frame)
+function lib:UIDropDownMenu_GetText(frame)
 	local frameName = frame:GetName();
 	return GetChild(frame, frameName, "Text"):GetText();
 end

-function L_UIDropDownMenu_ClearAll(frame)
+function lib:UIDropDownMenu_ClearAll(frame)
 	-- Previous code refreshed the menu quite often and was a performance bottleneck
 	frame.selectedID = nil;
 	frame.selectedName = nil;
 	frame.selectedValue = nil;
-	L_UIDropDownMenu_SetText(frame, "");
+	lib:UIDropDownMenu_SetText(frame, "");

 	local button, checkImage, uncheckImage;
 	for i=1, L_UIDROPDOWNMENU_MAXBUTTONS do
@@ -1590,23 +1741,23 @@ function L_UIDropDownMenu_ClearAll(frame)
 	end
 end

-function L_UIDropDownMenu_JustifyText(frame, justification)
+function lib:UIDropDownMenu_JustifyText(frame, justification, customXOffset)
 	local frameName = frame:GetName();
 	local text = GetChild(frame, frameName, "Text");
 	text:ClearAllPoints();
 	if ( justification == "LEFT" ) then
-		text:SetPoint("LEFT", GetChild(frame, frameName, "Left"), "LEFT", 27, 2);
+		text:SetPoint("LEFT", GetChild(frame, frameName, "Left"), "LEFT", customXOffset or 27, 2);
 		text:SetJustifyH("LEFT");
 	elseif ( justification == "RIGHT" ) then
-		text:SetPoint("RIGHT", GetChild(frame, frameName, "Right"), "RIGHT", -43, 2);
+		text:SetPoint("RIGHT", GetChild(frame, frameName, "Right"), "RIGHT", customXOffset or -43, 2);
 		text:SetJustifyH("RIGHT");
 	elseif ( justification == "CENTER" ) then
-		text:SetPoint("CENTER", GetChild(frame, frameName, "Middle"), "CENTER", -5, 2);
+		text:SetPoint("CENTER", GetChild(frame, frameName, "Middle"), "CENTER", customXOffset or -5, 2);
 		text:SetJustifyH("CENTER");
 	end
 end

-function L_UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint)
+function lib:UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint)
 	dropdown.xOffset = xOffset;
 	dropdown.yOffset = yOffset;
 	dropdown.point = point;
@@ -1614,7 +1765,7 @@ function L_UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeT
 	dropdown.relativePoint = relativePoint;
 end

-function L_UIDropDownMenu_GetCurrentDropDown()
+function lib:UIDropDownMenu_GetCurrentDropDown()
 	if ( L_UIDROPDOWNMENU_OPEN_MENU ) then
 		return L_UIDROPDOWNMENU_OPEN_MENU;
 	elseif ( L_UIDROPDOWNMENU_INIT_MENU ) then
@@ -1622,32 +1773,32 @@ function L_UIDropDownMenu_GetCurrentDropDown()
 	end
 end

-function L_UIDropDownMenuButton_GetChecked(self)
+function lib:UIDropDownMenuButton_GetChecked(self)
 	return _G[self:GetName().."Check"]:IsShown();
 end

-function L_UIDropDownMenuButton_GetName(self)
+function lib:UIDropDownMenuButton_GetName(self)
 	return _G[self:GetName().."NormalText"]:GetText();
 end

-function L_UIDropDownMenuButton_OpenColorPicker(self, button)
+function lib:UIDropDownMenuButton_OpenColorPicker(self, button)
 	securecall("CloseMenus");
 	if ( not button ) then
 		button = self;
 	end
 	L_UIDROPDOWNMENU_MENU_VALUE = button.value;
-	L_OpenColorPicker(button);
+	lib:OpenColorPicker(button);
 end

-function L_UIDropDownMenu_DisableButton(level, id)
+function lib:UIDropDownMenu_DisableButton(level, id)
 	_G["L_DropDownList"..level.."Button"..id]:Disable();
 end

-function L_UIDropDownMenu_EnableButton(level, id)
+function lib:UIDropDownMenu_EnableButton(level, id)
 	_G["L_DropDownList"..level.."Button"..id]:Enable();
 end

-function L_UIDropDownMenu_SetButtonText(level, id, text, colorCode)
+function lib:UIDropDownMenu_SetButtonText(level, id, text, colorCode)
 	local button = _G["L_DropDownList"..level.."Button"..id];
 	if ( colorCode) then
 		button:SetText(colorCode..text.."|r");
@@ -1656,41 +1807,43 @@ function L_UIDropDownMenu_SetButtonText(level, id, text, colorCode)
 	end
 end

-function L_UIDropDownMenu_SetButtonNotClickable(level, id)
+function lib:UIDropDownMenu_SetButtonNotClickable(level, id)
 	_G["L_DropDownList"..level.."Button"..id]:SetDisabledFontObject(GameFontHighlightSmallLeft);
 end

-function L_UIDropDownMenu_SetButtonClickable(level, id)
+function lib:UIDropDownMenu_SetButtonClickable(level, id)
 	_G["L_DropDownList"..level.."Button"..id]:SetDisabledFontObject(GameFontDisableSmallLeft);
 end

-function L_UIDropDownMenu_DisableDropDown(dropDown)
+function lib:UIDropDownMenu_DisableDropDown(dropDown)
 	local dropDownName = dropDown:GetName();
 	local label = GetChild(dropDown, dropDownName, "Label");
-	if ( label ) then
-		label:SetVertexColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
+	if label then
+		label:SetVertexColor(GRAY_FONT_COLOR:GetRGB());
 	end
-	GetChild(dropDown, dropDownName, "Text"):SetVertexColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
+	GetChild(dropDown, dropDownName, "Icon"):SetVertexColor(GRAY_FONT_COLOR:GetRGB());
+	GetChild(dropDown, dropDownName, "Text"):SetVertexColor(GRAY_FONT_COLOR:GetRGB());
 	GetChild(dropDown, dropDownName, "Button"):Disable();
 	dropDown.isDisabled = 1;
 end

-function L_UIDropDownMenu_EnableDropDown(dropDown)
+function lib:UIDropDownMenu_EnableDropDown(dropDown)
 	local dropDownName = dropDown:GetName();
 	local label = GetChild(dropDown, dropDownName, "Label");
-	if ( label ) then
-		label:SetVertexColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
+	if label then
+		label:SetVertexColor(NORMAL_FONT_COLOR:GetRGB());
 	end
-	GetChild(dropDown, dropDownName, "Text"):SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
+	GetChild(dropDown, dropDownName, "Icon"):SetVertexColor(HIGHLIGHT_FONT_COLOR:GetRGB());
+	GetChild(dropDown, dropDownName, "Text"):SetVertexColor(HIGHLIGHT_FONT_COLOR:GetRGB());
 	GetChild(dropDown, dropDownName, "Button"):Enable();
 	dropDown.isDisabled = nil;
 end

-function L_UIDropDownMenu_IsEnabled(dropDown)
+function lib:UIDropDownMenu_IsEnabled(dropDown)
 	return not dropDown.isDisabled;
 end

-function L_UIDropDownMenu_GetValue(id)
+function lib:UIDropDownMenu_GetValue(id)
 	--Only works if the dropdown has just been initialized, lame, I know =(
 	local button = _G["L_DropDownList1Button"..id];
 	if ( button ) then
@@ -1700,7 +1853,7 @@ function L_UIDropDownMenu_GetValue(id)
 	end
 end

-function L_OpenColorPicker(info)
+function lib:OpenColorPicker(info)
 	ColorPickerFrame.func = info.swatchFunc;
 	ColorPickerFrame.hasOpacity = info.hasOpacity;
 	ColorPickerFrame.opacityFunc = info.opacityFunc;
@@ -1713,6 +1866,171 @@ function L_OpenColorPicker(info)
 	ShowUIPanel(ColorPickerFrame);
 end

-function L_ColorPicker_GetPreviousValues()
+function lib:ColorPicker_GetPreviousValues()
 	return ColorPickerFrame.previousValues.r, ColorPickerFrame.previousValues.g, ColorPickerFrame.previousValues.b;
 end
+
+-- //////////////////////////////////////////////////////////////
+-- LibUIDropDownMenuTemplates
+-- //////////////////////////////////////////////////////////////
+
+-- Custom dropdown buttons are instantiated by some external system.
+-- When calling L_UIDropDownMenu_AddButton that system sets info.customFrame to the instance of the frame it wants to place on the menu.
+-- The dropdown menu creates its button for the entry as it normally would, but hides all elements.  The custom frame is then anchored
+-- to that button and assumes responsibility for all relevant dropdown menu operations.
+-- The hidden button will request a size that it should become from the custom frame.
+
+lib.DropDownMenuButtonMixin = {}
+
+function lib.DropDownMenuButtonMixin:OnEnter(...)
+	ExecuteFrameScript(self:GetParent(), "OnEnter", ...);
+end
+
+function lib.DropDownMenuButtonMixin:OnLeave(...)
+	ExecuteFrameScript(self:GetParent(), "OnLeave", ...);
+end
+
+function lib.DropDownMenuButtonMixin:OnMouseDown(button)
+	if self:IsEnabled() then
+		lib:ToggleDropDownMenu(nil, nil, self:GetParent());
+		PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+	end
+end
+
+lib.LargeDropDownMenuButtonMixin = CreateFromMixins(lib.DropDownMenuButtonMixin);
+
+function lib.LargeDropDownMenuButtonMixin:OnMouseDown(button)
+	if self:IsEnabled() then
+		local parent = self:GetParent();
+		lib:ToggleDropDownMenu(nil, nil, parent, parent, -8, 8);
+		PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+	end
+end
+
+lib.DropDownExpandArrowMixin = {};
+
+function lib.DropDownExpandArrowMixin:OnEnter()
+	local level =  self:GetParent():GetParent():GetID() + 1;
+
+	lib:CloseDropDownMenus(level);
+
+	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);
+		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);
+		PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+	end
+end
+
+lib.UIDropDownCustomMenuEntryMixin = {};
+
+function lib.UIDropDownCustomMenuEntryMixin:GetPreferredEntryWidth()
+	-- NOTE: Only width is currently supported, dropdown menus size vertically based on how many buttons are present.
+	return self:GetWidth();
+end
+
+function lib.UIDropDownCustomMenuEntryMixin:OnSetOwningButton()
+	-- for derived objects to implement
+end
+
+function lib.UIDropDownCustomMenuEntryMixin:SetOwningButton(button)
+	self:SetParent(button:GetParent());
+	self.owningButton = button;
+	self:OnSetOwningButton();
+end
+
+function lib.UIDropDownCustomMenuEntryMixin:GetOwningDropdown()
+	return self.owningButton:GetParent();
+end
+
+function lib.UIDropDownCustomMenuEntryMixin:SetContextData(contextData)
+	self.contextData = contextData;
+end
+
+function lib.UIDropDownCustomMenuEntryMixin:GetContextData()
+	return self.contextData;
+end
+
+-- //////////////////////////////////////////////////////////////
+-- L_UIDropDownCustomMenuEntryTemplate
+function lib:Create_UIDropDownCustomMenuEntry(name, parent)
+	local f = _G[name] or CreateFrame("Frame", name, parent or nil)
+	f:EnableMouse(true)
+	f:Hide()
+
+	-- I am not 100% sure if below works for replacing the mixins
+	f:SetScript("GetPreferredEntryWidth", function(self)
+		return self:GetWidth()
+	end)
+	f:SetScript("SetOwningButton", function(self, button)
+		self:SetParent(button:GetParent())
+		self.owningButton = button
+		self:OnSetOwningButton()
+	end)
+	f:SetScript("GetOwningDropdown", function(self)
+		return self.owningButton:GetParent()
+	end)
+	f:SetScript("SetContextData", function(self, contextData)
+		self.contextData = contextData
+	end)
+	f:SetScript("GetContextData", function(self)
+		return self.contextData
+	end)
+
+	return f
+end
+
+-- //////////////////////////////////////////////////////////////
+-- UIDropDownMenuButtonScriptTemplate
+--
+-- TBD
+--
+
+-- //////////////////////////////////////////////////////////////
+-- LargeUIDropDownMenuTemplate
+--
+-- TBD
+--
+
+-- //////////////////////////////////////////////////////////////
+-- EasyMenu
+-- Simplified Menu Display System
+--	This is a basic system for displaying a menu from a structure table.
+--
+--	Args:
+--		menuList - menu table
+--		menuFrame - the UI frame to populate
+--		anchor - where to anchor the frame (e.g. CURSOR)
+--		x - x offset
+--		y - y offset
+--		displayMode - border type
+--		autoHideDelay - how long until the menu disappears
+local function easyMenu_Initialize( frame, level, menuList )
+	for index = 1, #menuList do
+		local value = menuList[index]
+		if (value.text) then
+			value.index = index;
+			lib:UIDropDownMenu_AddButton( value, level );
+		end
+	end
+end
+
+function lib:EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay )
+	if ( displayMode == "MENU" ) then
+		menuFrame.displayMode = displayMode;
+	end
+	lib:UIDropDownMenu_Initialize(menuFrame, easyMenu_Initialize, displayMode, nil, menuList);
+	lib:ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList, nil, autoHideDelay);
+end
+
+function lib:EasyMenu_Initialize( frame, level, menuList )
+	easyMenu_Initialize( frame, level, menuList )
+end
+
diff --git a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.xml b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.xml
index dc97e9d..bc7d69e 100755
--- a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.xml
+++ b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenu.xml
@@ -1,10 +1,9 @@
-<!-- $Id: LibUIDropDownMenu.xml 40 2018-12-23 16:14:03Z arith $ -->
+<!-- $Id: LibUIDropDownMenu.xml 64 2020-11-18 13:13:15Z arithmandar $ -->
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
 	<Script file="LibUIDropDownMenu.lua"/>
-	<Include file="LibUIDropDownMenuTemplates.xml"/>
-	<Script file="LibEasyMenu.lua"/>
-<!--
+<!--	<Include file="LibUIDropDownMenuTemplates.xml"/>
+
 	<Button name="L_DropDownList1" toplevel="true" frameStrata="FULLSCREEN_DIALOG" inherits="L_UIDropDownListTemplate" hidden="true" id="1">
 		<Size>
 			<AbsDimension x="180" y="10"/>
diff --git a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.lua b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.lua
index 615f41d..28c8b8f 100755
--- a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.lua
+++ b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.lua
@@ -1,11 +1,11 @@
--- $Id: LibUIDropDownMenuTemplates.lua 40 2018-12-23 16:14:03Z arith $
+-- $Id: LibUIDropDownMenuTemplates.lua 64 2020-11-18 13:13:15Z arithmandar $
 -- ----------------------------------------------------------------------------
 -- Localized Lua globals.
 -- ----------------------------------------------------------------------------
-local _G = getfenv(0)
+--[[local _G = getfenv(0)
 -- ----------------------------------------------------------------------------
-local MAJOR_VERSION = "LibUIDropDownMenuTemplates-2.0"
-local MINOR_VERSION = 90000 + tonumber(("$Rev: 40 $"):match("%d+"))
+local MAJOR_VERSION = "LibUIDropDownMenuTemplates-3.0"
+local MINOR_VERSION = 90000 + tonumber(("$Rev: 64 $"):match("%d+"))

 local LibStub = _G.LibStub
 if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
@@ -18,6 +18,53 @@ if not Lib then return end
 -- to that button and assumes responsibility for all relevant dropdown menu operations.
 -- The hidden button will request a size that it should become from the custom frame.

+L_DropDownMenuButtonMixin = {}
+
+function L_DropDownMenuButtonMixin:OnEnter(...)
+	ExecuteFrameScript(self:GetParent(), "OnEnter", ...);
+end
+
+function L_DropDownMenuButtonMixin:OnLeave(...)
+	ExecuteFrameScript(self:GetParent(), "OnLeave", ...);
+end
+
+function L_DropDownMenuButtonMixin:OnMouseDown(button)
+	if self:IsEnabled() then
+		L_ToggleDropDownMenu(nil, nil, self:GetParent());
+		PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+	end
+end
+
+L_LargeDropDownMenuButtonMixin = CreateFromMixins(L_DropDownMenuButtonMixin);
+
+function L_LargeDropDownMenuButtonMixin:OnMouseDown(button)
+	if self:IsEnabled() then
+		local parent = self:GetParent();
+		L_ToggleDropDownMenu(nil, nil, parent, parent, -8, 8);
+		PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON);
+	end
+end
+
+L_DropDownExpandArrowMixin = {};
+
+function L_DropDownExpandArrowMixin:OnEnter()
+	local level =  self:GetParent():GetParent():GetID() + 1;
+
+	L_CloseDropDownMenus(level);
+
+	if self:IsEnabled() then
+		local listFrame = _G["L_DropDownList"..level];
+		if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then
+			L_ToggleDropDownMenu(level, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self);
+		end
+	end
+end
+
+function L_DropDownExpandArrowMixin:OnMouseDown(button)
+	if self:IsEnabled() then
+		L_ToggleDropDownMenu(self:GetParent():GetParent():GetID() + 1, self:GetParent().value, nil, nil, nil, nil, self:GetParent().menuList, self);
+	end
+end

 L_UIDropDownCustomMenuEntryMixin = {};

@@ -48,14 +95,6 @@ function L_UIDropDownCustomMenuEntryMixin:GetContextData()
 	return self.contextData;
 end

-function L_UIDropDownCustomMenuEntryMixin:OnEnter()
-	L_UIDropDownMenu_StopCounting(self:GetOwningDropdown());
-end
-
-function L_UIDropDownCustomMenuEntryMixin:OnLeave()
-	L_UIDropDownMenu_StartCounting(self:GetOwningDropdown());
-end
-
 -- //////////////////////////////////////////////////////////////
 -- L_UIDropDownCustomMenuEntryTemplate
 function L_Create_UIDropDownCustomMenuEntry(name, parent)
@@ -63,13 +102,6 @@ function L_Create_UIDropDownCustomMenuEntry(name, parent)
 	f:EnableMouse(true)
 	f:Hide()

-	f:SetScript("OnEnter", function(self)
-		L_UIDropDownMenu_StopCounting(self:GetOwningDropdown())
-	end)
-	f:SetScript("OnLeave", function(self)
-		L_UIDropDownMenu_StartCounting(self:GetOwningDropdown())
-	end)
-
 	-- I am not 100% sure if below works for replacing the mixins
 	f:SetScript("GetPreferredEntryWidth", function(self)
 		return self:GetWidth()
@@ -91,3 +123,4 @@ function L_Create_UIDropDownCustomMenuEntry(name, parent)

 	return f
 end
+]]
diff --git a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.xml b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.xml
index c2ac300..bf89718 100755
--- a/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.xml
+++ b/TitanClassic/libs/!LibUIDropDownMenu/LibUIDropDownMenu/LibUIDropDownMenuTemplates.xml
@@ -1,14 +1,49 @@
-<!-- $Id: LibUIDropDownMenuTemplates.xml 40 2018-12-23 16:14:03Z arith $ -->
+<!-- $Id: LibUIDropDownMenuTemplates.xml 64 2020-11-18 13:13:15Z arithmandar $ -->
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
 	<Include file="LibUIDropDownMenuTemplates.lua"/>
 <!--
-	<Frame name="L_UIDropDownCustomMenuEntryTemplate" enableMouse="true" hidden="true" mixin="L_UIDropDownCustomMenuEntryMixin" virtual="true">
+	<Frame name="L_UIDropDownCustomMenuEntryTemplate" enableMouse="true" hidden="true" mixin="L_UIDropDownCustomMenuEntryMixin" virtual="true/">
+
+	<Button name="ColorSwatchTemplate" virtual="true">
+		<Size x="16" y="16"/>
+		<Layers>
+			<Layer level="BACKGROUND" textureSubLevel="-3">
+				<Texture name="$parentSwatchBg" parentKey="SwatchBg" texelSnappingBias="0.0" snapToPixelGrid="false">
+					<Size x="14" y="14"/>
+					<Anchors>
+						<Anchor point="CENTER"/>
+					</Anchors>
+					<Color color="HIGHLIGHT_FONT_COLOR"/>
+				</Texture>
+			</Layer>
+			<Layer level="BACKGROUND" textureSubLevel="-2">
+				<Texture parentKey="InnerBorder" texelSnappingBias="0.0" snapToPixelGrid="false">
+					<Size x="12" y="12"/>
+					<Anchors>
+						<Anchor point="CENTER"/>
+					</Anchors>
+					<Color color="BLACK_FONT_COLOR"/>
+				</Texture>
+			</Layer>
+			<Layer level="BACKGROUND" textureSubLevel="-1">
+				<Texture parentKey="Color" texelSnappingBias="0.0" snapToPixelGrid="false">
+					<Size x="10" y="10"/>
+					<Anchors>
+						<Anchor point="CENTER"/>
+					</Anchors>
+					<Color color="HIGHLIGHT_FONT_COLOR"/>
+				</Texture>
+			</Layer>
+		</Layers>
 		<Scripts>
-			<OnEnter method="OnEnter"/>
-			<OnLeave method="OnLeave"/>
+			<OnShow inherit="prepend">
+				PixelUtil.SetSize(self.SwatchBg, 14, 14);
+				PixelUtil.SetSize(self.InnerBorder, 12, 12);
+				PixelUtil.SetSize(self.Color, 10, 10);
+			</OnShow>
 		</Scripts>
-	</Frame>
+	</Button>
 	<Button name="L_UIDropDownMenuButtonTemplate" virtual="true">
 		<Size x="100" y="16"/>
 		<Layers>
diff --git a/TitanClassicAmmo/TitanClassicAmmo.lua b/TitanClassicAmmo/TitanClassicAmmo.lua
index 594bf0c..2f2adf9 100644
--- a/TitanClassicAmmo/TitanClassicAmmo.lua
+++ b/TitanClassicAmmo/TitanClassicAmmo.lua
@@ -108,6 +108,11 @@ end

 local function GetAmmoCount()
 	weapon, weapon_type, ammo_type = GetWeaponInfo(rangedSlotID)
+--[[
+print("GetAmmoCount"
+.." '"..tostring(weapon).."'"
+)
+--]]

 	if IsThrown(ammo_type) then
 		ammo_name = select(1, GetItemInfo(GetInventoryItemID("player", rangedSlotID))) or _G["UNKNOWN"]
@@ -148,7 +153,7 @@ function TitanPanelAmmoButton_OnLoad(self)
 			ShowLabelText = true,
 			ShowRegularText = false,
 			ShowColoredText = true,
-			DisplayOnRightSide = true,
+			DisplayOnRightSide = true
 		},
 		savedVariables = {
 			ShowIcon = 1,
@@ -180,7 +185,7 @@ function TitanPanelAmmoButton_PLAYER_LOGIN()
 	-- Class check
 	if class ~= "ROGUE" and class ~= "WARRIOR" and class ~= "HUNTER" then
 		TitanPanelAmmoButton_PLAYER_LOGIN = nil
-		ammo_show = true
+		ClrAmmoInfo()
 		return
 	end

@@ -257,25 +262,26 @@ function TitanPanelAmmoButton_GetButtonText(id)

 	local labelText, ammoText, ammoRichText, color;

-	if not ammo_count then -- safeguard to prevent malformed labels
-		ClrAmmoInfo()
-	end
-
 	if (IsThrown(ammo_type)) then
 		labelText = L["TITAN_AMMO_BUTTON_LABEL_THROWN"];
 		ammoText = format(L["TITAN_AMMO_FORMAT"], ammo_count);
+		labelText = weapon_type.." : "
 		if TitanGetVar(TITAN_AMMO_ID, "ShowAmmoName") and ammo_name ~= "" then
 			ammoText = ammoText.."|cffffff9a".." ("..ammo_name..")".."|r"
 		end
-	else
+	elseif IsAmmo(ammo_type) then
 		labelText = L["TITAN_AMMO_BUTTON_LABEL_AMMO"];
+		labelText = weapon_type.." : "
 		ammoText = format(L["TITAN_AMMO_FORMAT"], ammo_count);
 		if TitanGetVar(TITAN_AMMO_ID, "ShowAmmoName") and ammo_name ~= "" then
 			ammoText = ammoText.."|cffffff9a".." ("..ammo_name..")".."|r"
 		end
+	else
+		ClrAmmoInfo()
+		ammoText = ammo_name
+		labelText = weapon_type..""
 	end

-	labelText = weapon_type.." : "
 --[[
 print("_GetButtonText"
 .." '"..tostring(weapon_type).."'"
@@ -297,11 +303,7 @@ end
 -- DESC : Display rightclick menu options
 -- **************************************************************************
 function TitanPanelRightClickMenu_PrepareAmmoMenu()
-	local info = {};
 	TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_AMMO_ID].menuText);
-	TitanPanelRightClickMenu_AddToggleIcon(TITAN_AMMO_ID);
-	TitanPanelRightClickMenu_AddToggleLabelText(TITAN_AMMO_ID);
-	TitanPanelRightClickMenu_AddToggleColoredText(TITAN_AMMO_ID);

 	info.text = L["TITAN_AMMO_BULLET_NAME"];
 	info.func = function() TitanPanelRightClickMenu_ToggleVar({TITAN_AMMO_ID, "ShowAmmoName"})
@@ -309,6 +311,12 @@ function TitanPanelRightClickMenu_PrepareAmmoMenu()
 	end
 	info.checked = TitanUtils_Ternary(TitanGetVar(TITAN_AMMO_ID, "ShowAmmoName"), 1, nil);
 	L_UIDropDownMenu_AddButton(info);
+	TitanPanelRightClickMenu_AddSpacer();
+
+	local info = {};
+	TitanPanelRightClickMenu_AddToggleIcon(TITAN_AMMO_ID);
+	TitanPanelRightClickMenu_AddToggleLabelText(TITAN_AMMO_ID);
+	TitanPanelRightClickMenu_AddToggleColoredText(TITAN_AMMO_ID);

 	TitanPanelRightClickMenu_AddToggleRightSide(TITAN_AMMO_ID);
 	TitanPanelRightClickMenu_AddSpacer();
diff --git a/TitanClassicBag/TitanClassicBag.lua b/TitanClassicBag/TitanClassicBag.lua
index b749efe..0d7e2c9 100644
--- a/TitanClassicBag/TitanClassicBag.lua
+++ b/TitanClassicBag/TitanClassicBag.lua
@@ -266,7 +266,7 @@ function TitanPanelBagButton_OnLoad(self)
 			ShowLabelText = true,
 			ShowRegularText = false,
 			ShowColoredText = true,
-			DisplayOnRightSide = true
+			DisplayOnRightSide = true,
 		},
 		savedVariables = {
 			ShowUsedSlots = 1,
@@ -277,7 +277,7 @@ function TitanPanelBagButton_OnLoad(self)
 			ShowIcon = 1,
 			ShowLabelText = 1,
 			ShowColoredText = 1,
-			DisplayOnRightSide = false
+			DisplayOnRightSide = false,
 		}
 	};

diff --git a/TitanClassicClock/TitanClassicClock.lua b/TitanClassicClock/TitanClassicClock.lua
index 825c0cf..7b2a228 100644
--- a/TitanClassicClock/TitanClassicClock.lua
+++ b/TitanClassicClock/TitanClassicClock.lua
@@ -120,6 +120,8 @@ end
 function TitanPanelClockButton_GetButtonText()
 	local clocktime = "";
 	local labeltext = "";
+	local clocktime2 = nil;
+	local labeltext2 = nil;
 	local _ = nil
 	if TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "Server" then
 		_,clocktime = TitanPanelClockButton_GetTime("Server", 0)
@@ -130,8 +132,29 @@ function TitanPanelClockButton_GetButtonText()
 	elseif TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "Local" then
 		_,clocktime = TitanPanelClockButton_GetTime ("Local", 0)
 		labeltext = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(L) ") or ""
+	elseif TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerLocal" then
+		local _, s = TitanPanelClockButton_GetTime ("Server", 0)
+		local _, l = TitanPanelClockButton_GetTime ("Local", 0)
+		sl = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(S) ") or ""
+		ll = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(L) ") or ""
+		clocktime = s
+		labeltext = sl
+		clocktime2 = l
+		labeltext2 = ll
+	elseif TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerAdjustedLocal" then
+		local _, s = TitanPanelClockButton_GetTime ("Server", TitanGetVar(TITAN_CLOCK_ID, "OffsetHour"))
+		local _, l = TitanPanelClockButton_GetTime ("Local", 0)
+		sl = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(A) ") or ""
+		ll = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(L) ") or ""
+		clocktime = s
+		labeltext = sl
+		clocktime2 = l
+		labeltext2 = ll
+	elseif TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "Local" then
+		_,clocktime = TitanPanelClockButton_GetTime ("Local", 0)
+		labeltext = TitanGetVar(TITAN_CLOCK_ID, "ShowLabelText") and TitanPanelClockButton_GetColored("(L) ") or ""
 	end
-	return labeltext, clocktime
+	return labeltext, clocktime, labeltext2, clocktime2
 end


@@ -260,6 +283,7 @@ function TitanPanelClockControlSlider_OnShow(self)
 	_G[self:GetName().."Low"]:SetText(L["TITAN_CLOCK_CONTROL_HIGH"]);
 	self:SetMinMaxValues(-12, 12);
 	self:SetValueStep(0.5);
+	self:SetObeyStepOnDrag(true)
 	self:SetValue(0 - TitanGetVar(TITAN_CLOCK_ID, "OffsetHour"));

 	local position = TitanUtils_GetRealPosition(TITAN_CLOCK_ID);
@@ -330,8 +354,9 @@ end


 function TitanPanelClockControlSlider_OnValueChanged(self, a1)
-	_G[self:GetName().."Text"]:SetText(TitanPanelClock_GetOffsetText(0 - self:GetValue()));
-	TitanSetVar(TITAN_CLOCK_ID, "OffsetHour", 0 - self:GetValue());
+	local step = self:GetValue()
+    _G[self:GetName().."Text"]:SetText(TitanPanelClock_GetOffsetText(0 - step));
+    TitanSetVar(TITAN_CLOCK_ID, "OffsetHour", 0 - step);
 	if ( ServerTimeOffsets[realmName] ) then
 		ServerTimeOffsets[realmName] = TitanGetVar(TITAN_CLOCK_ID, "OffsetHour");
 	end
@@ -417,8 +442,7 @@ end
 -- **************************************************************************
 function TitanPanelClockControlFrame_OnLoad(self)
 	_G[self:GetName().."Title"]:SetText(L["TITAN_CLOCK_CONTROL_TITLE"]);
---	self:SetBackdropBorderColor(1, 1, 1);
---	self:SetBackdropColor(0, 0, 0, 1);
+	TitanPanelRightClickMenu_SetCustomBackdrop(self)
 end

 -- **************************************************************************
@@ -455,6 +479,18 @@ function TitanPanelRightClickMenu_PrepareClockMenu()
 	info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerAdjusted" end
 	L_UIDropDownMenu_AddButton(info);

+	info = {};
+	info.text = L["TITAN_CLOCK_MENU_SERVER_TIME"].." & "..L["TITAN_CLOCK_MENU_LOCAL_TIME"]
+	info.func = function() TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "ServerLocal") TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) end
+	info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerLocal" end
+	L_UIDropDownMenu_AddButton(info);
+
+	info = {};
+	info.text = L["TITAN_CLOCK_MENU_SERVER_ADJUSTED_TIME"].." & "..L["TITAN_CLOCK_MENU_LOCAL_TIME"]
+	info.func = function() TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "ServerAdjustedLocal") TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) end
+	info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerAdjustedLocal" end
+	L_UIDropDownMenu_AddButton(info);
+
 	TitanPanelRightClickMenu_AddSpacer();

 	info = {};
@@ -471,7 +507,6 @@ function TitanPanelRightClickMenu_PrepareClockMenu()
 	info.keepShownOnClick = 1;
 	L_UIDropDownMenu_AddButton(info);

-	TitanPanelRightClickMenu_AddSpacer();
 	info = {};
 	info.text = L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"];
 	info.func = TitanPanelClockButton_ToggleRightSideDisplay;
diff --git a/TitanClassicClock/TitanClassicClock.xml b/TitanClassicClock/TitanClassicClock.xml
index 70093b0..70d2309 100644
--- a/TitanClassicClock/TitanClassicClock.xml
+++ b/TitanClassicClock/TitanClassicClock.xml
@@ -1,10 +1,15 @@
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
 	<Script file="TitanClassicClock.lua"/>
-	<Frame name="TitanPanelClockControlFrameTemplate" virtual="true" hidden="true">
+	<Frame name="TitanPanelClockControlFrameTemplate" inherits="BackdropTemplate" virtual="true" hidden="true">
 		<Size>
 			<AbsDimension x="90" y="200" />
 		</Size>
+<!--
+Blizzard decided to remove direct Backdrop API in 9.0 (Shadowlands) so inherit the template
+and set the values in the code.
+-->
+<!--
 		<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
 			<EdgeSize>
 				<AbsValue val="16"/>
@@ -16,6 +21,7 @@
 				<AbsInset left="5" right="5" top="5" bottom="5"/>
 			</BackgroundInsets>
 		</Backdrop>
+-->
 		<Layers>
 			<Layer>
 				<FontString name="$parentTitle" inherits="GameFontNormalSmall">
@@ -98,7 +104,7 @@
 			</OnUpdate>
 		</Scripts>
 	</Frame>
-	<Frame parent="UIParent">
+	<Frame parent="UIParent" inherits="BackdropTemplate">
 		<Frames>
 			<Button name="TitanPanelClockButton" inherits="TitanPanelTextTemplate" frameStrata="FULLSCREEN" toplevel="true">
 				<Scripts>
diff --git a/TitanClassicLocation/TitanClassicLocation.lua b/TitanClassicLocation/TitanClassicLocation.lua
index fd63733..b1cd07e 100755
--- a/TitanClassicLocation/TitanClassicLocation.lua
+++ b/TitanClassicLocation/TitanClassicLocation.lua
@@ -72,7 +72,7 @@ end
 -- **************************************************************************
 function TitanPanelLocationButton_OnShow()
 	local mapID = C_Map.GetBestMapForUnit("player");
-	if mapID ~= nil then
+	if mapID ~= nil and C_Map.MapHasArt(mapID) then
     	WorldMapFrame:SetMapID(mapID);
 	end
 	TitanPanelLocation_HandleUpdater();
@@ -199,7 +199,7 @@ function TitanPanelLocationButton_OnEvent(self, event, ...)
 	end
 	if TitanGetVar(TITAN_LOCATION_ID, "UpdateWorldmap") then
 		local mapID = C_Map.GetBestMapForUnit("player")
-		if mapID ~= nil then
+		if mapID ~= nil and C_Map.MapHasArt(mapID) then
     		WorldMapFrame:SetMapID(mapID);
 		end
 	end
diff --git a/TitanClassicLootType/TitanClassicLootType.xml b/TitanClassicLootType/TitanClassicLootType.xml
index 2cc08e6..df0f777 100644
--- a/TitanClassicLootType/TitanClassicLootType.xml
+++ b/TitanClassicLootType/TitanClassicLootType.xml
@@ -35,12 +35,14 @@
 	</Button>

 	<!-- For the Track feature -->
-	<Frame name="TitanPanelLootTypeMainWindow" parent="UIParent" hidden="true" toplevel="true" movable="true" enableMouse="true" frameStrata="HIGH" resizable="true">
+	<Frame name="TitanPanelLootTypeMainWindow" parent="UIParent" hidden="true" toplevel="true" inherits="BackdropTemplate"
+		movable="true" enableMouse="true" frameStrata="HIGH" resizable="true">
 		<Size><AbsDimension x="194" y="170"/></Size>
 		<Anchors>
 			<Anchor point="CENTER"/>
 			<Offset><AbsDimension x="300" y="0"/></Offset>
 		</Anchors>
+<!--
 		<Backdrop name="$parentBackdrop" bgFile="Interface\TutorialFrame\TutorialFrameBackground"
 		edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
 			<EdgeSize>
@@ -53,6 +55,10 @@
 				<AbsInset left="5" right="5" top="5" bottom="5"/>
 			</BackgroundInsets>
 		</Backdrop>
+-->
+		<KeyValues>
+			<KeyValue key="backdropInfo" value="BACKDROP_TUTORIAL_16_16" type="global"/>
+		</KeyValues>

 		<Layers>
 			<Layer level="BACKGROUND">
diff --git a/TitanClassicPerformance/TitanClassicPerformance.lua b/TitanClassicPerformance/TitanClassicPerformance.lua
index d1a8c04..4aa5acc 100644
--- a/TitanClassicPerformance/TitanClassicPerformance.lua
+++ b/TitanClassicPerformance/TitanClassicPerformance.lua
@@ -726,7 +726,7 @@ function TitanPanelPerfControlSlider_OnShow(self)
 	self:SetValueStep(1);
 	self:SetValue(CalcAppNum(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")));
 --	self:SetValue((TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")));
-	TitanPanelPerfControlFrame:SetBackdropColor(0, 0, 0, 1)
+--	TitanPanelPerfControlFrame:SetBackdropColor(0, 0, 0, 1)

 	local scale = _G[drop_down.."1"]:GetScale()
 	local drop_arrow = drop_down.."2Button4ExpandArrow"
@@ -797,8 +797,7 @@ end
 -- **************************************************************************
 function TitanPanelPerfControlFrame_OnLoad(self)
 	_G[self:GetName().."Title"]:SetText(L["TITAN_PERFORMANCE_CONTROL_TITLE"]);
---	self:SetBackdropBorderColor(1, 1, 1);
---	self:SetBackdropColor(0, 0, 0, 1);
+	TitanPanelRightClickMenu_SetCustomBackdrop(self)
 end

 -- **************************************************************************
diff --git a/TitanClassicPerformance/TitanClassicPerformance.xml b/TitanClassicPerformance/TitanClassicPerformance.xml
index 0fda4e0..aa1c250 100644
--- a/TitanClassicPerformance/TitanClassicPerformance.xml
+++ b/TitanClassicPerformance/TitanClassicPerformance.xml
@@ -1,10 +1,13 @@
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
 	<Script file="TitanClassicPerformance.lua"/>
-	<Frame name="TitanPanelPerfControlFrameTemplate" virtual="true" hidden="true">
+	<Frame name="TitanPanelPerfControlFrameTemplate" inherits="BackdropTemplate" virtual="true" hidden="true">
 		<Size>
 			<AbsDimension x="120" y="170" />
 		</Size>
+<!--
+Blizzard decided to remove direct Backdrop API in 9.0 (Shadowlands) so inherit the template
+and set the values in the code.
 		<Backdrop bgFile="Interface\FullScreenTextures\OutOfControl" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
 			<EdgeSize>
 				<AbsValue val="16"/>
@@ -16,6 +19,7 @@
 				<AbsInset left="2" right="2" top="2" bottom="2"/>
 			</BackgroundInsets>
 		</Backdrop>
+-->
 		<Layers>
 			<Layer>
 				<FontString name="$parentTitle" inherits="GameFontNormalSmall">
diff --git a/TitanClassicVolume/TitanClassicVolume.lua b/TitanClassicVolume/TitanClassicVolume.lua
index b654757..e3a7ce8 100644
--- a/TitanClassicVolume/TitanClassicVolume.lua
+++ b/TitanClassicVolume/TitanClassicVolume.lua
@@ -357,8 +357,7 @@ function TitanPanelVolumeControlFrame_OnLoad(self)
 	_G[self:GetName().."DialogTitle"]:SetText(L["TITAN_VOLUME_DIALOG_CONTROL_TITLE"]);
 --	_G[self:GetName().."MicrophoneTitle"]:SetText(L["TITAN_VOLUME_MICROPHONE_CONTROL_TITLE"]);
 --	_G[self:GetName().."SpeakerTitle"]:SetText(L["TITAN_VOLUME_SPEAKER_CONTROL_TITLE"]);
---	self:SetBackdropBorderColor(1, 1, 1);
---	self:SetBackdropColor(0, 0, 0, 1);
+	TitanPanelRightClickMenu_SetCustomBackdrop(self)
 end

 function TitanPanelVolumeControlFrame_OnUpdate(self, elapsed)
diff --git a/TitanClassicVolume/TitanClassicVolume.xml b/TitanClassicVolume/TitanClassicVolume.xml
index d260c91..1cc7533 100644
--- a/TitanClassicVolume/TitanClassicVolume.xml
+++ b/TitanClassicVolume/TitanClassicVolume.xml
@@ -1,10 +1,13 @@
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
 	<Script file="TitanClassicVolume.lua"/>
-	<Frame name="TitanPanelVolumeControlFrameTemplate" virtual="true" hidden="true">
+	<Frame name="TitanPanelVolumeControlFrameTemplate" inherits="BackdropTemplate" virtual="true" hidden="true">
 		<Size>
 			<AbsDimension x="400" y="200" />
 		</Size>
+<!--
+Blizzard decided to remove direct Backdrop API in 9.0 (Shadowlands) so inherit the template
+and set the values in the code.
 		<Backdrop bgFile="Interface\Tooltips\UI-Tooltip-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
 			<EdgeSize>
 				<AbsValue val="16"/>
@@ -16,6 +19,7 @@
 				<AbsInset left="5" right="5" top="5" bottom="5"/>
 			</BackgroundInsets>
 		</Backdrop>
+-->
 		<Layers>
 			<Layer>
 				<FontString name="$parentTitle" inherits="GameFontNormalSmall">
diff --git a/TitanClassicXP/TitanClassicXP.lua b/TitanClassicXP/TitanClassicXP.lua
index 5c845bb..7b23a4f 100644
--- a/TitanClassicXP/TitanClassicXP.lua
+++ b/TitanClassicXP/TitanClassicXP.lua
@@ -86,9 +86,9 @@ function TitanPanelXPButton_OnShow()
 	TitanPanelXPButton_SetIcon();
 	found = nil;
 	if not TitanPanelXPButton_ButtonAdded then
-        if not TitanAllGetVar("Silenced") then
-            RequestTimePlayed();
-        end
+		if not TitanAllGetVar("Silenced") then
+		    RequestTimePlayed();
+		end
 		TitanPanelXPButton_ButtonAdded = true;
 	end
 end
@@ -403,10 +403,6 @@ function TitanPanelRightClickMenu_PrepareXPMenu()
 		TitanPanelRightClickMenu_AddCommand(L["TITAN_XP_MENU_REFRESH_PLAYED"], TITAN_XP_ID, "TitanPanelXPButton_RefreshPlayed");

 		TitanPanelRightClickMenu_AddSpacer();
-		TitanPanelRightClickMenu_AddToggleIcon(TITAN_XP_ID);
-		TitanPanelRightClickMenu_AddToggleLabelText(TITAN_XP_ID);
-
-		TitanPanelRightClickMenu_AddSpacer();

 		local info = {};
 		info.text = L["TITAN_USE_COMMA"];
@@ -423,7 +419,11 @@ function TitanPanelRightClickMenu_PrepareXPMenu()
 	end
 	L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);

+	TitanPanelRightClickMenu_AddSpacer();
+	TitanPanelRightClickMenu_AddToggleIcon(TITAN_XP_ID);
+	TitanPanelRightClickMenu_AddToggleLabelText(TITAN_XP_ID);
 	TitanPanelRightClickMenu_AddToggleRightSide(TITAN_XP_ID);
+
 	TitanPanelRightClickMenu_AddSpacer();
 	TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], TITAN_XP_ID, TITAN_PANEL_MENU_FUNC_HIDE);
 	end