Mercurial > wow > reaction
diff modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua @ 30:0d95ce7a9ec2
- added Ace3 externs
- converted ReAction_ConfigUI to use blizzard interface addons panel via AceConfigDialog-3.0
- partially converted FuBar module to LibRock, deprecated it (going to remove it entirely later)
- cleaned up a couple other tidbits
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Wed, 02 Apr 2008 23:31:13 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/FuBar_ReActionFu/lib/LibFuBarPlugin-3.0/LibFuBarPlugin-3.0.lua Wed Apr 02 23:31:13 2008 +0000 @@ -0,0 +1,2145 @@ +--[[ +Name: LibFuBarPlugin-3.0 +Revision: $Rev: 63707 $ +Developed by: ckknight (ckknight@gmail.com) +Website: http://www.wowace.com/ +Description: Plugin for FuBar. +Dependencies: LibRock-1.0 +License: LGPL v2.1 +]] + +local MAJOR_VERSION = "LibFuBarPlugin-3.0" +local MINOR_VERSION = tonumber(("$Revision: 63707 $"):match("(%d+)")) - 60000 + +if not Rock then error(MAJOR_VERSION .. " requires LibRock-1.0") end + +local FuBarPlugin, oldLib = Rock:NewLibrary(MAJOR_VERSION, MINOR_VERSION) +if not FuBarPlugin then + return +end + +local SHOW_FUBAR_ICON = "Show FuBar icon" +local SHOW_FUBAR_ICON_DESC = "Show the FuBar plugin's icon on the panel." +local SHOW_FUBAR_TEXT = "Show FuBar text" +local SHOW_FUBAR_TEXT_DESC = "Show the FuBar plugin's text on the panel." +local SHOW_COLORED_FUBAR_TEXT = "Show colored FuBar text" +local SHOW_COLORED_FUBAR_TEXT_DESC = "Allow the FuBar plugin to color its text on the panel." +local DETACH_FUBAR_TOOLTIP = "Detach FuBar tooltip" +local DETACH_FUBAR_TOOLTIP_DESC = "Detach the FuBar tooltip from the panel." +local LOCK_FUBAR_TOOLTIP = "Lock tooltip" +local LOCK_FUBAR_TOOLTIP_DESC = "Lock the tooltips position. When the tooltip is locked, you must use Alt to access it with your mouse." +local POSITION_ON_FUBAR = "Position on FuBar" +local POSITION_ON_FUBAR_DESC = "Position the FuBar plugin on the panel." +local POSITION_LEFT = "Left" +local POSITION_RIGHT = "Right" +local POSITION_CENTER = "Center" +local ATTACH_PLUGIN_TO_MINIMAP = "Attach FuBar plugin to minimap" +local ATTACH_PLUGIN_TO_MINIMAP_DESC = "Attach the FuBar plugin to the minimap instead of the panel." +local HIDE_FUBAR_PLUGIN = "Hide FuBar plugin" +local HIDE_MINIMAP_BUTTON = "Hide minimap button" +local HIDE_FUBAR_PLUGIN_DESC = "Hide the FuBar plugin from the panel or minimap, leaving the addon running." +local OTHER = "Other" +local CLOSE = "Close" +local CLOSE_DESC = "Close the menu." + +if GetLocale() == "zhCN" then + SHOW_FUBAR_ICON = "显示FuBar图标" + SHOW_FUBAR_ICON_DESC = "在面板上显示FuBar插件的图标." + SHOW_FUBAR_TEXT = "显示FuBar文字" + SHOW_FUBAR_TEXT_DESC = "在面板上显示Fubar插件文字标题" + SHOW_COLORED_FUBAR_TEXT = "显示彩色文字" + SHOW_COLORED_FUBAR_TEXT_DESC = "允许插件显示彩色文字." + DETACH_FUBAR_TOOLTIP = "独立提示信息" + DETACH_FUBAR_TOOLTIP_DESC = "从面板上独立显示信息" + LOCK_FUBAR_TOOLTIP = "锁定提示信息" + LOCK_FUBAR_TOOLTIP_DESC = "锁定提示信息位置.当提示信息被锁定时,你必须要按Alt-鼠标方可查看." + POSITION_ON_FUBAR = "位置" + POSITION_ON_FUBAR_DESC = "FuBar插件在面板上的位置." + POSITION_LEFT = "居左" + POSITION_RIGHT = "居右" + POSITION_CENTER = "居中" + ATTACH_PLUGIN_TO_MINIMAP = "依附在小地图" + ATTACH_PLUGIN_TO_MINIMAP_DESC = "插件图标依附在小地图而不显示在面板上." + HIDE_FUBAR_PLUGIN = "隐藏FuBar插件" + HIDE_MINIMAP_BUTTON = "隐藏小地图按钮" + HIDE_FUBAR_PLUGIN_DESC = "隐藏在面板或小地图上的FuBar插件,暂定插件工作." + OTHER = "其他" + CLOSE = "关闭" + LOSE_DESC = "关闭目录." +elseif GetLocale() == "zhTW" then + SHOW_FUBAR_ICON = "顯示圖示" + SHOW_FUBAR_ICON_DESC = "在面板上顯示插件圖示。" + SHOW_FUBAR_TEXT = "顯示文字" + SHOW_FUBAR_TEXT_DESC = "在面板上顯示插件文字。" + SHOW_COLORED_FUBAR_TEXT = "允許彩色文字" + SHOW_COLORED_FUBAR_TEXT_DESC = "允許插件在面板上使用彩色文字。" + DETACH_FUBAR_TOOLTIP = "獨立提示訊息" + DETACH_FUBAR_TOOLTIP_DESC = "從面板上獨立提示訊息。" + LOCK_FUBAR_TOOLTIP = "鎖定提示訊息" + LOCK_FUBAR_TOOLTIP_DESC = "鎖定提示訊息位置。當提示訊息鎖定時,需要用Alt鍵使用提示訊息的功能。" + POSITION_ON_FUBAR = "位置" + POSITION_ON_FUBAR_DESC = "插件在面板上的位置。" + POSITION_LEFT = "靠左" + POSITION_RIGHT = "靠右" + POSITION_CENTER = "置中" + ATTACH_PLUGIN_TO_MINIMAP = "依附在小地圖" + ATTACH_PLUGIN_TO_MINIMAP_DESC = "插件圖標依附在小地圖而不顯示在面板上。" + HIDE_FUBAR_PLUGIN = "隱藏插件" + HIDE_MINIMAP_BUTTON = "隱藏小地圖按鈕" + HIDE_FUBAR_PLUGIN_DESC = "在面板或小地圖上隱藏該插件,但保持執行狀態。" + OTHER = "其他" + CLOSE = "關閉" + CLOSE_DESC = "關閉選單。" +elseif GetLocale() == "koKR" then + SHOW_FUBAR_ICON = "FuBar 아이콘 표시" + SHOW_FUBAR_ICON_DESC = "FuBar 패널에 플러그인 아이콘을 표시합니다." + SHOW_FUBAR_TEXT = "FuBar 텍스트 표시" + SHOW_FUBAR_TEXT_DESC = "FuBar 페널에 플러그인 텍스트를 표시합니다." + SHOW_COLORED_FUBAR_TEXT = "색상화된 FuBar 텍스트 표시" + SHOW_COLORED_FUBAR_TEXT_DESC = "패널의 FuBar 플러그인의 텍스트 색상을 허용합니다." + DETACH_FUBAR_TOOLTIP = "FuBar 툴팁 분리" + DETACH_FUBAR_TOOLTIP_DESC = "패널에서 FuBar 툴팁을 분리합니다." + LOCK_FUBAR_TOOLTIP = "툴팁 고정" + LOCK_FUBAR_TOOLTIP_DESC = "툴팁 위치를 고정시킵니다. 툴팁이 고정되어 있을때, 마우스로 접근하기 위해 Alt키를 사용하여야 합니다." + POSITION_ON_FUBAR = "FuBar 위치" + POSITION_ON_FUBAR_DESC = "패널 위의 FuBar 플러그인의 위치를 설정합니다." + POSITION_LEFT = "좌측" + POSITION_RIGHT = "우측" + POSITION_CENTER = "중앙" + ATTACH_PLUGIN_TO_MINIMAP = "FuBar 플러그인 미니맵 표시" + ATTACH_PLUGIN_TO_MINIMAP_DESC = "FuBar 플러그인을 패널 대신 미니맵에 표시합니다." + HIDE_FUBAR_PLUGIN = "FuBar 플러그인 숨김" + HIDE_MINIMAP_BUTTON = "미니맵 버튼 숨김" + HIDE_FUBAR_PLUGIN_DESC = "FuBar 플러그인을 패널이나 미니맵으로 부터 숨김니다." + OTHER = "기타" + CLOSE = "닫기" + CLOSE_DESC = "메뉴를 닫습니다." +elseif GetLocale() == "frFR" then + SHOW_FUBAR_ICON = "Afficher l'icône FuBar" + SHOW_FUBAR_ICON_DESC = "Affiche l'icône du plugin FuBar sur le panneau." + SHOW_FUBAR_TEXT = "Afficher le texte FuBar" + SHOW_FUBAR_TEXT_DESC = "Affiche le texte du plugin FuBar sur le panneau." + SHOW_COLORED_FUBAR_TEXT = "Afficher le texte FuBar coloré" + SHOW_COLORED_FUBAR_TEXT_DESC = "Autorise le plugin FuBar à colorer son texte sur le panneau." + DETACH_FUBAR_TOOLTIP = "Détacher l'infobulle FuBar" + DETACH_FUBAR_TOOLTIP_DESC = "Détache l'infobulle FuBar du panneau." + LOCK_FUBAR_TOOLTIP = "Verrouiller l'infobulle" + LOCK_FUBAR_TOOLTIP_DESC = "Verrouille l'infobulle dans sa position actuelle. Quand l'infobulle est verrouillée, vous devez utiliser la touche Alt pour y interagir avec la souris." + POSITION_ON_FUBAR = "Position sur FuBar" + POSITION_ON_FUBAR_DESC = "Position du plugin FuBar sur le panneau." + POSITION_LEFT = "Gauche" + POSITION_RIGHT = "Droite" + POSITION_CENTER = "Centre" + ATTACH_PLUGIN_TO_MINIMAP = "Attacher le plugin FuBar sur la minicarte" + ATTACH_PLUGIN_TO_MINIMAP_DESC = "Attache le plugin FuBar sur la minicarte au lieu du panneau." + HIDE_FUBAR_PLUGIN = "Masquer le plugin FuBar" + HIDE_MINIMAP_BUTTON = "Masquer le bouton de la minicarte" + HIDE_FUBAR_PLUGIN_DESC = "Masque le plugin FuBar du panneau ou de la minicarte, laissant l'addon fonctionner." + OTHER = "Autre" + CLOSE = "Fermer" + CLOSE_DESC = "Ferme le menu." +end + +-- #AUTODOC_NAMESPACE FuBarPlugin + +local precondition, argCheck = Rock:GetContractFunctions(MAJOR_VERSION, "precondition", "argCheck") +local newList, del = Rock:GetRecyclingFunctions(MAJOR_VERSION, "newList", "del") + +FuBarPlugin.pluginToFrame = oldLib and oldLib.pluginToFrame or {} +local pluginToFrame = FuBarPlugin.pluginToFrame +FuBarPlugin.pluginToMinimapFrame = oldLib and oldLib.pluginToMinimapFrame or {} +local pluginToMinimapFrame = FuBarPlugin.pluginToMinimapFrame +FuBarPlugin.pluginToPanel = oldLib and oldLib.pluginToPanel or {} +local pluginToPanel = FuBarPlugin.pluginToPanel +FuBarPlugin.pluginToOptions = oldLib and oldLib.pluginToOptions or {} +local pluginToOptions = FuBarPlugin.pluginToOptions +FuBarPlugin.folderNames = oldLib and oldLib.folderNames or {} +local folderNames = FuBarPlugin.folderNames + +local Tablet20 +local Dewdrop20 + +FuBarPlugin.MinimapContainer = oldLib and oldLib.MinimapContainer or {} +local MinimapContainer = FuBarPlugin.MinimapContainer + +local epsilon = 1e-5 + +-- #AUTODOC_NAMESPACE FuBarPlugin + +--[[--------------------------------------------------------------------------- +Notes: + *Set metadata about a certain plugin. + ; tooltipType : string - + : "GameTooltip" + :: Use Blizzard's GameTooltip. (default if not given) + : "Tablet-2.0" + :: Use Tablet-2.0. + : "Custom" + :: LibFuBarPlugin-3.0 will not provide any extra mechanisms, all done manually. + ; configType : string - + : "LibRockConfig-1.0" + :: Use LibRockConfig-1.0 to show configuration. (default if not given) + : "Dewdrop-2.0" + :: Use Dewdrop-2.0. + ; hasNoText : boolean - If set to true, then it will be a text-less frame. + ; iconPath : string - the path of the icon to show. + ; hasNoColor : boolean - If set to true, then it is assumed that no color will be in the text (and thus not show the menu item) + ; cannotHideText : boolean - If set to true, then the menu item to hide text will not be shown. + ; overrideMenu : boolean - If set to true, then the menu will not show any of the standard menu items + ; hideMenuTitle : boolean - If set to true, the plugins name will not be added to the top of the menu as a header. + ; defaultPosition : string - + : "LEFT" + ::show on the left. (default if not given) + : "CENTER" + ::show in the center. + : "RIGHT" + ::show on the right. + : "MINIMAP" + ::show on the minimap. + ; defaultMinimapPosition : number - Angle on the minimap, in degrees. [0, 360) + ; clickableTooltip : boolean - Whether you can drag your mouse onto the tooltip and click a line + ; tooltipHiddenWhenEmpty : boolean - Whether the detached tooltip is hidden when it is empty. + ; cannotDetachTooltip : boolean - Whether the tooltip cannot be detached from the plugin text. + ::Normally, a tooltip can detach (if using Tablet-2.0). This should be set if there is no relevant data in the tooltip. + ; independentProfile : boolean - If set to true, then the profile setting will not be stripped from .OnMenuRequest, and FuBar will not set the plugin's profile when it changes. + ::non-FuBar-centric plugins should set this to true. +Arguments: + string - the key to set + value - the value to set said key to. +Example: + self:SetFuBarOption('tooltipType', "Tablet-2.0") +-----------------------------------------------------------------------------]] +function FuBarPlugin:SetFuBarOption(key, value) + local pluginToOptions_self = pluginToOptions[self] + if not pluginToOptions_self then + pluginToOptions_self = {} + pluginToOptions[self] = pluginToOptions_self + end + + pluginToOptions_self[key] = value + + if key == 'tooltipType' then + if value == "Tablet-2.0" then + Tablet20 = Rock("Tablet-2.0", false, true) + if not Tablet20 then + error(("Cannot specify %q = %q if %q is not loaded."):format(key, value, value), 2) + end + end + end + if key == 'configType' then + if value == "Dewdrop-2.0" then + Dewdrop20 = Rock("Dewdrop-2.0", false, true) + if not Dewdrop20 then + error(("Cannot specify %q = %q if %q is not loaded."):format(key, value, value), 2) + end + end + end +end +precondition(FuBarPlugin, 'SetFuBarOption', function(self, key, value) + argCheck(self, 1, "table") + argCheck(key, 2, "string") + argCheck(value, 3, "string", "number", "boolean") + + if pluginToOptions[self] and pluginToOptions[self][key] ~= nil then + error(("Bad argument #2 to `SetFuBarOption'. Cannot specify %q more than once."):format(key), 3) + end +end) + +local function getPluginOption(object, key, default) + local pluginToOptions_object = pluginToOptions[object] + if pluginToOptions_object == nil then + return default + end + local value = pluginToOptions_object[key] + if value == nil then + return default + end + return value +end + +local good = nil +local function CheckFuBar() + if not good then + if FuBar then + local version = FuBar.version + if type(version) == "string" then + local num = version:match("^(%d+%.?%d*)") + if num then + num = tonumber(num) + good = num >= 3 + end + end + end + end + return good +end + +--[[--------------------------------------------------------------------------- +Returns: + string - the localized name of the plugin, not including the "FuBar - " part. +Example + local title = self:GetTitle() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetTitle() + local name = self.title or self.name + if type(name) ~= "string" then + error("You must provide self.title or self.name", 2) + end + local title = name:match("[Ff][Uu][Bb][Aa][Rr]%s*%-%s*(.-)%s*$") or name + return title:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "") +end + +--[[--------------------------------------------------------------------------- +Returns: + string - name of the plugin. +Notes: + This is here for FuBar core to communicate properly. +Example: + local name = self:GetName() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetName() + return self.name +end + +--[[--------------------------------------------------------------------------- +Returns: + string - category of the plugin. +Notes: + This is here for FuBar core to communicate properly. +Example: + local category = self:GetCategory() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetCategory() + return self.category or OTHER +end + +--[[--------------------------------------------------------------------------- +Returns: + frame - frame for the plugin. +Notes: + This is here for FuBar core to communicate properly. +Example: + local frame = self:GetFrame() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetFrame() + return pluginToFrame[self] +end + +--[[--------------------------------------------------------------------------- +Returns: + object - panel for the plugin. +Notes: + This is here for FuBar core to communicate properly. +Example: + local panel = self:GetPanel() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetPanel() + return pluginToPanel[self] +end + +local function getLazyDatabaseValueDefault(object, value, ...) + local object_db = object.db + if type(object_db) ~= "table" then + return value + end + local current = object_db.profile + for i = 1, select('#', ...) do + -- traverse through, make sure tables exist. + if type(current) ~= "table" then + return value + end + current = current[(select(i, ...))] + end + if current == nil then + return value + else + return current + end +end + +local function getLazyDatabaseValue(object, ...) + return getLazyDatabaseValueDefault(object, nil, ...) +end + +local function setLazyDatabaseValue(object, value, ...) + local object_db = object.db + if type(object_db) ~= "table" then + return nil + end + local current = object_db.profile + if type(current) ~= "table" then + return nil + end + local n = select('#', ...) + for i = 1, n-1 do + -- traverse through, create tables if necessary. + local nextOne = current[(select(i, ...))] + if type(nextOne) ~= "table" then + if nextOne ~= nil then + return nil + end + nextOne = {} + current[(select(i, ...))] = nextOne + end + current = nextOne + end + current[select(n, ...)] = value + return true +end + +--[[--------------------------------------------------------------------------- +Returns: + boolean - whether the text has color applied. +Example: + local colored = self:IsFuBarTextColored() +-----------------------------------------------------------------------------]] +function FuBarPlugin:IsFuBarTextColored() + return not getLazyDatabaseValue(self, 'uncolored') +end + +--[[--------------------------------------------------------------------------- +Notes: + Toggles whether the text has color applied +Example: + self:ToggleTextColored() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ToggleFuBarTextColored() + if not setLazyDatabaseValue(self, not getLazyDatabaseValue(self, 'uncolored') or nil, 'uncolored') then + error(("%s: Cannot change text color if self.db is not available."):format(self:GetTitle()), 2) + end + self:UpdateFuBarText() +end + +--[[--------------------------------------------------------------------------- +Returns: + boolean - whether the plugin is attached to the minimap. +Example: + local attached = self:IsMinimapAttached() +-----------------------------------------------------------------------------]] +function FuBarPlugin:IsFuBarMinimapAttached() + if not CheckFuBar() then + return true + end + return pluginToPanel[self] == MinimapContainer +end + +--[[--------------------------------------------------------------------------- +Notes: + Toggles whether the plugin is attached to the minimap. +Example: + self:ToggleMinimapAttached() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ToggleFuBarMinimapAttached() + if CheckFuBar() and not getPluginOption(self, 'cannotAttachToMinimap', false) then + local panel = pluginToPanel[self] + local value = panel == MinimapContainer + if value then + panel:RemovePlugin(self) + local defaultPosition = getPluginOption(self, 'defaultPosition', "LEFT") + FuBar:GetPanel(1):AddPlugin(self, nil, defaultPosition == "MINIMAP" and "LEFT" or defaultPosition) + else + if panel then + panel:RemovePlugin(self) + end + MinimapContainer:AddPlugin(self) + end + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Calls :UpdateFuBarText() and :UpdateFuBarTooltip(), in that order. +Example: + self:UpdateFuBarPlugin() +-----------------------------------------------------------------------------]] +function FuBarPlugin:UpdateFuBarPlugin() + self:UpdateFuBarText() + self:UpdateFuBarTooltip() +end + +--[[--------------------------------------------------------------------------- +Notes: + * Calls :OnUpdateFuBarText() if it is available and the plugin is not disabled. + * It is expected to update the icon in :OnUpdateFuBarText as well as text. +Example: + self:UpdateFuBarText() +-----------------------------------------------------------------------------]] +function FuBarPlugin:UpdateFuBarText() + if type(self.OnUpdateFuBarText) == "function" then + if not self:IsDisabled() then + self:OnUpdateFuBarText() + end + elseif self:IsFuBarTextShown() then + self:SetFuBarText(self:GetTitle()) + end +end + +local function Tablet20_point(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 + +local function RegisterTablet20(self) + local frame = pluginToFrame[self] + if not Tablet20:IsRegistered(frame) then + local db = getLazyDatabaseValue(self) + if db and not db.detachedTooltip then + db.detachedTooltip = {} + end + Tablet20:Register(frame, + 'children', function() + Tablet20:SetTitle(self:GetTitle()) + if type(self.OnUpdateFuBarTooltip) == "function" then + if not self:IsDisabled() then + self:OnUpdateFuBarTooltip() + end + end + end, + 'clickable', getPluginOption(self, 'clickableTooltip', false), + 'data', CheckFuBar() and FuBar.db.profile.tooltip or db and db.detachedTooltip or {}, + 'detachedData', db and db.detachedTooltip or {}, + 'point', Tablet20_point, + '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 name:find('^table:') then + name = name:gsub("|c%x%x%x%x%x%x%x%x(.-)|r", "%1") + Rock("Dewdrop-2.0"):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 + Rock("Dewdrop-2.0"):FeedAceOptionsTable(self.OnMenuRequest) + end + end, + 'hideWhenEmpty', getPluginOption(self, 'tooltipHiddenWhenEmpty', false) + ) + local func = pluginToFrame[self]:GetScript("OnEnter") + frame:SetScript("OnEnter", function(this, ...) + -- HACK + func(this, ...) + + if FuBar and FuBar.IsHidingTooltipsInCombat and FuBar:IsHidingTooltipsInCombat() and InCombatLockdown() then + if Tablet20:IsAttached(this) then + Tablet20:Close(this) + end + end + end) + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Calls :OnUpdateFuBarTooltip() if it is available, the plugin is not disabled, and the tooltip is shown. +Example: + self:UpdateFuBarTooltip() +-----------------------------------------------------------------------------]] +function FuBarPlugin:UpdateFuBarTooltip() + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + + if tooltipType == "GameTooltip" then + local frame = self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self] + if not GameTooltip:IsOwned(frame) then + return + end + GameTooltip:Hide() + + local anchor + if frame:GetTop() > GetScreenHeight() / 2 then + local x = frame:GetCenter() + if x < GetScreenWidth() / 2 then + anchor = "ANCHOR_BOTTOMRIGHT" + else + anchor = "ANCHOR_BOTTOMLEFT" + end + else + local x = frame:GetCenter() + if x < GetScreenWidth() / 2 then + anchor = "ANCHOR_TOPLEFT" + else + anchor = "ANCHOR_TOPRIGHT" + end + end + GameTooltip:SetOwner(frame, anchor) + if type(self.OnUpdateFuBarTooltip) == "function" and not self:IsDisabled() then + self:OnUpdateFuBarTooltip() + end + GameTooltip:Show() + return + elseif tooltipType == "Custom" then + if type(self.OnUpdateFuBarTooltip) == "function" and not self:IsDisabled() then + self:OnUpdateFuBarTooltip() + end + return + elseif tooltipType == "Tablet-2.0" then + RegisterTablet20(self) + if self:IsFuBarMinimapAttached() and not self:IsFuBarTooltipDetached() and pluginToMinimapFrame[self] then + Tablet20:Refresh(pluginToMinimapFrame[self]) + else + Tablet20:Refresh(pluginToFrame[self]) + end + elseif tooltipType == "None" then + return + else + error(("Unknown %s option for %q: %q"):format(MAJOR_VERSION, 'tooltipType', tostring(tooltipType)), 2) + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Shows the plugin, enables the plugin if previously disabled, and calls :UpdateFuBarPlugin(). +Example: + self:Show() +-----------------------------------------------------------------------------]] +function FuBarPlugin:Show(panelId) + if pluginToFrame[self]:IsShown() or (pluginToMinimapFrame[self] and pluginToMinimapFrame[self]:IsShown()) then + return + end + if panelId ~= false then + setLazyDatabaseValue(self, nil, 'hidden') + end + if self.IsActive and not self:IsActive() then + self.panelIdTmp = panelId + self:ToggleActive() + self.panelIdTmp = nil + setLazyDatabaseValue(self, nil, 'disabled') + elseif not getLazyDatabaseValue(self, 'hidden') then + if panelId == 0 or not CheckFuBar() then + MinimapContainer:AddPlugin(self) + else + FuBar:ShowPlugin(self, panelId or self.panelIdTmp) + end + if not getPluginOption(self, 'userDefinedFrame', false) then + if not self:IsFuBarTextShown() then + local text = pluginToFrame[self].text + text:SetText("") + text:SetWidth(epsilon) + text:Hide() + end + if not self:IsFuBarIconShown() then + local icon = pluginToFrame[self].icon + icon:SetWidth(epsilon) + icon:Hide() + end + end + self:UpdateFuBarPlugin() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Hides the plugin, disables the plugin if cannot hide without standby. +Arguments: + [optional] boolean - internal variable. Do not set this. +Example: + self:Hide() +-----------------------------------------------------------------------------]] +function FuBarPlugin:Hide(check) + if not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown()) then + return + end + local hideWithoutStandby = getPluginOption(self, 'hideWithoutStandby', false) + if hideWithoutStandby and check ~= false then + setLazyDatabaseValue(self, true, 'hidden') + end + if not hideWithoutStandby then + if getPluginOption(self, 'tooltipType', "GameTooltip") == "Tablet-2.0" and not getPluginOption(self, 'cannotDetachTooltip', false) and self:IsFuBarTooltipDetached() and getLazyDatabaseValue(self, 'detachedTooltip', 'detached') then + self:ReattachTooltip() + setLazyDatabaseValue(self, true, 'detachedTooltip', 'detached') + end + if self.IsActive and self:IsActive() and self.ToggleActive and (not CheckFuBar() or not FuBar:IsChangingProfile()) then + self:ToggleActive() + end + end + if pluginToPanel[self] then + pluginToPanel[self]:RemovePlugin(self) + end + pluginToFrame[self]:Hide() + if pluginToMinimapFrame[self] then + pluginToMinimapFrame[self]:Hide() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Sets the path to the icon for the plugin. +Arguments: + string or nil - The path to the icon. If nil, then no icon. +Example: + self:SetFuBarIcon("Interface\\AddOns\\MyAddon\\otherIcon") +-----------------------------------------------------------------------------]] +function FuBarPlugin:SetFuBarIcon(path) + if not path then + return + end + if not pluginToFrame[self] or not pluginToFrame[self].icon then + return + end + if path:match([[^Interface\Icons\]]) then + pluginToFrame[self].icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) + else + pluginToFrame[self].icon:SetTexCoord(0, 1, 0, 1) + end + pluginToFrame[self].icon:SetTexture(path) + if pluginToMinimapFrame[self] and pluginToMinimapFrame[self].icon then + if path:match([[^Interface\Icons\]]) then + pluginToMinimapFrame[self].icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) + else + pluginToMinimapFrame[self].icon:SetTexCoord(0, 1, 0, 1) + end + pluginToMinimapFrame[self].icon:SetTexture(path) + end +end +precondition(FuBarPlugin, 'SetFuBarIcon', function(self, path) + if not path then + return + end + argCheck(path, 2, "string", "nil") + if not getPluginOption(self, 'iconPath', false) then + error(("%s: Cannot set icon unless 'iconPath' is set."):format(self:GetTitle()), 3) + end +end) + +--[[--------------------------------------------------------------------------- +Returns: + string or nil - The path to the icon for the plugin. If nil, then no icon. +Example: + local path = self:GetFuBarIcon() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetFuBarIcon() + if getPluginOption(self, 'iconPath', false) then + return pluginToFrame[self] and pluginToFrame[self].icon and pluginToFrame[self].icon:GetTexture() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Checks the current width of the icon and text, then updates frame to expand/shrink to it if necessary. +Arguments: + [optional] boolean - if true, Shrink/expand no matter what, otherwise if the width is less than 8 pixels smaller, don't shrink. +Example: + self:CheckWidth(true) +-----------------------------------------------------------------------------]] +function FuBarPlugin:CheckWidth(force) + local frame = pluginToFrame[self] + if not frame then + return + end + local icon = frame.icon + local text = frame.text + if (not icon or not icon:IsShown()) and (not text or not text:IsShown()) then + return + end + + local db = getLazyDatabaseValue(self) + + if (db and not self:IsFuBarIconShown()) or not getPluginOption(self, 'iconPath', false) then + icon:SetWidth(epsilon) + end + local width + if not getPluginOption(self, 'hasNoText', false) then + text:SetHeight(0) + text:SetWidth(500) + width = text:GetStringWidth() + 1 + text:SetWidth(width) + text:SetHeight(text:GetHeight()) + end + local panel = pluginToPanel[self] + if getPluginOption(self, 'hasNoText', false) or not text:IsShown() then + frame:SetWidth(icon:GetWidth()) + if panel and panel:GetPluginSide(self) == "CENTER" then + panel:UpdateCenteredPosition() + end + elseif force or not frame.textWidth or frame.textWidth < width or frame.textWidth - 8 > width then + frame.textWidth = width + text:SetWidth(width) + if icon and icon:IsShown() then + frame:SetWidth(width + icon:GetWidth()) + else + frame:SetWidth(width) + end + if panel and panel:GetPluginSide(self) == "CENTER" then + panel:UpdateCenteredPosition() + end + end +end +precondition(FuBarPlugin, 'CheckWidth', function(self, force) + argCheck(force, 2, "boolean", "nil") +end) + +--[[--------------------------------------------------------------------------- +Notes: + Sets the text of the plugin. Should only be called from within :OnFuBarUpdateText() +Arguments: + string - text to set the plugin to. If not given, set to title. +Example: + myAddon.OnFuBarUpdateText = function(self) + self:SetFuBarText("Hello") + fend +-----------------------------------------------------------------------------]] +function FuBarPlugin:SetFuBarText(text) + local frame = pluginToFrame[self] + if not frame or not frame.text then + return + end + if text == "" then + if getPluginOption(self, 'iconPath', false) then + self:ShowFuBarIcon() + else + text = self:GetTitle() + end + end + if not self:IsFuBarTextColored() then + text = text:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "") + end + frame.text:SetText(text) + self:CheckWidth() +end +precondition(FuBarPlugin, 'SetFuBarText', function(self, text) + local frame = pluginToFrame[self] + if not frame or not frame.text then + return + end + if getPluginOption(self, 'hasNoText', false) then + error(("%s: Cannot set text if 'hasNoText' has been set."):format(self:GetTitle()), 3) + end + argCheck(text, 2, "string", "number") +end) + +--[[--------------------------------------------------------------------------- +Returns: + string - The current text of the plugin. +Example: + local text = self:GetFuBarText() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetFuBarText() + local frame = pluginToFrame[self] + if not frame or not frame.text then + error(("%s: Cannot get text without a text frame."):format(self:GetTitle()), 2) + end + if not getPluginOption(self, 'hasNoText', false) then + return frame.text:GetText() or "" + end +end + +--[[--------------------------------------------------------------------------- +Returns: + boolean - whether the icon for the plugin is showing. +Example: + local isIconShowing = self:IsFuBarIconShown() +-----------------------------------------------------------------------------]] +function FuBarPlugin:IsFuBarIconShown() + if not getPluginOption(self, 'iconPath', false) then + return false + elseif getPluginOption(self, 'hasNoText', false) then + return true + end + return not not getLazyDatabaseValueDefault(self, true, 'showIcon') +end + +--[[--------------------------------------------------------------------------- +Notes: + Toggles whether the icon for the plugin is showing. +Example: + self:ToggleFuBarIconShown() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ToggleFuBarIconShown() + local frame = pluginToFrame[self] + local icon = frame and frame.icon + local text = frame and frame.text + if not icon then + error(("%s: Cannot toggle icon without an icon frame."):format(self:GetTitle()), 2) + elseif not text then + error(("%s: Cannot toggle icon without a text frame."):format(self:GetTitle()), 2) + elseif not getPluginOption(self, 'iconPath', false) then + error(("%s: Cannot show icon unless 'iconPath' is set."):format(self:GetTitle()), 2) + elseif getPluginOption(self, 'hasNoText', false) then + error(("%s: Cannot show icon if 'hasNoText' is set."):format(self:GetTitle()), 2) + elseif not getLazyDatabaseValue(self) then + error(("%s: Cannot hide icon if self.db is not available."):format(self:GetTitle()), 2) + end + local value = not self:IsFuBarIconShown() + setLazyDatabaseValue(self, value, 'showIcon') + if value then + if not self:IsFuBarTextShown() and text:IsShown() and text:GetText() == self:GetTitle() then + text:Hide() + text:SetText("") + end + icon:Show() + icon:SetWidth(pluginToFrame[self].icon:GetHeight()) + self:UpdateFuBarText() + else + if not text:IsShown() or not text:GetText() or text:GetText() == "" then + text:Show() + text:SetText(self:GetTitle()) + end + icon:Hide() + icon:SetWidth(epsilon) + end + self:CheckWidth(true) + return value +end + +--[[--------------------------------------------------------------------------- +Notes: + Shows the icon of the plugin if hidden. +Example: + self:ShowFuBarIcon() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ShowFuBarIcon() + if not self:IsFuBarIconShown() then + self:ToggleFuBarIconShown() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Hides the icon of the plugin if shown. +Example: + self:HideFuBarIcon() +-----------------------------------------------------------------------------]] +function FuBarPlugin:HideFuBarIcon() + if self:IsFuBarIconShown() then + self:ToggleFuBarIconShown() + end +end + +--[[--------------------------------------------------------------------------- +Returns: + boolean - whether the text for the plugin is showing. +Example: + local isTextShowing = self:IsFuBarTextShown() +-----------------------------------------------------------------------------]] +function FuBarPlugin:IsFuBarTextShown() + if getPluginOption(self, 'hasNoText', false) then + return false + elseif not getPluginOption(self, 'iconPath', false) then + return true + end + return not not getLazyDatabaseValueDefault(self, true, 'showText') +end + +--[[--------------------------------------------------------------------------- +Notes: + Toggles whether the text for the plugin is showing. +Example: + self:ToggleFuBarTextShown() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ToggleFuBarTextShown() + local frame = pluginToFrame[self] + local icon = frame and frame.icon + local text = frame and frame.text + if not icon then + error(("%s: Cannot toggle text without an icon frame."):format(self:GetTitle()), 2) + elseif not text then + error(("%s: Cannot toggle text without a text frame."):format(self:GetTitle()), 2) + elseif getPluginOption(self, 'cannotHideText', false) then + error(("%s: Cannot toggle text if 'cannotHideText' is set."):format(self:GetTitle()), 2) + elseif not getPluginOption(self, 'iconPath', false) then + error(("%s: Cannot toggle text unless 'iconPath' is set."):format(self:GetTitle()), 2) + elseif getPluginOption(self, 'hasNoText', false) then + error(("%s: Cannot toggle text if 'hasNoText' is set."):format(self:GetTitle()), 2) + elseif not getLazyDatabaseValue(self) then + error(("%s: Cannot toggle text if self.db is not available."):format(self:GetTitle()), 2) + end + local value = not self:IsFuBarTextShown() + setLazyDatabaseValue(self, value, 'showText') + if value then + text:Show() + self:UpdateFuBarText() + else + text:SetText("") + text:SetWidth(epsilon) + text:Hide() + self:ShowFuBarIcon() + end + self:CheckWidth(true) + return value +end + +--[[--------------------------------------------------------------------------- +Notes: + Shows the text of the plugin if hidden. +Example: + self:ShowFuBarText() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ShowFuBarText() + if not self:IsFuBarTextShown() then + self:ToggleFuBarTextShown() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Hides the text of the plugin if shown. +Example: + self:HideFuBarText() +-----------------------------------------------------------------------------]] +function FuBarPlugin:HideFuBarText() + if self:IsFuBarTextShown() then + self:ToggleFuBarTextShown() + end +end + +--[[--------------------------------------------------------------------------- +Returns: + string - default position of the plugin. +Notes: + This is here for FuBar core to communicate properly. +Example: + local pos = self:GetDefaultPosition() +-----------------------------------------------------------------------------]] +function FuBarPlugin:GetDefaultPosition() + return getPluginOption(self, 'defaultPosition', "LEFT") +end + +--[[--------------------------------------------------------------------------- +Returns: + boolean - Whether the tooltip is detached. +Example: + local detached = self:IsFuBarTooltipDetached() +-----------------------------------------------------------------------------]] +function FuBarPlugin:IsFuBarTooltipDetached() + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType ~= "Tablet-2.0" then + return + end + + RegisterTablet20(self) + return not Tablet20:IsAttached(pluginToFrame[self]) +end + +--[[--------------------------------------------------------------------------- +Notes: + Toggles whether the tooltip is detached. +Example: + self:ToggleFuBarTooltipDetached() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ToggleFuBarTooltipDetached() + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType ~= "Tablet-2.0" then + return + end + + RegisterTablet20(self) + if Tablet20:IsAttached(pluginToFrame[self]) then + Tablet20:Detach(pluginToFrame[self]) + else + Tablet20:Attach(pluginToFrame[self]) + end +end + +--[[--------------------------------------------------------------------------- +Notes: + * Detaches the tooltip from the plugin. + * This does nothing if already detached. +Example: + self:DetachFuBarTooltip() +-----------------------------------------------------------------------------]] +function FuBarPlugin:DetachFuBarTooltip() + if not self:IsFuBarTooltipDetached() then + self:ToggleFuBarTooltipDetached() + end +end + +--[[--------------------------------------------------------------------------- +Notes: + Reattaches the tooltip to the plugin. + This does nothing if already attached. +Example: + self:ReattachFuBarTooltip() +-----------------------------------------------------------------------------]] +function FuBarPlugin:ReattachFuBarTooltip() + if self:IsFuBarTooltipDetached() then + self:ToggleFuBarTooltipDetached() + end +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 + +-- #NODOC +-- this is used internally by FuBar +function FuBarPlugin:SetPanel(panel) + pluginToPanel[self] = panel +end +precondition(FuBarPlugin, 'SetPanel', function(self, panel) + argCheck(panel, 2, "table", "nil") + if panel and not IsCorrectPanel(panel) then + error("Bad argument #2 to `SetPanel'. Panel does not have the correct API.", 3) + end +end) + +-- #NODOC +-- this is used internally by FuBar +function FuBarPlugin:SetFontSize(size) + if getPluginOption(self, 'userDefinedFrame', false) then + error(("%sYou must provide a :SetFontSize(size) method if you have 'userDefinedFrame' set."):format(self.name and self.name .. ": " or ""), 2) + end + if getPluginOption(self, 'iconPath', false) then + local frame = pluginToFrame[self] + local icon = frame and frame.icon + if not icon then + error(("%sno icon frame found."):format(self.name and self.name .. ": " or ""), 2) + end + icon:SetWidth(size + 3) + icon:SetHeight(size + 3) + end + if not getPluginOption(self, 'hasNoText', false) then + local frame = pluginToFrame[self] + local text = frame and frame.text + if not text then + error(("%sno text frame found."):format(self.name and self.name .. ": " or ""), 2) + end + local font, _, flags = text:GetFont() + text:SetFont(font, size, flags) + end + self:CheckWidth() +end + +local function IsLoadOnDemand(plugin) + return IsAddOnLoadOnDemand(folderNames[plugin] or "") +end + +-- #NODOC +-- this is used internally by FuBar. +function FuBarPlugin:IsDisabled() + return type(self.IsActive) == "function" and not self:IsActive() or false +end + +function FuBarPlugin:OnEmbed(target) + local folder = Rock.addonToFolder[target] + if not folder then + for i = 6, 3, -1 do + folder = debugstack(i, 1, 0):match([[\AddOns\(.*)\]]) + if folder then + break + end + end + end + folderNames[target] = folder +end + +local frame_OnClick, frame_OnDoubleClick, frame_OnMouseDown, frame_OnMouseUp, frame_OnReceiveDrag, frame_OnEnter, frame_OnLeave +--[[--------------------------------------------------------------------------- +Arguments: + [optional] string - name of the frame +Returns: + frame - a frame with the basic scripts to be considered a plugin frame. +Example: + MyPlugin.frame = MyPlugin:CreateBasicPluginFrame("FuBar_MyPluginFrame") +-----------------------------------------------------------------------------]] +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_OnEnter then + function frame_OnEnter(this) + local self = this.self + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType == "GameTooltip" then + GameTooltip:SetOwner(self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self], "ANCHOR_CURSOR") + self:UpdateFuBarTooltip() + end + if type(self.OnFuBarEnter) == "function" then + self:OnFuBarEnter() + end + end + end + frame:SetScript("OnEnter", frame_OnEnter) + if not frame_OnLeave then + function frame_OnLeave(this) + local self = this.self + if type(self.OnFuBarLeave) == "function" then + self:OnFuBarLeave() + end + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType == "GameTooltip" and GameTooltip:IsOwned(self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self]) then + GameTooltip:Hide() + end + end + end + frame:SetScript("OnLeave", frame_OnLeave) + if not frame_OnClick then + function frame_OnClick(this, button) + local self = this.self + if self:IsFuBarMinimapAttached() and this.dragged then return end + if type(self.OnFuBarClick) == "function" then + self:OnFuBarClick(button) + end + end + end + frame:SetScript("OnClick", frame_OnClick) + if not frame_OnDoubleClick then + function frame_OnDoubleClick(this, button) + local self = this.self + if type(self.OnFuBarDoubleClick) == "function" then + self:OnFuBarDoubleClick(button) + end + end + end + frame:SetScript("OnDoubleClick", frame_OnDoubleClick) + if not frame_OnMouseDown then + function frame_OnMouseDown(this, button) + local self = this.self + if button == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then + self:OpenMenu() + return + else + if type(self.OnFuBarMouseDown) == "function" then + self:OnFuBarMouseDown(button) + end + end + end + end + frame:SetScript("OnMouseDown", frame_OnMouseDown) + if not frame_OnMouseUp then + function frame_OnMouseUp(this, button) + local self = this.self + if type(self.OnFuBarMouseUp) == "function" then + self:OnFuBarMouseUp(button) + end + end + end + frame:SetScript("OnMouseUp", frame_OnMouseUp) + if not frame_OnReceiveDrag then + function frame_OnReceiveDrag(this) + local self = this.self + if (self:IsFuBarMinimapAttached() and not this.dragged) and type(self.OnReceiveDrag) == "function" then + self:OnFuBarReceiveDrag() + 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 +--[[--------------------------------------------------------------------------- +Arguments: + string - type of the frame, e.g. "Frame", "Button", etc. + [optional] string - name of the frame + [optional] frame - parent frame +Returns: + frame - a child frame that can be manipulated and used +Example: + local child = self:CreatePluginChildFrame("Frame", nil, self.frame) +-----------------------------------------------------------------------------]] +function FuBarPlugin:CreatePluginChildFrame(frameType, name, parent) + 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(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:GetScript("OnEnter") then + frame:GetScript("OnEnter")(frame, ...) + end + end + end + child:SetScript("OnEnter", child_OnEnter) + if not child_OnLeave then + function child_OnLeave(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:GetScript("OnLeave") then + frame:GetScript("OnLeave")(frame, ...) + end + end + end + child:SetScript("OnLeave", child_OnLeave) + if child:HasScript("OnClick") then + if not child_OnClick then + function child_OnClick(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:HasScript("OnClick") and frame:GetScript("OnClick") then + frame:GetScript("OnClick")(frame, ...) + end + end + end + child:SetScript("OnClick", child_OnClick) + end + if child:HasScript("OnDoubleClick") then + if not child_OnDoubleClick then + function child_OnDoubleClick(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:HasScript("OnDoubleClick") and frame:GetScript("OnDoubleClick") then + frame:GetScript("OnDoubleClick")(frame, ...) + end + end + end + child:SetScript("OnDoubleClick", child_OnDoubleClick) + end + if not child_OnMouseDown then + function child_OnMouseDown(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:HasScript("OnMouseDown") and frame:GetScript("OnMouseDown") then + frame:GetScript("OnMouseDown")(frame, ...) + end + end + end + child:SetScript("OnMouseDown", child_OnMouseDown) + if not child_OnMouseUp then + function child_OnMouseUp(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:HasScript("OnMouseUp") and frame:GetScript("OnMouseUp") then + frame:GetScript("OnMouseUp")(frame, ...) + end + end + end + child:SetScript("OnMouseUp", child_OnMouseUp) + if not child_OnReceiveDrag then + function child_OnReceiveDrag(this, ...) + local self = this.self + local frame = pluginToFrame[self] + if frame:HasScript("OnReceiveDrag") and frame:GetScript("OnReceiveDrag") then + frame:GetScript("OnReceiveDrag")(frame, ...) + end + end + end + child:SetScript("OnReceiveDrag", child_OnReceiveDrag) + return child +end +precondition(FuBarPlugin, 'CreatePluginChildFrame', function(self, frameType, name, parent) + if not pluginToFrame[self] then + error(("%sYou must have self.frame declared in order to add child frames."):format(self.name and self.name .. ": " or ""), 3) + end + argCheck(frameType, 2, "string") +end) + +--[[--------------------------------------------------------------------------- +Notes: + Opens the configuration menu associated with this plugin. +Example: + self:OpenMenu() +-----------------------------------------------------------------------------]] +function FuBarPlugin:OpenMenu(frame) + if not frame then + frame = self:IsFuBarMinimapAttached() and pluginToMinimapFrame[self] or pluginToFrame[self] + end + if not frame:IsVisible() then + frame = UIParent + end + local configType = getPluginOption(self, 'configType', "LibRockConfig-1.0") + if configType == "Dewdrop-2.0" then + if not frame or not self:GetFrame() or Dewdrop20:IsOpen(frame) then + Dewdrop20:Close() + return + end + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType == "GameTooltip" then + if GameTooltip:IsOwned(frame) then + GameTooltip:Hide() + end + elseif tooltipType == "Custom" and type(self.CloseTooltip) == "function" then + self:CloseTooltip() + elseif tooltipType == "Tablet-2.0" and Tablet20 then + Tablet20:Close() + end + + if not Dewdrop20: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 + Dewdrop20:InjectAceOptionsTable(self, self.OnMenuRequest) + if self.OnMenuRequest.args and CheckFuBar() and not getPluginOption(self, 'independentProfile', false) then + self.OnMenuRequest.args.profile = nil + if self.OnMenuRequest.extraArgs then + self.OnMenuRequest.extraArgs.profile = nil + end + end + end + Dewdrop20: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 + if not getPluginOption(self, 'hideMenuTitle', false) then + Dewdrop20:AddLine( + 'text', self:GetTitle(), + 'isTitle', true + ) + end + + if self.OnMenuRequest then + self:OnMenuRequest(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4) + end + + if not getPluginOption(self, 'overrideMenu', false) then + if self.MenuSettings and not getPluginOption(self, 'hideMenuTitle', false) then + Dewdrop20:AddLine() + end + self:AddImpliedMenuOptions() + end + else + if not getPluginOption(self, 'overrideMenu', false) 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 + Dewdrop20: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 + Dewdrop20:Open(self:GetFrame()) + elseif frame ~= UIParent then + Dewdrop20:Open(frame, self:GetFrame()) + else + Dewdrop20:Open(frame, self:GetFrame(), 'cursorX', true, 'cursorY', true) + end + elseif configType == "LibRockConfig-1.0" then + local RockConfig = Rock("LibRockConfig-1.0", false, true) + if RockConfig then + RockConfig.OpenConfigMenu(self) + end + else + -- TODO: add more possibilities + end +end + +function FuBarPlugin.OnEmbedInitialize(FuBarPlugin, self) + if not self.frame then + local name = MAJOR_VERSION .. "_" .. self:GetTitle() .. "_" .. "Frame" + local frame = _G[name] + if not frame or not _G[name .. "Text"] or not _G[name .. "Icon"] then + frame = FuBarPlugin.CreateBasicPluginFrame(self, name) + + local icon = frame:CreateTexture(name .. "Icon", "ARTWORK") + frame.icon = icon + icon:SetWidth(16) + icon:SetHeight(16) + icon:SetPoint("LEFT", frame, "LEFT") + + local text = frame:CreateFontString(name .. "Text", "ARTWORK") + frame.text = text + text:SetWidth(134) + text:SetHeight(24) + text:SetPoint("LEFT", icon, "RIGHT", 0, 1) + text:SetFontObject(GameFontNormal) + end + pluginToFrame[self] = frame + else + pluginToFrame[self] = self.frame + if not pluginToOptions[self] then + pluginToOptions[self] = {} + end + pluginToOptions[self].userDefinedFrame = true + end + + local frame = pluginToFrame[self] + frame.plugin = self + frame:SetParent(UIParent) + frame:SetPoint("RIGHT", UIParent, "LEFT", -5, 0) + frame:Hide() + + local iconPath = getPluginOption(self, 'iconPath', false) + if iconPath then + self:SetFuBarIcon(iconPath) + end + + if CheckFuBar() then + FuBar:RegisterPlugin(self) + end +end + + +local CheckShow = function(self, panelId) + if not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown()) then + self:Show(panelId) + end +end + +local schedules = {} +local f = CreateFrame("Frame") +f:SetScript("OnUpdate", function(this) + for i,v in ipairs(schedules) do + local success, ret = pcall(unpack(v)) + if not success then + geterrorhandler()(ret) + end + schedules[i] = del(v) + end + f:Hide() +end) + +local recheckPlugins +local AceConsole +function FuBarPlugin.OnEmbedEnable(FuBarPlugin, self, first) + if not getPluginOption(self, 'userDefinedFrame', false) then + local icon = pluginToFrame[self].icon + if self:IsFuBarIconShown() then + icon:Show() + else + icon:Hide() + end + end + self:CheckWidth(true) + + if not getPluginOption(self, 'hideWithoutStandby', false) or (getLazyDatabaseValue(self) and not getLazyDatabaseValue(self, 'hidden')) then + if not first then + CheckShow(self, self.panelIdTmp) + else + schedules[#schedules+1] = newList(CheckShow, self, self.panelIdTmp) + f:Show() + end + end + + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType == "Tablet-2.0" and not getPluginOption(self, 'cannotDetachTooltip', false) and getLazyDatabaseValue(self, 'detachedTooltip', 'detached') then + schedules[#schedules+1] = newList(self.DetachFuBarTooltip, self) + f:Show() + end + + if IsLoadOnDemand(self) and CheckFuBar() then + if not FuBar.db.profile.loadOnDemand then + FuBar.db.profile.loadOnDemand = {} + end + if not FuBar.db.profile.loadOnDemand[folderNames[self]] then + FuBar.db.profile.loadOnDemand[folderNames[self]] = {} + end + FuBar.db.profile.loadOnDemand[folderNames[self]].disabled = nil + end + --[[ + if CheckFuBar() and AceLibrary:HasInstance("AceConsole-2.0") then + if not recheckPlugins then + if not AceConsole then + AceConsole = AceLibrary("AceConsole-2.0") + end + recheckPlugins = function() + for k,v in pairs(AceConsole.registry) do + if type(v) == "table" and v.args and AceOO.inherits(v.handler, FuBarPlugin) and not v.handler.independentProfile then + v.args.profile = nil + end + end + end + end + FuBarPlugin:ScheduleEvent("FuBarPlugin-recheckPlugins", recheckPlugins, 0) + end + ]] +end + +function FuBarPlugin.OnEmbedDisable(FuBarPlugin, self) + self:Hide(false) + + if IsLoadOnDemand(self) and CheckFuBar() then + if not FuBar.db.profile.loadOnDemand then + FuBar.db.profile.loadOnDemand = {} + end + if not FuBar.db.profile.loadOnDemand[folderNames[self]] then + FuBar.db.profile.loadOnDemand[folderNames[self]] = {} + end + FuBar.db.profile.loadOnDemand[folderNames[self]].disabled = true + end +end + +function FuBarPlugin.OnEmbedProfileEnable(FuBarPlugin, self) + self:UpdateFuBarPlugin() + if getLazyDatabaseValue(self) then + if not getLazyDatabaseValue(self, 'detachedTooltip') then + setLazyDatabaseValue(self, {}, 'detachedTooltip') + end + local tooltipType = getPluginOption(self, 'tooltipType', "GameTooltip") + if tooltipType == "Tablet-2.0" and Tablet20 then + if Tablet20.registry[pluginToFrame[self]] then + Tablet20:UpdateDetachedData(pluginToFrame[self], getLazyDatabaseValue(self, 'detachedTooltip')) + else + RegisterTablet20(self) + end + end + if MinimapContainer:HasPlugin(self) then + MinimapContainer:ReadjustLocation(self) + end + end +end + +-- #NODOC +function FuBarPlugin.GetEmbedRockConfigOptions(FuBarPlugin, self) + return 'icon', { + type = 'boolean', + name = SHOW_FUBAR_ICON, + desc = SHOW_FUBAR_ICON_DESC, + set = "ToggleFuBarIconShown", + get = "IsFuBarIconShown", + hidden = function() + return not getPluginOption(self, 'iconPath', false) or getPluginOption(self, 'hasNoText', false) or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self) + end, + order = -13.7, + handler = self, + }, 'text', { + type = 'boolean', + name = SHOW_FUBAR_TEXT, + desc = SHOW_FUBAR_TEXT_DESC, + set = "ToggleFuBarTextShown", + get = "IsFuBarTextShown", + hidden = function() + return getPluginOption(self, 'cannotHideText', false) or not getPluginOption(self, 'iconPath', false) or getPluginOption(self, 'hasNoText') or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self) + end, + order = -13.6, + handler = self, + }, 'colorText', { + type = 'boolean', + name = SHOW_COLORED_FUBAR_TEXT, + desc = SHOW_COLORED_FUBAR_TEXT_DESC, + set = "ToggleFuBarTextColored", + get = "IsFuBarTextColored", + hidden = function() + return getPluginOption(self, 'userDefinedFrame', false) or getPluginOption(self, 'hasNoText', false) or getPluginOption(self, 'hasNoColor', false) or self:IsDisabled() or self:IsFuBarMinimapAttached() or not getLazyDatabaseValue(self) + end, + order = -13.5, + handler = self, + }, 'detachTooltip', { + type = 'boolean', + name = DETACH_FUBAR_TOOLTIP, + desc = DETACH_FUBAR_TOOLTIP_DESC, + get = "IsFuBarTooltipDetached", + set = "ToggleFuBarTooltipDetached", + hidden = function() + return not Tablet20 or getPluginOption(self, 'tooltipType', "GameTooltip") ~= "Tablet-2.0" or self:IsDisabled() + end, + order = -13.4, + handler = self, + }, 'lockTooltip', { + type = 'boolean', + name = LOCK_FUBAR_TOOLTIP, + desc = LOCK_FUBAR_TOOLTIP_DESC, + get = function() + return Tablet20:IsLocked(pluginToFrame[self]) + end, + set = function() + return Tablet20:ToggleLocked(pluginToFrame[self]) + end, + disabled = function() + return not self:IsFuBarTooltipDetached() + end, + hidden = function() + return not Tablet20 or getPluginOption(self, 'tooltipType', "GameTooltip") ~= "Tablet-2.0" or getPluginOption(self, 'cannotDetachTooltip', false) or self:IsDisabled() + end, + order = -13.3, + handler = self, + }, 'position', { + type = 'choice', + name = POSITION_ON_FUBAR, + desc = POSITION_ON_FUBAR_DESC, + choices = { + LEFT = POSITION_LEFT, + CENTER = POSITION_CENTER, + RIGHT = POSITION_RIGHT + }, + choiceSort = { + "LEFT", + "CENTER", + "RIGHT", + }, + get = function() + return self:GetPanel() and self:GetPanel():GetPluginSide(self) + end, + set = function(value) + if self:GetPanel() then + self:GetPanel():SetPluginSide(self, value) + end + end, + hidden = function() + return self:IsFuBarMinimapAttached() or self:IsDisabled() or not pluginToPanel[self] + end, + order = -13.2, + handler = self, + }, 'minimapAttach', { + type = 'boolean', + name = ATTACH_PLUGIN_TO_MINIMAP, + desc = ATTACH_PLUGIN_TO_MINIMAP_DESC, + get = "IsFuBarMinimapAttached", + set = "ToggleFuBarMinimapAttached", + hidden = function() + return (getPluginOption(self, 'cannotAttachToMinimap', false) and not self:IsFuBarMinimapAttached()) or not CheckFuBar() or self:IsDisabled() + end, + order = -13.1, + handler = self, + }, 'hide', { + type = 'boolean', + name = function() + if self:IsFuBarMinimapAttached() then + return HIDE_MINIMAP_BUTTON + else + return HIDE_FUBAR_PLUGIN + end + end, + desc = HIDE_FUBAR_PLUGIN_DESC, + get = function() + return not pluginToFrame[self]:IsShown() and (not pluginToMinimapFrame[self] or not pluginToMinimapFrame[self]:IsShown()) + end, + set = function(value) + if not value then + self:Show() + else + self:Hide() + end + end, + hidden = function() + return not getPluginOption(self, 'hideWithoutStandby', false) or self:IsDisabled() + end, + order = -13, + handler = self, + } +end + +local plugins = MinimapContainer.plugins or {} +for k in pairs(MinimapContainer) do + MinimapContainer[k] = nil +end +MinimapContainer.plugins = plugins + +local minimap_OnMouseDown, minimap_OnMouseUp +function MinimapContainer:AddPlugin(plugin) + if CheckFuBar() and FuBar:IsChangingProfile() then + return + end + if pluginToPanel[plugin] then + pluginToPanel[plugin]:RemovePlugin(plugin) + end + pluginToPanel[plugin] = self + if not pluginToMinimapFrame[plugin] then + local frame = CreateFrame("Button", pluginToFrame[plugin]:GetName() .. "MinimapButton", Minimap) + pluginToMinimapFrame[plugin] = frame + plugin.minimapFrame = 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:GetFuBarIcon() or (pluginToFrame[plugin].icon and pluginToFrame[plugin].icon:GetTexture()) or "Interface\\Icons\\INV_Misc_QuestionMark" + icon:SetTexture(path) + if path:sub(1, 16) == "Interface\\Icons\\" then + icon:SetTexCoord(0.07, 0.93, 0.07, 0.93) + 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.self = plugin + if not frame_OnEnter then + function frame_OnEnter(this) + if type(this.self.OnFuBarEnter) == "function" then + this.self:OnFuBarEnter() + end + end + end + frame:SetScript("OnEnter", frame_OnEnter) + if not frame_OnLeave then + function frame_OnLeave(this) + if type(this.self.OnFuBarLeave) == "function" then + this.self:OnFuBarLeave() + end + end + end + frame:SetScript("OnLeave", frame_OnLeave) + if not frame_OnClick then + function frame_OnClick(this, arg1) + if this.self:IsMinimapAttached() and this.dragged then return end + if type(this.self.OnFuBarClick) == "function" then + this.self:OnFuBarClick(arg1) + end + end + end + frame:SetScript("OnClick", frame_OnClick) + if not frame_OnDoubleClick then + function frame_OnDoubleClick(this, arg1) + if type(this.self.OnFuBarDoubleClick) == "function" then + this.self:OnFuBarDoubleClick(arg1) + end + end + end + frame:SetScript("OnDoubleClick", frame_OnDoubleClick) + if not frame_OnReceiveDrag then + function frame_OnReceiveDrag(this) + if this.self:IsMinimapAttached() and this.dragged then return end + if type(this.self.OnFuBarReceiveDrag) == "function" then + this.self:OnFuBarReceiveDrag() + end + end + end + frame:SetScript("OnReceiveDrag", frame_OnReceiveDrag) + if not minimap_OnMouseDown then + function minimap_OnMouseDown(this, arg1) + this.dragged = false + if arg1 == "LeftButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then + HideDropDownMenu(1) + if type(this.self.OnFuBarMouseDown) == "function" then + this.self:OnFuBarMouseDown(arg1) + end + elseif arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then + this.self:OpenMenu(this) + else + HideDropDownMenu(1) + if type(this.self.OnFuBarMouseDown) == "function" then + this.self:OnFuBarMouseDown(arg1) + end + end + if this.self.OnFuBarClick or this.self.OnFuBarMouseDown or this.self.OnFuBarMouseUp or this.self.OnFuBarDoubleClick then + if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then + this.self.minimapIcon:SetTexCoord(0.14, 0.86, 0.14, 0.86) + else + this.self.minimapIcon:SetTexCoord(0.1, 0.9, 0.1, 0.9) + end + end + end + end + frame:SetScript("OnMouseDown", minimap_OnMouseDown) + if not minimap_OnMouseUp then + function minimap_OnMouseUp(this, arg1) + if not this.dragged and type(this.self.OnFuBarMouseUp) == "function" then + this.self:OnFuBarMouseUp(arg1) + end + if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then + this.self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95) + else + this.self.minimapIcon:SetTexCoord(0, 1, 0, 1) + end + end + end + frame:SetScript("OnMouseUp", minimap_OnMouseUp) + frame:RegisterForDrag("LeftButton") + frame:SetScript("OnDragStart", self.OnDragStart) + frame:SetScript("OnDragStop", self.OnDragStop) + + if getPluginOption(plugin, 'tooltipType', "GameTooltip") == "Tablet-2.0" then + -- Note that we have to do this after :SetScript("OnEnter"), etc, + -- so that Tablet-2.0 can override it properly. + RegisterTablet20(plugin) + Tablet20:Register(frame, pluginToFrame[plugin]) + end + end + pluginToFrame[plugin]:Hide() + pluginToMinimapFrame[plugin]: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(pluginToPanel[plugin] == self, "Plugin has improper panel field") + plugin:SetPanel(nil) + table.remove(t, index) + return true +end + +function MinimapContainer:ReadjustLocation(plugin) + local frame = pluginToMinimapFrame[plugin] + 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 getPluginOption(plugin, 'defaultMinimapPosition', nil) or math.random(1, 360) + else + position = plugin.minimapPosition or getPluginOption(plugin, 'defaultMinimapPosition', nil) or math.random(1, 360) + end + local angle = math.rad(position or 0) + local x,y + local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND" + local cos = math.cos(angle) + local sin = math.sin(angle) + + local round = true + if minimapShape == "ROUND" then + -- do nothing + elseif minimapShape == "SQUARE" then + round = false + elseif minimapShape == "CORNER-TOPRIGHT" then + if cos < 0 or sin < 0 then + round = false + end + elseif minimapShape == "CORNER-TOPLEFT" then + if cos > 0 or sin < 0 then + round = false + end + elseif minimapShape == "CORNER-BOTTOMRIGHT" then + if cos < 0 or sin > 0 then + round = false + end + elseif minimapShape == "CORNER-BOTTOMLEFT" then + if cos > 0 or sin > 0 then + round = false + end + elseif minimapShape == "SIDE-LEFT" then + if cos > 0 then + round = false + end + elseif minimapShape == "SIDE-RIGHT" then + if cos < 0 then + round = false + end + elseif minimapShape == "SIDE-TOP" then + if sin < 0 then + round = false + end + elseif minimapShape == "SIDE-BOTTOM" then + if sin > 0 then + round = false + end + elseif minimapShape == "TRICORNER-TOPRIGHT" then + if cos < 0 and sin < 0 then + round = false + end + elseif minimapShape == "TRICORNER-TOPLEFT" then + if cos > 0 and sin < 0 then + round = false + end + elseif minimapShape == "TRICORNER-BOTTOMRIGHT" then + if cos < 0 and sin > 0 then + round = false + end + elseif minimapShape == "TRICORNER-BOTTOMLEFT" then + if cos > 0 and sin > 0 then + round = false + end + end + + if round then + x = cos * 80 + y = sin * 80 + else + x = 80 * 2^0.5 * cos + y = 80 * 2^0.5 * sin + if x < -80 then + x = -80 + elseif x > 80 then + x = 80 + end + if y < -80 then + y = -80 + elseif y > 80 then + y = 80 + end + end + frame:SetPoint("CENTER", Minimap, "CENTER", x, y) + end +end + +function MinimapContainer:GetPlugin(index) + return self.plugins[index] +end + +function MinimapContainer:GetNumPlugins() + return #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) + this.dragged = true + this:LockHighlight() + this:SetScript("OnUpdate", MinimapContainer.OnUpdate) + if this.self.minimapIcon:GetTexture():sub(1, 16) == "Interface\\Icons\\" then + this.self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95) + else + this.self.minimapIcon:SetTexCoord(0, 1, 0, 1) + end +end + +function MinimapContainer.OnDragStop(this) + this:SetScript("OnUpdate", nil) + this:UnlockHighlight() +end + +function MinimapContainer.OnUpdate(this, elapsed) + 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.self.db then + this.self.db.profile.minimapPosition = position + this.self.db.profile.minimapPositionX = nil + this.self.db.profile.minimapPositionY = nil + this.self.db.profile.minimapPositionWild = nil + else + this.self.minimapPosition = position + this.self.minimapPositionX = nil + this.self.minimapPositionY = nil + this.self.minimapPositionWild = nil + end + else + local px, py = GetCursorPosition() + local scale = UIParent:GetEffectiveScale() + px, py = px / scale, py / scale + if this.self.db then + this.self.db.profile.minimapPositionX = px + this.self.db.profile.minimapPositionY = py + this.self.db.profile.minimapPosition = nil + this.self.db.profile.minimapPositionWild = true + else + this.self.minimapPositionX = px + this.self.minimapPositionY = py + this.self.minimapPosition = nil + this.self.minimapPositionWild = true + end + end + MinimapContainer:ReadjustLocation(this.self) +end + +FuBarPlugin:SetExportedMethods( + "SetFuBarOption", + "GetTitle", + "GetName", + "GetCategory", + "SetFontSize", + "GetFrame", + "Show", + "Hide", + "GetPanel", + "IsFuBarTextColored", + "ToggleFuBarTextColored", + "IsFuBarMinimapAttached", + "ToggleFuBarMinimapAttached", + "UpdateFuBarPlugin", + "UpdateFuBarText", + "UpdateFuBarTooltip", + "SetFuBarIcon", + "GetFuBarIcon", + "CheckWidth", + "SetFuBarText", + "GetFuBarText", + "IsFuBarIconShown", + "ToggleFuBarIconShown", + "ShowFuBarIcon", + "HideFuBarIcon", + "IsFuBarTextShown", + "ToggleFuBarTextShown", + "ShowFuBarText", + "HideFuBarText", + "IsFuBarTooltipDetached", + "ToggleFuBarTooltipDetached", + "DetachFuBarTooltip", + "ReattachFuBarTooltip", + "GetDefaultPosition", + "SetPanel", + "IsDisabled", + "CreateBasicPluginFrame", + "CreatePluginChildFrame", + "OpenMenu" +) + +Rock:FinalizeLibrary(MAJOR_VERSION)