diff libs/FuBarPlugin-2.0/FuBarPlugin-2.0.lua @ 1:c11ca1d8ed91

Version 0.1
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:03:57 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libs/FuBarPlugin-2.0/FuBarPlugin-2.0.lua	Tue Mar 20 21:03:57 2007 +0000
@@ -0,0 +1,1521 @@
+--[[
+Name: FuBarPlugin-2.0
+Revision: $Rev: 19941 $
+Author: Cameron Kenneth Knight (ckknight@gmail.com)
+Website: http://wiki.wowace.com/index.php/FuBarPlugin-2.0
+Documentation: http://wiki.wowace.com/index.php/FuBarPlugin-2.0
+SVN: svn://svn.wowace.com/root/branches/FuBar/FuBarPlugin-2.0/FuBarPlugin-2.0/
+Description: Plugin for FuBar.
+Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0, Tablet-2.0, Dewdrop-2.0
+]]
+
+local MAJOR_VERSION = "FuBarPlugin-2.0"
+local MINIMAPCONTAINER_MAJOR_VERSION = "FuBarPlugin-MinimapContainer-2.0"
+local MINOR_VERSION = "$Revision: 19941 $"
+
+-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
+if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
+if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
+
+if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
+
+local AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0")
+local Tablet = AceLibrary:HasInstance("Tablet-2.0") and AceLibrary("Tablet-2.0")
+local Dewdrop = AceLibrary:HasInstance("Dewdrop-2.0") and AceLibrary("Dewdrop-2.0")
+
+local epsilon = 1e-5
+local _G = getfenv(0)
+
+local SHOW_ICON = "Show icon"
+local SHOW_ICON_DESC = "Show the plugins icon on the panel."
+local SHOW_TEXT = "Show text"
+local SHOW_TEXT_DESC = "Show the plugins text on the panel."
+local SHOW_COLORED_TEXT = "Show colored text"
+local SHOW_COLORED_TEXT_DESC = "Allow the plugin to color its text."
+local DETACH_TOOLTIP = "Detach tooltip"
+local DETACH_TOOLTIP_DESC = "Detach the tooltip from the panel."
+local LOCK_TOOLTIP = "Lock tooltip"
+local LOCK_TOOLTIP_DESC = "Lock the tooltips position. When the tooltip is locked, you must use Alt to access it with your mouse."
+local POSITION = "Position"
+local POSITION_DESC = "Position the plugin on the panel."
+local POSITION_LEFT = "Left"
+local POSITION_RIGHT = "Right"
+local POSITION_CENTER = "Center"
+local ATTACH_TO_MINIMAP = "Attach to minimap"
+local ATTACH_TO_MINIMAP_DESC = "Attach the plugin to the minimap instead of the panel."
+local HIDE_FUBAR_PLUGIN = "Hide plugin"
+local HIDE_FUBAR_PLUGIN_CMD = "Hidden"
+local HIDE_FUBAR_PLUGIN_DESC = "Hide the plugin from the panel or minimap, leaving the addon running."
+local OTHER = "Other"
+local CLOSE = "Close"
+local CLOSE_DESC = "Close the menu."
+
+if GetLocale() == "koKR" then
+	SHOW_ICON = "아이콘 표시"
+	SHOW_ICON_DESC = "패널에 플러그인 아이콘을 표시합니다."
+	SHOW_TEXT = "텍스트 표시"
+	SHOW_TEXT_DESC = "페널에 플러그인 텍스트를 표시합니다."
+	SHOW_COLORED_TEXT = "색상화된 텍스트 표시"
+	SHOW_COLORED_TEXT_DESC = "플러그인의 텍스트 색상을 허용합니다."
+	DETACH_TOOLTIP = "툴팁 분리"
+	DETACH_TOOLTIP_DESC = "패널에서 툴팁을 분리 합니다."
+	LOCK_TOOLTIP = "툴팁 고정"
+	LOCK_TOOLTIP_DESC = "툴팁 위치를 고정합니다."
+	POSITION = "위치"
+	POSITION_DESC = "패널에서 플러그인의 위치를 설정합니다."
+	POSITION_LEFT = "왼쪽"
+	POSITION_RIGHT = "오른쪽"
+	POSITION_CENTER = "가운데"
+	ATTACH_TO_MINIMAP = "미니맵에 표시"
+	ATTACH_TO_MINIMAP_DESC = "플러그인을 패널 대신 미니맵에 표시합니다."
+	HIDE_FUBAR_PLUGIN = "FuBar 플러그인 숨기기"
+	HIDE_FUBAR_PLUGIN_CMD = "숨겨짐"
+	HIDE_FUBAR_PLUGIN_DESC = "패널에서 플러그인을 숨깁니다."
+	OTHER = "기타"
+	CLOSE = "닫기"
+	CLOSE_DESC = "메뉴 닫기."
+elseif GetLocale() == "deDE" then
+	SHOW_ICON = "Zeige Icon"
+	SHOW_ICON_DESC = "Zeige das Plugin-Icon auf der Leiste."
+	SHOW_TEXT = "Zeige Text"
+	SHOW_TEXT_DESC = "Zeige den Plugin-Text auf der Leiste."
+	SHOW_COLORED_TEXT = "Zeige gef\195\164rbten Text"
+	SHOW_COLORED_TEXT_DESC = "Dem Plugin erlauben sein Text zu f\195\164rben."
+	DETACH_TOOLTIP = "Tooltip l\195\182sen"
+	DETACH_TOOLTIP_DESC = "Tooltip von der Leiste l\195\182sen."
+	LOCK_TOOLTIP = "Tooltip sperren"
+	LOCK_TOOLTIP_DESC = "Tooltip an der Position sperren."
+	POSITION = "Position"
+	POSITION_DESC = "Positioniert das Plugin auf der Leiste."
+	POSITION_LEFT = "Links"
+	POSITION_RIGHT = "Rechts"
+	POSITION_CENTER = "Mitte"
+	ATTACH_TO_MINIMAP = "An der Minimap anbringen"
+	ATTACH_TO_MINIMAP_DESC = "Bringt das Plugin an der Minimap anstelle der Leiste an."
+	HIDE_FUBAR_PLUGIN = "Versteckt das FuBar Plugin"
+	HIDE_FUBAR_PLUGIN_CMD = "Verstecken"
+	HIDE_FUBAR_PLUGIN_DESC = "Versteckt das Plugin von der Leiste."
+elseif GetLocale() == "frFR" then
+	SHOW_ICON = "Afficher l'ic\195\180ne"
+	SHOW_ICON_DESC = "Afficher l'ic\195\180ne du plugin sur le panneau."
+	SHOW_TEXT = "Afficher le texte"
+	SHOW_TEXT_DESC = "Afficher le texte du plugin sur le panneau."
+	SHOW_COLORED_TEXT = "Afficher la couleur du texte"
+	SHOW_COLORED_TEXT_DESC = "Permet au plugin de colorer le texte."
+	DETACH_TOOLTIP = "D\195\169tacher le tooltip"
+	DETACH_TOOLTIP_DESC = "Permet de d\195\169tacher le tooltip du panneau."
+	LOCK_TOOLTIP = "Bloquer le tooltip"
+	LOCK_TOOLTIP_DESC = "Permet de bloquer le tooltip \195\160 sa position actuelle. Une fois le tooltip bloqu\195\169, vous devez utiliser la touche Alt pour le d\195\169placer avec votre souris."
+	POSITION = "Position"
+	POSITION_DESC = "Permet de changer la position du plugin dans le panneau."
+	POSITION_LEFT = "Gauche"
+	POSITION_RIGHT = "Droite"
+	POSITION_CENTER = "Centre"
+	ATTACH_TO_MINIMAP = "Attacher \195\160 la minicarte"
+	ATTACH_TO_MINIMAP_DESC = "Attache l'ic\195\180ne du plugin \195\160 la minicarte."
+	HIDE_FUBAR_PLUGIN = "Masquer le plugin"
+	HIDE_FUBAR_PLUGIN_CMD = "Masqu\195\169"
+	HIDE_FUBAR_PLUGIN_DESC = "Permet de masquer compl\195\168tement le plugin du panneau, mais laisse l'addon fonctionner."
+	OTHER = "Autre"
+	CLOSE = "Fermer"
+	CLOSE_DESC = "Ferme le menu."
+elseif GetLocale() == "zhCN" then
+	SHOW_ICON = "显示图标"
+	SHOW_ICON_DESC = "在面板上显示插件图标."
+	SHOW_TEXT = "显示文字"
+	SHOW_TEXT_DESC = "在面板上显示文字标题."
+	SHOW_COLORED_TEXT = "显示彩色文字"
+	SHOW_COLORED_TEXT_DESC = "允许插件显示彩色文字."
+	DETACH_TOOLTIP = "独立提示信息"
+	DETACH_TOOLTIP_DESC = "从面板上独立提示信息."
+	LOCK_TOOLTIP = "锁定提示信息"
+	LOCK_TOOLTIP_DESC = "锁定提示信息位置."
+	POSITION = "位置"
+	POSITION_DESC = "插件在面板上的位置."
+	POSITION_LEFT = "居左"
+	POSITION_RIGHT = "居右"
+	POSITION_CENTER = "居中"
+	ATTACH_TO_MINIMAP = "依附在小地图"
+	ATTACH_TO_MINIMAP_DESC = "插件图标依附在小地图而不显示在面板上."
+	HIDE_FUBAR_PLUGIN = "隐藏FuBar插件"
+	HIDE_FUBAR_PLUGIN_CMD = "Hidden"
+	HIDE_FUBAR_PLUGIN_DESC = "在面板上隐藏该插件."
+elseif GetLocale() == "zhTW" then
+	SHOW_ICON = "顯示圖示"
+	SHOW_ICON_DESC = "在面板上顯示插件圖示。"
+	SHOW_TEXT = "顯示文字"
+	SHOW_TEXT_DESC = "在面板上顯示文字標題。"
+	SHOW_COLORED_TEXT = "顯示彩色文字"
+	SHOW_COLORED_TEXT_DESC = "允許插件顯示彩色文字。"
+	DETACH_TOOLTIP = "獨立提示訊息"
+	DETACH_TOOLTIP_DESC = "從面板上獨立提示訊息。"
+	LOCK_TOOLTIP = "鎖定提示訊息"
+	LOCK_TOOLTIP_DESC = "鎖定提示訊息位置。"
+	POSITION = "位置"
+	POSITION_DESC = "插件在面板上的位置。"
+	POSITION_LEFT = "靠左"
+	POSITION_RIGHT = "靠右"
+	POSITION_CENTER = "置中"
+	ATTACH_TO_MINIMAP = "依附在小地圖"
+	ATTACH_TO_MINIMAP_DESC = "插件圖標依附在小地圖而不顯示在面板上。"
+	HIDE_FUBAR_PLUGIN = "隱藏FuBar插件"
+	HIDE_FUBAR_PLUGIN_CMD = "Hidden"
+	HIDE_FUBAR_PLUGIN_DESC = "在面板上隱藏該插件."
+end
+
+local FuBarPlugin = AceLibrary("AceOO-2.0").Mixin {
+													"GetTitle",
+													"GetName",
+													"GetCategory",
+													"SetFontSize",
+													"GetFrame",
+													"Show",
+													"Hide",
+													"GetPanel",
+													"IsTextColored",
+													"ToggleTextColored",
+													"IsMinimapAttached",
+													"ToggleMinimapAttached",
+													"Update",
+													"UpdateDisplay",
+													"UpdateData",
+													"UpdateText",
+													"UpdateTooltip",
+													"SetIcon",
+													"GetIcon",
+													"CheckWidth",
+													"SetText",
+													"GetText",
+													"IsIconShown",
+													"ToggleIconShown",
+													"ShowIcon",
+													"HideIcon",
+													"IsTextShown",
+													"ToggleTextShown",
+													"ShowText",
+													"HideText",
+													"IsTooltipDetached",
+													"ToggleTooltipDetached",
+													"DetachTooltip",
+													"ReattachTooltip",
+													"GetDefaultPosition",
+													"SetPanel",
+													"IsLoadOnDemand",
+													"IsDisabled",
+													"CreateBasicPluginFrame",
+													"CreatePluginChildFrame",
+													"OpenMenu",
+													"AddImpliedMenuOptions",
+												  }
+
+local good = nil
+local function CheckFuBar()
+	if not good then
+		good = FuBar and tonumber(string.sub(FuBar.version, 1, 3)) and tonumber(string.sub(FuBar.version, 1, 3)) >= 2 and true
+	end
+	return good
+end
+
+function FuBarPlugin:GetTitle()
+	local name = self.title or self.name
+	FuBarPlugin:assert(name, "You must provide self.title or self.name")
+	local _,_,title = string.find(name, "FuBar %- (.-)%s*$")
+	if not title then
+		title = name
+	end
+	return (string.gsub(string.gsub(title, "|c%x%x%x%x%x%x%x%x", ""), "|r", ""))
+end
+
+function FuBarPlugin:GetName()
+	return self.name
+end
+
+function FuBarPlugin:GetCategory()
+	return self.category or OTHER
+end
+
+function FuBarPlugin:GetFrame()
+	return self.frame
+end
+
+function FuBarPlugin:GetPanel()
+	return self.panel
+end
+
+function FuBarPlugin:IsTextColored()
+	return not self.db or not self.db.profile or not self.db.profile.uncolored
+end
+
+function FuBarPlugin:ToggleTextColored()
+	FuBarPlugin:assert(self.db, "Cannot change text color if self.db is not available. (" .. self:GetTitle() .. ")")
+	self.db.profile.uncolored = not self.db.profile.uncolored or nil
+	self:UpdateText()
+end
+
+function FuBarPlugin:ToggleMinimapAttached()
+	if CheckFuBar() and not self.cannotAttachToMinimap then
+		local value = self:IsMinimapAttached()
+		if value then
+			if self.panel then
+				self.panel:RemovePlugin(self)
+			end
+			FuBar:GetPanel(1):AddPlugin(self, nil, self.defaultPosition)
+		else
+			if self.panel then
+				self.panel:RemovePlugin(self)
+			end
+			AceLibrary(MINIMAPCONTAINER_MAJOR_VERSION):AddPlugin(self)
+		end
+	end
+	Dewdrop:Close()
+end
+
+function FuBarPlugin:IsMinimapAttached()
+	if not CheckFuBar() then
+		return true
+	end
+	return self.panel == AceLibrary(MINIMAPCONTAINER_MAJOR_VERSION)
+end
+
+function FuBarPlugin:Update()
+	self:UpdateData()
+	self:UpdateText()
+	self:UpdateTooltip()
+end
+
+function FuBarPlugin:UpdateDisplay()
+	self:UpdateText()
+	self:UpdateTooltip()
+end
+
+function FuBarPlugin:UpdateData()
+	if type(self.OnDataUpdate) == "function" then
+		if not self:IsDisabled() then
+			self:OnDataUpdate()
+		end
+	end
+end
+
+function FuBarPlugin:UpdateText()
+	if type(self.OnTextUpdate) == "function" then
+		if not self:IsDisabled() then
+			self:OnTextUpdate()
+		end
+	elseif self:IsTextShown() then
+		self:SetText(self:GetTitle())
+	end
+end
+
+function FuBarPlugin:RegisterTablet()
+	if not Tablet:IsRegistered(self.frame) then
+		if self.db and self.db.profile and not self.db.profile.detachedTooltip then
+			self.db.profile.detachedTooltip = {}
+		end
+		Tablet:Register(self.frame,
+			'children', function()
+				Tablet:SetTitle(self:GetTitle())
+				if type(self.OnTooltipUpdate) == "function" then
+					if not self:IsDisabled() then
+						self:OnTooltipUpdate()
+					end
+				end
+			end,
+			'clickable', self.clickableTooltip,
+			'data', CheckFuBar() and FuBar.db.profile.tooltip or self.db and self.db.profile.detachedTooltip or {},
+			'detachedData', self.db and self.db.profile.detachedTooltip or {},
+			'point', function(frame)
+				if frame:GetTop() > GetScreenHeight() / 2 then
+					local x = frame:GetCenter()
+					if x < GetScreenWidth() / 3 then
+						return "TOPLEFT", "BOTTOMLEFT"
+					elseif x < GetScreenWidth() * 2 / 3 then
+						return "TOP", "BOTTOM"
+					else
+						return "TOPRIGHT", "BOTTOMRIGHT"
+					end
+				else
+					local x = frame:GetCenter()
+					if x < GetScreenWidth() / 3 then
+						return "BOTTOMLEFT", "TOPLEFT"
+					elseif x < GetScreenWidth() * 2 / 3 then
+						return "BOTTOM", "TOP"
+					else
+						return "BOTTOMRIGHT", "TOPRIGHT"
+					end
+				end
+			end,
+			'menu', self.OnMenuRequest and function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
+				if level == 1 then
+					local name = tostring(self)
+					if not string.find(name, '^table:') then
+						name = string.gsub(name, "|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
+						Dewdrop:AddLine(
+							'text', name,
+							'isTitle', true
+						)
+					end
+				end
+				if type(self.OnMenuRequest) == "function" then
+					self:OnMenuRequest(level, value, true, valueN_1, valueN_2, valueN_3, valueN_4)
+				elseif type(self.OnMenuRequest) == "table" then
+					Dewdrop:FeedAceOptionsTable(self.OnMenuRequest)
+				end
+			end,
+			'hideWhenEmpty', self.tooltipHiddenWhenEmpty
+		)
+	end
+end
+
+function FuBarPlugin:UpdateTooltip()
+	FuBarPlugin.RegisterTablet(self)
+	if self:IsMinimapAttached() and not self:IsTooltipDetached() and self.minimapFrame then
+		Tablet:Refresh(self.minimapFrame)
+	else
+		Tablet:Refresh(self.frame)
+	end
+end
+
+function FuBarPlugin:OnProfileEnable()
+	self:Update()
+end
+
+function FuBarPlugin:Show(panelId)
+	if self.frame:IsShown() or (self.minimapFrame and self.minimapFrame:IsShown()) then
+		return
+	end
+	if panelId ~= false then
+		if self.db then
+			self.db.profile.hidden = nil
+		end
+	end
+	if self.IsActive and not self:IsActive() then
+		self.panelIdTmp = panelId
+		self:ToggleActive()
+		self.panelIdTmp = nil
+		if self.db then
+			self.db.profile.disabled = nil
+		end
+	elseif not self.db or not self.db.profile.hidden then
+		if panelId == 0 or not CheckFuBar() then
+			AceLibrary(MINIMAPCONTAINER_MAJOR_VERSION):AddPlugin(self)
+		else
+			FuBar:ShowPlugin(self, panelId or self.panelIdTmp)
+		end
+		if not self.userDefinedFrame then
+			if not self:IsTextShown() then
+				self.textFrame:SetText("")
+				self.textFrame:SetWidth(epsilon)
+				self.textFrame:Hide()
+			end
+			if not self:IsIconShown() then
+				self.iconFrame:SetWidth(epsilon)
+				self.iconFrame:Hide()
+			end
+		end
+		self:Update()
+	end
+end
+
+function FuBarPlugin:Hide(check)
+	if not self.frame:IsShown() and (not self.minimapFrame or not self.minimapFrame:IsShown()) then
+		return
+	end
+	if self.hideWithoutStandby and self.db and check ~= false then
+		self.db.profile.hidden = true
+	end
+	if not self.hideWithoutStandby then
+		if self.db and not self.overrideTooltip and not self.cannotDetachTooltip and self:IsTooltipDetached() and self.db.profile.detachedTooltip and self.db.profile.detachedTooltip.detached then
+			self:ReattachTooltip()
+			self.db.profile.detachedTooltip.detached = true
+		end
+		if self.IsActive and self:IsActive() and self.ToggleActive and (not CheckFuBar() or not FuBar:IsChangingProfile()) then
+			self:ToggleActive()
+		end
+	end
+	if self.panel then
+		self.panel:RemovePlugin(self)
+	end
+	self.frame:Hide()
+	if self.minimapFrame then
+		self.minimapFrame:Hide()
+	end
+
+	if Dewdrop:IsOpen(self.frame) or (self.minimapFrame and Dewdrop:IsOpen(self.minimapFrame)) then
+		Dewdrop:Close()
+	end
+end
+
+function FuBarPlugin:SetIcon(path)
+	if not path then
+		return
+	end
+	FuBarPlugin:argCheck(path, 2, "string", "boolean")
+	FuBarPlugin:assert(self.hasIcon, "Cannot set icon unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
+	if not self.iconFrame then
+		return
+	end
+	if type(path) ~= "string" then
+		path = format("Interface\\AddOns\\%s\\icon", self.folderName)
+	elseif not string.find(path, '^Interface[\\/]') then
+		path = format("Interface\\AddOns\\%s\\%s", self.folderName, path)
+	end
+	if string.sub(path, 1, 16) == "Interface\\Icons\\" then
+		self.iconFrame:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+	else
+		self.iconFrame:SetTexCoord(0, 1, 0, 1)
+	end
+	self.iconFrame:SetTexture(path)
+	if self.minimapIcon then
+		if string.sub(path, 1, 16) == "Interface\\Icons\\" then
+			self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+		else
+			self.minimapIcon:SetTexCoord(0, 1, 0, 1)
+		end
+		self.minimapIcon:SetTexture(path)
+	end
+end
+
+function FuBarPlugin:GetIcon()
+	if self.hasIcon then
+		return self.iconFrame:GetTexture()
+	end
+end
+
+function FuBarPlugin:CheckWidth(force)
+	FuBarPlugin:argCheck(force, 2, "boolean", "nil")
+	if (self.iconFrame and self.iconFrame:IsShown()) or (self.textFrame and self.textFrame:IsShown()) then
+		if (self.db and self.db.profile and not self:IsIconShown()) or not self.hasIcon then
+			self.iconFrame:SetWidth(epsilon)
+		end
+		local width
+		if not self.hasNoText then
+			self.textFrame:SetHeight(0)
+			self.textFrame:SetWidth(500)
+			width = self.textFrame:GetStringWidth() + 1
+			self.textFrame:SetWidth(width)
+			self.textFrame:SetHeight(self.textFrame:GetHeight())
+		end
+		if self.hasNoText or not self.textFrame:IsShown() then
+			self.frame:SetWidth(self.iconFrame:GetWidth())
+			if self.panel and self.panel:GetPluginSide(self) == "CENTER" then
+				self.panel:UpdateCenteredPosition()
+			end
+		elseif force or not self.textWidth or self.textWidth < width or self.textWidth - 8 > width then
+			self.textWidth = width
+			self.textFrame:SetWidth(width)
+			if self.iconFrame and self.iconFrame:IsShown() then
+				self.frame:SetWidth(width + self.iconFrame:GetWidth())
+			else
+				self.frame:SetWidth(width)
+			end
+			if self.panel and self.panel:GetPluginSide(self) == "CENTER" then
+				self.panel:UpdateCenteredPosition()
+			end
+		end
+	end
+end
+
+function FuBarPlugin:SetText(text)
+	if not self.textFrame then
+		return
+	end
+	FuBarPlugin:assert(not self.hasNoText, "Cannot set text if self.hasNoText has been set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:argCheck(text, 2, "string", "number")
+	if text == "" then
+		if self.hasIcon then
+			self:ShowIcon()
+		else
+			text = self:GetTitle()
+		end
+	end
+	if not self:IsTextColored() then
+		text = string.gsub(string.gsub(text, "|c%x%x%x%x%x%x%x%x", ""), "|r", "")
+	end
+	self.textFrame:SetText(text)
+	self:CheckWidth()
+end
+
+function FuBarPlugin:GetText()
+	FuBarPlugin:assert(self.textFrame, "Cannot get text without a self.textFrame (" .. self:GetTitle() .. ")")
+	if not self.hasNoText then
+		return self.textFrame:GetText() or ""
+	end
+end
+
+function FuBarPlugin:IsIconShown()
+	if not self.hasIcon then
+		return false
+	elseif self.hasNoText then
+		return true
+	elseif not self.db then
+		return true
+	elseif self.db and self.db.profile.showIcon == nil then
+		return true
+	else
+		return (self.db and (self.db.profile.showIcon == 1 or self.db.profile.showIcon == true)) and true or false
+	end
+end
+
+function FuBarPlugin:ToggleIconShown()
+	FuBarPlugin:assert(self.iconFrame, "Cannot toggle icon without a self.iconFrame (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.hasIcon, "Cannot show icon unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(not self.hasNoText, "Cannot hide icon if self.hasNoText is set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.textFrame, "Cannot hide icon if self.textFrame is not set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.iconFrame, "Cannot hide icon if self.iconFrame is not set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.db, "Cannot hide icon if self.db is not available. (" .. self:GetTitle() .. ")")
+	local value = not self:IsIconShown()
+	self.db.profile.showIcon = value
+	if value then
+		if not self:IsTextShown() and self.textFrame:IsShown() and self.textFrame:GetText() == self:GetTitle() then
+			self.textFrame:Hide()
+			self.textFrame:SetText("")
+		end
+		self.iconFrame:Show()
+		self.iconFrame:SetWidth(self.iconFrame:GetHeight())
+	else
+		if not self.textFrame:IsShown() or not self.textFrame:GetText() then
+			self.textFrame:Show()
+			self.textFrame:SetText(self:GetTitle())
+		end
+		self.iconFrame:Hide()
+		self.iconFrame:SetWidth(epsilon)
+	end
+	self:CheckWidth(true)
+	return value
+end
+
+function FuBarPlugin:ShowIcon()
+	if not self:IsIconShown() then
+		self:ToggleIconShown()
+	end
+end
+
+function FuBarPlugin:HideIcon()
+	if self:IsIconShown() then
+		self:ToggleIconShown()
+	end
+end
+
+function FuBarPlugin:IsTextShown()
+	if self.hasNoText then
+		return false
+	elseif not self.hasIcon then
+		return true
+	elseif not self.db then
+		return true
+	elseif self.db and self.db.profile.showText == nil then
+		return true
+	else
+		return (self.db and (self.db.profile.showText == 1 or self.db.profile.showText == true)) and true or false
+	end
+end
+
+function FuBarPlugin:ToggleTextShown()
+	FuBarPlugin:assert(not self.cannotHideText, "Cannot hide text unless self.cannotHideText is unset. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.hasIcon, "Cannot show text unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(not self.hasNoText, "Cannot hide text if self.hasNoText is set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.textFrame, "Cannot hide text if self.textFrame is not set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.iconFrame, "Cannot hide text if self.iconFrame is not set. (" .. self:GetTitle() .. ")")
+	FuBarPlugin:assert(self.db, "Cannot hide text if self.db is not available. (" .. self:GetTitle() .. ")")
+	local value = not self:IsTextShown()
+	self.db.profile.showText = value
+	if value then
+		self.textFrame:Show()
+		self:UpdateText()
+	else
+		self.textFrame:SetText("")
+		self.textFrame:SetWidth(epsilon)
+		self.textFrame:Hide()
+		if not self:IsIconShown() then
+			DropDownList1:Hide()
+		end
+		self:ShowIcon()
+	end
+	self:CheckWidth(true)
+	return value
+end
+
+function FuBarPlugin:ShowText()
+	if not self:IsTextShown() then
+		self:ToggleTextShown()
+	end
+end
+
+function FuBarPlugin:HideText()
+	if self:IsTextShown() then
+		self:ToggleTextShown()
+	end
+end
+
+function FuBarPlugin:IsTooltipDetached()
+	FuBarPlugin.RegisterTablet(self)
+	return not Tablet:IsAttached(self.frame)
+end
+
+function FuBarPlugin:ToggleTooltipDetached()
+	FuBarPlugin.RegisterTablet(self)
+	if self:IsTooltipDetached() then
+		Tablet:Attach(self.frame)
+	else
+		Tablet:Detach(self.frame)
+	end
+	if Dewdrop then Dewdrop:Close() end
+end
+
+function FuBarPlugin:DetachTooltip()
+	FuBarPlugin.RegisterTablet(self)
+	Tablet:Detach(self.frame)
+end
+
+function FuBarPlugin:ReattachTooltip()
+	FuBarPlugin.RegisterTablet(self)
+	Tablet:Attach(self.frame)
+end
+
+function FuBarPlugin:GetDefaultPosition()
+	return self.defaultPosition or "LEFT"
+end
+
+local function IsCorrectPanel(panel)
+	if type(panel) ~= "table" then
+		return false
+	elseif type(panel.AddPlugin) ~= "function" then
+		return false
+	elseif type(panel.RemovePlugin) ~= "function" then
+		return false
+	elseif type(panel.GetNumPlugins) ~= "function" then
+		return false
+	elseif type(panel:GetNumPlugins()) ~= "number" then
+		return false
+	elseif type(panel.GetPlugin) ~= "function" then
+		return false
+	elseif type(panel.HasPlugin) ~= "function" then
+		return false
+	elseif type(panel.GetPluginSide) ~= "function" then
+		return false
+	end
+	return true
+end
+
+function FuBarPlugin:SetPanel(panel)
+	if panel then
+		FuBarPlugin:assert(IsCorrectPanel(panel), "Bad argument #2 to `SetPanel'. Panel does not have the correct API.")
+	end
+	self.panel = panel
+end
+
+function FuBarPlugin:SetFontSize(size)
+	FuBarPlugin:assert(not self.userDefinedFrame, (self.name and self.name .. ": " or "") .. "You must provide a SetFontSize(size) method if you provide your own frame.")
+	if self.hasIcon then
+		FuBarPlugin:assert(self.iconFrame, (self.name and self.name .. ": " or "") .. "No iconFrame found")
+		self.iconFrame:SetWidth(size + 3)
+		self.iconFrame:SetHeight(size + 3)
+	end
+	if not self.hasNoText then
+		FuBarPlugin:assert(self.textFrame, (self.name and self.name .. ": " or "") .. "No textFrame found")
+		local font, _, flags = self.textFrame:GetFont()
+		self.textFrame:SetFont(font, size, flags)
+	end
+	self:CheckWidth()
+end
+
+function FuBarPlugin:IsLoadOnDemand()
+	return IsAddOnLoadOnDemand(self.folderName)
+end
+
+function FuBarPlugin:IsDisabled()
+	return self.IsActive and not self:IsActive() or false
+end
+
+function FuBarPlugin:OnInstanceInit(target)
+	if not AceEvent then
+		self:error(MAJOR_VERSION .. " requires AceEvent-2.0.")
+	elseif not Tablet then
+		self:error(MAJOR_VERSION .. " requires Tablet-2.0.")
+	elseif not Dewdrop then
+		self:error(MAJOR_VERSION .. " requires Dewdrop-2.0.")
+	end
+	self.registry[target] = true
+
+	local _,_,folderName = string.find(debugstack(6, 1, 0), "\\AddOns\\(.*)\\")
+	target.folderName = folderName
+	self.folderNames[target] = folderName
+end
+
+local frame_OnClick, frame_OnDoubleClick, frame_OnMouseDown, frame_OnMouseUp, frame_OnReceiveDrag
+
+function FuBarPlugin:CreateBasicPluginFrame(name)
+	local frame = CreateFrame("Button", name, UIParent)
+	frame:SetFrameStrata("HIGH")
+	frame:SetFrameLevel(7)
+	frame:EnableMouse(true)
+	frame:EnableMouseWheel(true)
+	frame:SetMovable(true)
+	frame:SetWidth(150)
+	frame:SetHeight(24)
+	frame:SetPoint("CENTER", UIParent, "CENTER")
+	frame.self = self
+	if not frame_OnClick then
+		function frame_OnClick()
+			if type(this.self.OnClick) == "function" then
+				this.self:OnClick(arg1)
+			end
+		end
+	end
+	frame:SetScript("OnClick", frame_OnClick)
+	if not frame_OnDoubleClick then
+		function frame_OnDoubleClick()
+			if type(this.self.OnDoubleClick) == "function" then
+				this.self:OnDoubleClick(arg1)
+			end
+		end
+	end
+	frame:SetScript("OnDoubleClick", frame_OnDoubleClick)
+	if not frame_OnMouseDown then
+		function frame_OnMouseDown()
+			if arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
+				this.self:OpenMenu()
+				return
+			else
+				HideDropDownMenu(1)
+				if type(this.self.OnMouseDown) == "function" then
+					this.self:OnMouseDown(arg1)
+				end
+			end
+		end
+	end
+	frame:SetScript("OnMouseDown", frame_OnMouseDown)
+	if not frame_OnMouseUp then
+		function frame_OnMouseUp()
+			if type(this.self.OnMouseUp) == "function" then
+				this.self:OnMouseUp(arg1)
+			end
+		end
+	end
+	frame:SetScript("OnMouseUp", frame_OnMouseUp)
+	if not frame_OnReceiveDrag then
+		function frame_OnReceiveDrag()
+			if type(this.self.OnReceiveDrag) == "function" then
+				this.self:OnReceiveDrag()
+			end
+		end
+	end
+	frame:SetScript("OnReceiveDrag", frame_OnReceiveDrag)
+	return frame
+end
+
+local child_OnEnter, child_OnLeave, child_OnClick, child_OnDoubleClick, child_OnMouseDown, child_OnMouseUp, child_OnReceiveDrag
+function FuBarPlugin:CreatePluginChildFrame(frameType, name, parent)
+	FuBarPlugin:assert(self.frame, (self.name and self.name .. ": " or "") .. "You must have self.frame declared in order to add child frames")
+	FuBarPlugin:argCheck(frameType, 1, "string")
+	local child = CreateFrame(frameType, name, parent)
+	if parent then
+		child:SetFrameLevel(parent:GetFrameLevel() + 2)
+	end
+	child.self = self
+	if not child_OnEnter then
+		function child_OnEnter(...)
+			if this.self.frame:GetScript("OnEnter") then
+				this.self.frame:GetScript("OnEnter")(...)
+			end
+		end
+	end
+	child:SetScript("OnEnter", child_OnEnter)
+	if not child_OnLeave then
+		function child_OnLeave(...)
+			if this.self.frame:GetScript("OnLeave") then
+				this.self.frame:GetScript("OnLeave")(...)
+			end
+		end
+	end
+	child:SetScript("OnLeave", child_OnLeave)
+	if child:HasScript("OnClick") then
+		if not child_OnClick then
+			function child_OnClick(...)
+				if this.self.frame:HasScript("OnClick") and this.self.frame:GetScript("OnClick") then
+					this.self.frame:GetScript("OnClick")(...)
+				end
+			end
+		end
+		child:SetScript("OnClick", child_OnClick)
+	end
+	if child:HasScript("OnDoubleClick") then
+		if not child_OnDoubleClick then
+			function child_OnDoubleClick(...)
+				if this.self.frame:HasScript("OnDoubleClick") and this.self.frame:GetScript("OnDoubleClick") then
+					this.self.frame:GetScript("OnDoubleClick")(...)
+				end
+			end
+		end
+		child:SetScript("OnDoubleClick", child_OnDoubleClick)
+	end
+	if not child_OnMouseDown then
+		function child_OnMouseDown(...)
+			if this.self.frame:HasScript("OnMouseDown") and this.self.frame:GetScript("OnMouseDown") then
+				this.self.frame:GetScript("OnMouseDown")(...)
+			end
+		end
+	end
+	child:SetScript("OnMouseDown", child_OnMouseDown)
+	if not child_OnMouseUp then
+		function child_OnMouseUp(...)
+			if this.self.frame:HasScript("OnMouseUp") and this.self.frame:GetScript("OnMouseUp") then
+				this.self.frame:GetScript("OnMouseUp")(...)
+			end
+		end
+	end
+	child:SetScript("OnMouseUp", child_OnMouseUp)
+	if not child_OnReceiveDrag then
+		function child_OnReceiveDrag(this)
+			if this.self.frame:HasScript("OnReceiveDrag") and this.self.frame:GetScript("OnReceiveDrag") then
+				this.self.frame:GetScript("OnReceiveDrag")()
+			end
+		end
+	end
+	child:SetScript("OnReceiveDrag", child_OnReceiveDrag)
+	return child
+end
+
+function FuBarPlugin:OpenMenu(frame)
+	if not frame then
+		frame = self:GetFrame()
+	end
+	if not frame or not self:GetFrame() or Dewdrop:IsOpen(frame) then
+		Dewdrop:Close()
+		return
+	end
+	Tablet:Close()
+
+	if not Dewdrop:IsRegistered(self:GetFrame()) then
+		if type(self.OnMenuRequest) == "table" and (not self.OnMenuRequest.handler or self.OnMenuRequest.handler == self) and self.OnMenuRequest.type == "group" then
+			Dewdrop:InjectAceOptionsTable(self, self.OnMenuRequest)
+			if self.OnMenuRequest.args and CheckFuBar() and not self.independentProfile then
+				self.OnMenuRequest.args.profile = nil
+			end
+		end
+		Dewdrop:Register(self:GetFrame(),
+			'children', type(self.OnMenuRequest) == "table" and self.OnMenuRequest or function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
+				if level == 1 then
+					Dewdrop:AddLine(
+						'text', self:GetTitle(),
+						'isTitle', true
+					)
+				end
+
+				if level == 1 then
+					if self.OnMenuRequest then
+						self:OnMenuRequest(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4)
+					end
+
+					if not self.overrideMenu then
+						if self.MenuSettings then
+							Dewdrop:AddLine()
+						end
+						self:AddImpliedMenuOptions()
+					end
+				else
+					if not self.overrideMenu and self:AddImpliedMenuOptions() then
+					else
+						if self.OnMenuRequest then
+							self:OnMenuRequest(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4)
+						end
+					end
+				end
+				if level == 1 then
+					Dewdrop:AddLine(
+						'text', CLOSE,
+						'tooltipTitle', CLOSE,
+						'tooltipText', CLOSE_DESC,
+						'func', Dewdrop.Close,
+						'arg1', Dewdrop
+					)
+				end
+			end,
+			'point', function(frame)
+				local x, y = frame:GetCenter()
+				local leftRight
+				if x < GetScreenWidth() / 2 then
+					leftRight = "LEFT"
+				else
+					leftRight = "RIGHT"
+				end
+				if y < GetScreenHeight() / 2 then
+					return "BOTTOM" .. leftRight, "TOP" .. leftRight
+				else
+					return "TOP" .. leftRight, "BOTTOM" .. leftRight
+				end
+			end,
+			'dontHook', true
+		)
+	end
+	if frame == self:GetFrame() then
+		Dewdrop:Open(self:GetFrame())
+	else
+		Dewdrop:Open(frame, self:GetFrame())
+	end
+end
+
+local impliedMenuOptions
+function FuBarPlugin:AddImpliedMenuOptions(level)
+	FuBarPlugin:argCheck(level, 2, "number", "nil")
+	if not impliedMenuOptions then
+		impliedMenuOptions = {}
+	end
+	if not impliedMenuOptions[self] then
+		impliedMenuOptions[self] = { type = 'group', args = {} }
+		Dewdrop:InjectAceOptionsTable(self, impliedMenuOptions[self])
+		if impliedMenuOptions[self].args and CheckFuBar() and not self.independentProfile then
+			impliedMenuOptions[self].args.profile = nil
+		end
+	end
+	return Dewdrop:FeedAceOptionsTable(impliedMenuOptions[self], level and level - 1)
+end
+
+function FuBarPlugin.OnEmbedInitialize(FuBarPlugin, self)
+	if not self.frame then
+		local name = "FuBarPlugin" .. self:GetTitle() .. "Frame"
+		local frame = _G[name]
+		if not frame or not _G[name .. "Text"] or not _G[name .. "Icon"] then
+			frame = self:CreateBasicPluginFrame(name)
+
+			local icon = frame:CreateTexture(name .. "Icon", "ARTWORK")
+			icon:SetWidth(16)
+			icon:SetHeight(16)
+			icon:SetPoint("LEFT", frame, "LEFT")
+
+			local text = frame:CreateFontString(name .. "Text", "ARTWORK")
+			text:SetWidth(134)
+			text:SetHeight(24)
+			text:SetPoint("LEFT", icon, "RIGHT", 0, 1)
+			text:SetFontObject(GameFontNormal)
+		end
+		self.frame = frame
+		self.textFrame = _G[name .. "Text"]
+		self.iconFrame = _G[name .. "Icon"]
+	else
+		self.userDefinedFrame = true
+	end
+
+	self.frame.plugin = self
+	self.frame:SetParent(UIParent)
+	self.frame:SetPoint("RIGHT", UIParent, "LEFT", -5, 0)
+	self.frame:Hide()
+
+	if self.hasIcon then
+		self:SetIcon(self.hasIcon)
+	end
+
+	if CheckFuBar() then
+		FuBar:RegisterPlugin(self)
+	end
+end
+
+local CheckShow = function(self, panelId)
+	if not self.frame:IsShown() and (not self.minimapFrame or not self.minimapFrame:IsShown()) then
+		self:Show(panelId)
+		Dewdrop:Refresh(2)
+	end
+end
+
+local recheckPlugins
+function FuBarPlugin.OnEmbedEnable(FuBarPlugin, self)
+	if not self.userDefinedFrame then
+		if self:IsIconShown() then
+			self.iconFrame:Show()
+		else
+			self.iconFrame:Hide()
+		end
+	end
+	self:CheckWidth(true)
+
+	if not self.hideWithoutStandby or (self.db and not self.db.profile.hidden) then
+		if FuBarPlugin.enabledPlugins[self] then
+			CheckShow(self, self.panelIdTmp)
+		else
+			FuBarPlugin:ScheduleEvent(CheckShow, 0, self, self.panelIdTmp)
+		end
+	end
+	FuBarPlugin.enabledPlugins[self] = true
+
+	if not self.overrideTooltip and not self.cannotDetachTooltip and self.db and self.db.profile.detachedTooltip and self.db.profile.detachedTooltip.detached then
+		FuBarPlugin:ScheduleEvent(self.DetachTooltip, 0, self)
+	end
+
+	if self:IsLoadOnDemand() and CheckFuBar() then
+		if not FuBar.db.profile.loadOnDemand then
+			FuBar.db.profile.loadOnDemand = {}
+		end
+		if not FuBar.db.profile.loadOnDemand[self.folderName] then
+			FuBar.db.profile.loadOnDemand[self.folderName] = {}
+		end
+		FuBar.db.profile.loadOnDemand[self.folderName].disabled = nil
+	end
+
+	if CheckFuBar() and AceLibrary:HasInstance("AceConsole-2.0") then
+		if not recheckPlugins then
+			local AceConsole = AceLibrary("AceConsole-2.0")
+			local AceOO = AceLibrary("AceOO-2.0")
+			function recheckPlugins()
+				for k,v in pairs(AceConsole.registry) do
+					if type(v) == "table" and v.args and AceOO.inherits(v.handler, FuBarPlugin) and not v.independentProfile then
+						v.args.profile = nil
+					end
+				end
+			end
+		end
+		FuBarPlugin:ScheduleEvent(recheckPlugins, 0)
+	end
+end
+
+function FuBarPlugin.OnEmbedDisable(FuBarPlugin, self)
+	self:Hide(false)
+
+	if self:IsLoadOnDemand() and CheckFuBar() then
+		if not FuBar.db.profile.loadOnDemand then
+			FuBar.db.profile.loadOnDemand = {}
+		end
+		if not FuBar.db.profile.loadOnDemand[self.folderName] then
+			FuBar.db.profile.loadOnDemand[self.folderName] = {}
+		end
+		FuBar.db.profile.loadOnDemand[self.folderName].disabled = true
+	end
+end
+
+function FuBarPlugin.OnEmbedProfileEnable(FuBarPlugin, self)
+	self:Update()
+	if self.db and self.db.profile then
+		if not self.db.profile.detachedTooltip then
+			self.db.profile.detachedTooltip = {}
+		end
+		if Tablet.registry[self.frame] then
+			Tablet:UpdateDetachedData(self.frame, self.db.profile.detachedTooltip)
+		else
+			FuBarPlugin.RegisterTablet(self)
+		end
+	end
+end
+
+function FuBarPlugin.GetAceOptionsDataTable(FuBarPlugin, self)
+	return {
+		icon = {
+			type = "toggle",
+			name = SHOW_ICON,
+			desc = SHOW_ICON_DESC,
+			set = "ToggleIconShown",
+			get = "IsIconShown",
+			hidden = function()
+				return not self.hasIcon or self.hasNoText or self:IsDisabled() or self:IsMinimapAttached() or not self.db
+			end,
+			order = -13.7,
+			handler = self,
+		},
+		text = {
+			type = "toggle",
+			name = SHOW_TEXT,
+			desc = SHOW_TEXT_DESC,
+			set = "ToggleTextShown",
+			get = "IsTextShown",
+			hidden = function()
+				return self.cannotHideText or not self.hasIcon or self.hasNoText or self:IsDisabled() or self:IsMinimapAttached() or not self.db
+			end,
+			order = -13.6,
+			handler = self,
+		},
+		colorText = {
+			type = "toggle",
+			name = SHOW_COLORED_TEXT,
+			desc = SHOW_COLORED_TEXT_DESC,
+			set = "ToggleTextColored",
+			get = "IsTextColored",
+			hidden = function()
+				return self.userDefinedFrame or self.hasNoText or self.hasNoColor or self:IsDisabled() or self:IsMinimapAttached() or not self.db
+			end,
+			order = -13.5,
+			handler = self,
+		},
+		detachTooltip = {
+			type = "toggle",
+			name = DETACH_TOOLTIP,
+			desc = DETACH_TOOLTIP_DESC,
+			get = "IsTooltipDetached",
+			set = "ToggleTooltipDetached",
+			hidden = function()
+				return self.overrideTooltip or self.cannotDetachTooltip or self:IsDisabled()
+			end,
+			order = -13.4,
+			handler = self,
+		},
+		lockTooltip = {
+			type = "toggle",
+			name = LOCK_TOOLTIP,
+			desc = LOCK_TOOLTIP_DESC,
+			get = function()
+				return Tablet:IsLocked(self.frame)
+			end,
+			set = function()
+				return Tablet:ToggleLocked(self.frame)
+			end,
+			disabled = function()
+				return not self:IsTooltipDetached()
+			end,
+			hidden = function()
+				return self.overrideTooltip or self.cannotDetachTooltip or self:IsDisabled()
+			end,
+			order = -13.3,
+			handler = self,
+		},
+		position = {
+			type = "text",
+			name = POSITION,
+			desc = POSITION_DESC,
+			validate = {
+				LEFT = POSITION_LEFT,
+				CENTER = POSITION_CENTER,
+				RIGHT = POSITION_RIGHT
+			},
+			get = function()
+				return self.panel and self.panel:GetPluginSide(self)
+			end,
+			set = function(value)
+				if self.panel then
+					self.panel:SetPluginSide(self, value)
+				end
+			end,
+			hidden = function()
+				return self:IsMinimapAttached() or self:IsDisabled() or not self.panel
+			end,
+			order = -13.2,
+			handler = self,
+		},
+		minimapAttach = {
+			type = "toggle",
+			name = ATTACH_TO_MINIMAP,
+			desc = ATTACH_TO_MINIMAP_DESC,
+			get = "IsMinimapAttached",
+			set = "ToggleMinimapAttached",
+			hidden = function()
+				return (self.cannotAttachToMinimap and not self:IsMinimapAttached()) or not CheckFuBar() or self:IsDisabled()
+			end,
+			order = -13.1,
+			handler = self,
+		},
+		hide = {
+			type = "toggle",
+			cmdName = HIDE_FUBAR_PLUGIN_CMD,
+			guiName = HIDE_FUBAR_PLUGIN,
+			desc = HIDE_FUBAR_PLUGIN_DESC,
+			get = function()
+				return not self.frame:IsShown() and (not self.minimapFrame or not self.minimapFrame:IsShown())
+			end,
+			set = function()
+				if not self.frame:IsShown() and (not self.minimapFrame or not self.minimapFrame:IsShown()) then
+					self:Show()
+				else
+					self:Hide()
+				end
+			end,
+			hidden = function()
+				return not self.hideWithoutStandby or self:IsDisabled()
+			end,
+			order = -13,
+			handler = self,
+		},
+	}
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	FuBarPlugin = self
+
+	if oldLib then
+		self.registry = oldLib.registry
+		self.folderNames = oldLib.folderNames
+		self.enabledPlugins = oldLib.enabledPlugins
+	end
+
+	if not self.registry then
+		self.registry = {}
+	end
+	if not self.folderNames then
+		self.folderNames = {}
+	end
+	if not self.enabledPlugins then
+		self.enabledPlugins = {}
+	end
+
+	FuBarPlugin.activate(self, oldLib, oldDeactivate)
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+local function external(self, major, instance)
+	if major == "AceEvent-2.0" then
+		AceEvent = instance
+
+		AceEvent:embed(self)
+	elseif major == "Tablet-2.0" then
+		Tablet = instance
+	elseif major == "Dewdrop-2.0" then
+		Dewdrop = instance
+	end
+end
+
+AceLibrary:Register(FuBarPlugin, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
+
+local MinimapContainer = {}
+
+local function IsMinimapSquare()
+	return IsAddOnLoaded("CornerMinimap") or IsAddOnLoaded("SquareMinimap") or IsAddOnLoaded("Squeenix") or (IsAddOnLoaded("simpleMinimap") and simpleMinimap_Skins and simpleMinimap_Skins:GetShape() == "square")
+end
+
+function MinimapContainer:AddPlugin(plugin)
+	if CheckFuBar() and FuBar:IsChangingProfile() then
+		return
+	end
+	if plugin.panel ~= nil then
+		plugin.panel:RemovePlugin(plugin)
+	end
+	plugin.panel = self
+	if not plugin.minimapFrame then
+		local frame = CreateFrame("Button", plugin.frame:GetName() .. "MinimapButton", Minimap)
+		plugin.minimapFrame = frame
+		AceLibrary(MAJOR_VERSION).RegisterTablet(plugin)
+		Tablet:Register(frame, plugin.frame)
+		frame.plugin = plugin
+		frame:SetWidth(31)
+		frame:SetHeight(31)
+		frame:SetFrameStrata("BACKGROUND")
+		frame:SetFrameLevel(4)
+		frame:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
+		local icon = frame:CreateTexture(frame:GetName() .. "Icon", "BACKGROUND")
+		plugin.minimapIcon = icon
+		local path = plugin:GetIcon() or (plugin.iconFrame and plugin.iconFrame:GetTexture()) or "Interface\\Icons\\INV_Misc_QuestionMark"
+		icon:SetTexture(path)
+		if string.sub(path, 1, 16) == "Interface\\Icons\\" then
+			icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+		else
+			icon:SetTexCoord(0, 1, 0, 1)
+		end
+		icon:SetWidth(20)
+		icon:SetHeight(20)
+		icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -5)
+		local overlay = frame:CreateTexture(frame:GetName() .. "Overlay","OVERLAY")
+overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
+		overlay:SetWidth(53)
+		overlay:SetHeight(53)
+		overlay:SetPoint("TOPLEFT",frame,"TOPLEFT")
+		frame:EnableMouse(true)
+		frame:RegisterForClicks("LeftButtonUp")
+		frame.plugin = plugin
+		frame:SetScript("OnClick", function()
+			if type(plugin.OnClick) == "function" then
+				if not this.dragged then
+					plugin:OnClick(arg1)
+				end
+			end
+		end)
+		frame:SetScript("OnDoubleClick", function()
+			if type(plugin.OnDoubleClick) == "function" then
+				plugin:OnDoubleClick(arg1)
+			end
+		end)
+		frame:SetScript("OnReceiveDrag", function()
+			if type(plugin.OnReceiveDrag) == "function" then
+				if not this.dragged then
+					plugin:OnReceiveDrag()
+				end
+			end
+		end)
+		frame:SetScript("OnMouseDown", function()
+			this.dragged = false
+			if arg1 == "LeftButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
+				HideDropDownMenu(1)
+				if type(plugin.OnMouseDown) == "function" then
+					plugin:OnMouseDown(arg1)
+				end
+			elseif arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
+				plugin:OpenMenu(frame)
+			else
+				HideDropDownMenu(1)
+				if type(plugin.OnMouseDown) == "function" then
+					plugin:OnMouseDown(arg1)
+				end
+			end
+			if plugin.OnClick or plugin.OnMouseDown or plugin.OnMouseUp or plugin.OnDoubleClick then
+				if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
+					plugin.minimapIcon:SetTexCoord(0.14, 0.86, 0.14, 0.86)
+				else
+					plugin.minimapIcon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+				end
+			end
+		end)
+		frame:SetScript("OnMouseUp", function()
+			if not this.dragged and type(plugin.OnMouseUp) == "function" then
+				plugin:OnMouseUp(arg1)
+			end
+			if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
+				plugin.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+			else
+				plugin.minimapIcon:SetTexCoord(0, 1, 0, 1)
+			end
+		end)
+		frame:RegisterForDrag("LeftButton")
+		frame:SetScript("OnDragStart", self.OnDragStart)
+		frame:SetScript("OnDragStop", self.OnDragStop)
+	end
+	plugin.frame:Hide()
+	plugin.minimapFrame:Show()
+	self:ReadjustLocation(plugin)
+	table.insert(self.plugins, plugin)
+	local exists = false
+	return true
+end
+
+function MinimapContainer:RemovePlugin(index)
+	if CheckFuBar() and FuBar:IsChangingProfile() then
+		return
+	end
+	if type(index) == "table" then
+		index = self:IndexOfPlugin(index)
+		if not index then
+			return
+		end
+	end
+	local t = self.plugins
+	local plugin = t[index]
+	assert(plugin.panel == self, "Plugin has improper panel field")
+	plugin:SetPanel(nil)
+	table.remove(t, index)
+	return true
+end
+
+function MinimapContainer:ReadjustLocation(plugin)
+	local frame = plugin.minimapFrame
+	if plugin.db and plugin.db.profile.minimapPositionWild then
+		frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", plugin.db.profile.minimapPositionX, plugin.db.profile.minimapPositionY)
+	elseif not plugin.db and plugin.minimapPositionWild then
+		frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", plugin.minimapPositionX, plugin.minimapPositionY)
+	else
+		local position
+		if plugin.db then
+			position = plugin.db.profile.minimapPosition or plugin.defaultMinimapPosition or math.random(1, 360)
+		else
+			position = plugin.minimapPosition or plugin.defaultMinimapPosition or math.random(1, 360)
+		end
+		local angle = math.rad(position or 0)
+		local x,y
+		if not IsMinimapSquare() then
+			x = math.cos(angle) * 80
+			y = math.sin(angle) * 80
+		else
+			x = 110 * math.cos(angle)
+			y = 110 * math.sin(angle)
+			x = math.max(-82, math.min(x, 84))
+			y = math.max(-86, math.min(y, 82))
+		end
+		frame:SetPoint("CENTER", Minimap, "CENTER", x, y)
+	end
+end
+
+function MinimapContainer:GetPlugin(index)
+	return self.plugins[index]
+end
+
+function MinimapContainer:GetNumPlugins()
+	return table.getn(self.plugins)
+end
+
+function MinimapContainer:IndexOfPlugin(plugin)
+	for i,p in ipairs(self.plugins) do
+		if p == plugin then
+			return i, "MINIMAP"
+		end
+	end
+end
+
+function MinimapContainer:HasPlugin(plugin)
+	return self:IndexOfPlugin(plugin) ~= nil
+end
+
+function MinimapContainer:GetPluginSide(plugin)
+	local index = self:IndexOfPlugin(plugin)
+	assert(index, "Plugin not in panel")
+	return "MINIMAP"
+end
+
+function MinimapContainer.OnDragStart()
+	this.dragged = true
+	this:LockHighlight()
+	this:SetScript("OnUpdate", MinimapContainer.OnUpdate)
+	if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
+		this.plugin.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
+	else
+		this.plugin.minimapIcon:SetTexCoord(0, 1, 0, 1)
+	end
+end
+
+function MinimapContainer.OnDragStop()
+	this:SetScript("OnUpdate", nil)
+	this:UnlockHighlight()
+end
+
+function MinimapContainer.OnUpdate()
+	if not IsAltKeyDown() then
+		local mx, my = Minimap:GetCenter()
+		local px, py = GetCursorPosition()
+		local scale = UIParent:GetEffectiveScale()
+		px, py = px / scale, py / scale
+		local position = math.deg(math.atan2(py - my, px - mx))
+		if position <= 0 then
+			position = position + 360
+		elseif position > 360 then
+			position = position - 360
+		end
+		if this.plugin.db then
+			this.plugin.db.profile.minimapPosition = position
+			this.plugin.db.profile.minimapPositionX = nil
+			this.plugin.db.profile.minimapPositionY = nil
+			this.plugin.db.profile.minimapPositionWild = nil
+		else
+			this.plugin.minimapPosition = position
+			this.plugin.minimapPositionX = nil
+			this.plugin.minimapPositionY = nil
+			this.plugin.minimapPositionWild = nil
+		end
+	else
+		local px, py = GetCursorPosition()
+		local scale = UIParent:GetEffectiveScale()
+		px, py = px / scale, py / scale
+		if this.plugin.db then
+			this.plugin.db.profile.minimapPositionX = px
+			this.plugin.db.profile.minimapPositionY = py
+			this.plugin.db.profile.minimapPosition = nil
+			this.plugin.db.profile.minimapPositionWild = true
+		else
+			this.plugin.minimapPositionX = px
+			this.plugin.minimapPositionY = py
+			this.plugin.minimapPosition = nil
+			this.plugin.minimapPositionWild = true
+		end
+	end
+	MinimapContainer:ReadjustLocation(this.plugin)
+end
+
+local function activate(self, oldLib, oldDeactivate)
+	MinimapContainer = self
+
+	if oldLib then
+		self.plugins = oldLib.plugins
+	end
+
+	if not self.plugins then
+		self.plugins = {}
+	end
+
+	if oldDeactivate then
+		oldDeactivate(oldLib)
+	end
+end
+
+AceLibrary:Register(MinimapContainer, MINIMAPCONTAINER_MAJOR_VERSION, MINOR_VERSION, activate)