--[[
Whom is doing what with this library
$Author: myrroddin $
$URL: file:///media/cf-repositories/svn/wow/libaboutpanel-2-0/mainline/trunk/LibAboutPanel-2.0/LibAboutPanel-2.0.lua $
$Id: LibAboutPanel-2.0.lua 2 2016-09-11 06:20:19Z myrroddin $
$Header: file:///media/cf-repositories/svn/wow/libaboutpanel-2-0/mainline/trunk/LibAboutPanel-2.0/LibAboutPanel-2.0.lua 2 2016-09-11 06:20:19Z myrroddin $
@class file
@name LibAboutPanel-2.0.lua
@release $Id: LibAboutPanel-2.0.lua 2 2016-09-11 06:20:19Z myrroddin $
]]--
--- **LibAboutPanel-2.0** either creates an "About" panel in your AddOn's
-- Interface/AddOns frame or within said AddOn's options table
-- The word //About// will be localized, among other things, automatically
-- API includes:
-- * **CreateAboutPanel** which works like Ackis' LibAboutPanel
-- * **AboutOptionsTable** which embeds the panel within AceConfig-3.0 options table
--
-- @usage
-- function MyAddOn:OnInitialize()
-- local options = {
-- name = "MyAddOn",
-- type = "group",
-- args = {
-- enableAddOn = {
-- order = 10,
-- name = ENABLE, -- use Blizzard's global string
-- type = "toggle",
-- get = function() return self.db.profile.enableAddOn end,
-- set = function(info, value)
-- self.db.profile.enableAddOn = value
-- if value then
-- self:OnEnable()
-- else
-- self:OnDisable()
-- end
-- end
-- }
-- }
-- }
-- -- support for LibAboutPanel-2.0
-- options.args.aboutTab = self:AboutOptionsTable("MyAddOn")
-- options.args.aboutTab.order = -1 -- -1 means "put it last"
-- -- Register your options with AceConfigRegistry
-- LibStub("AceConfig-3.0"):RegisterOptionsTable("MyAddOn", options)
-- end
local MAJOR, MINOR = "LibAboutPanel-2.0", tonumber("@project-revision@") or 1000
assert(LibStub, MAJOR .. " requires LibStub")
local AboutPanel = LibStub:NewLibrary(MAJOR, MINOR)
if not AboutPanel then return end -- no upgrade necessary
AboutPanel.embeds = AboutPanel.embeds or {} -- table containing objects AboutPanel is embedded in.
AboutPanel.aboutTable = AboutPanel.aboutTable or {} -- tables for
AboutPanel.aboutFrame = AboutPanel.aboutFrame or {}
-- Lua APIs
local setmetatable, tostring, rawset, pairs = setmetatable, tostring, rawset, pairs
-- WoW APIs
local GetLocale, GetAddOnMetadata, CreateFrame = GetLocale, GetAddOnMetadata, CreateFrame
-- localization ---------------------------------
local L = setmetatable({}, {
__index = function(tab, key)
local value = tostring(key)
rawset(tab, key, value)
return value
end
})
local locale = GetLocale()
if locale == "koKR" then
L["About"] = "대하여"
L["Click and press Ctrl-C to copy"] = "클릭 후 Ctrl-C 복사"
L["Author"] = "저작자"
L["Category"] = "분류"
L["Credits"] = "공로자"
L["Date"] = "날짜"
L["Email"] = "전자 우편"
L["License"] = "라이센스"
L["Version"] = "버전"
L["Website"] = "웹 사이트"
-- L["All Rights Reserved"] = ""
-- L["Localizations"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
elseif locale == "frFR" then
L["About"] = "à propos de"
L["Category"] = "Catégorie"
L["Author"] = "Auteur"
L["Date"] = "Date"
L["Email"] = "E-mail"
L["Version"] = "Version"
L["Website"] = "Site web"
-- L["All Rights Reserved"] = ""
-- L["Click and press Ctrl-C to copy"] = ""
-- L["Credits"] = ""
-- L["License"] = ""
-- L["Localizations"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
elseif locale == "deDE" then
L["About"] = "Über"
L["Author"] = "Autor"
L["Category"] = "Kategorie"
L["Click and press Ctrl-C to copy"] = "Klicken und Strg-C drücken zum kopieren."
L["Credits"] = "Ehren"
L["Date"] = "Datum"
L["Email"] = "E-Mail"
L["License"] = "Lizenz"
L["Localizations"] = "Sprachen"
L["Version"] = "Version"
L["Website"] = "Webseite"
-- L["All Rights Reserved"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
elseif locale == "ruRU" then
L["About"] = "Об аддоне"
L["All Rights Reserved"] = "Все права сохранены"
L["Author"] = "Автор"
L["Category"] = "Категория"
L["Click and press Ctrl-C to copy"] = "Щелкните и нажмите Ctrl-C для копирования"
L["Date"] = "Дата"
L["Email"] = "Почта"
L["License"] = "Лицензия"
L["Localizations"] = "Локализация"
L["on the %s realm"] = "с сервера %s"
L["Repository"] = "Репозиторий"
L["Version"] = "Версия"
L["Website"] = "Сайт"
--L["Credits"] = ""
elseif locale == "zhTW" then
L["About"] = "日期"
L["Category"] = "類別"
L["Click and press Ctrl-C to copy"] = "左鍵點擊並按下 Ctrl-C 以複製字串"
L["Date"] = "日期"
L["Author"] = "作者"
L["Credits"] = "特別感謝"
L["Email"] = "電子郵件"
L["License"] = "版權"
L["Version"] = "版本"
L["Website"] = "網站"
-- L["All Rights Reserved"] = ""
-- L["Localizations"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
elseif locale == "zhCN" then
L["About"] = "关于"
L["Category"] = "分类"
L["Click and press Ctrl-C to copy"] = "点击并 Ctrl-C 复制"
L["Date"] = "日期"
L["Author"] = "作者"
L["Email"] = "电子邮件"
L["Version"] = "版本"
L["Website"] = "网站"
-- L["All Rights Reserved"] = ""
-- L["Credits"] = ""
-- L["License"] = ""
-- L["Localizations"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
elseif locale == "itIT" then
-- L["About"] = ""
-- L["All Rights Reserved"] = ""
-- L["Author"] = ""
-- L["Click and press Ctrl-C to copy"] = ""
-- L["Credits"] = ""
-- L["Email"] = ""
-- L["License"] = ""
-- L["Localizations"] = ""
-- L["Repository"] = ""
-- L["on the %s realm"] = ""
-- L["Version"] = ""
-- L["Website"] = ""
elseif locale == "ptBR" then
-- L["About"] = ""
-- L["All Rights Reserved"] = ""
-- L["Author"] = ""
-- L["Click and press Ctrl-C to copy"] = ""
-- L["Credits"] = ""
-- L["Email"] = ""
-- L["License"] = ""
-- L["Localizations"] = ""
-- L["Repository"] = ""
-- L["on the %s realm"] = ""
-- L["Version"] = ""
-- L["Website"] = ""
elseif locale == "esES" or locale == "esMX" then
L["About"] = "Sobre"
L["Author"] = "Autor"
L["Category"] = "Categoría"
L["Click and press Ctrl-C to copy"] = "Clic y pulse Ctrl-C para copiar."
L["Credits"] = "Créditos"
L["Date"] = "Fecha"
L["Email"] = "Email"
L["License"] = "Licencia"
L["Localizations"] = "Idiomas"
L["Version"] = "Versión"
L["Website"] = "Sitio web"
-- L["All Rights Reserved"] = ""
-- L["on the %s realm"] = ""
-- L["Repository"] = ""
end
-- handy fuction to create Title Case -----------
local function TitleCase(str)
str = str:gsub("(%a)(%a+)", function(a, b) return a:upper()..b:lower() end)
return str
end
local function GetTitle(addon)
local title = "Title"
if locale ~= "enUS" then
title = title .. "-" .. locale
end
return GetAddOnMetadata(addon, title) or GetAddOnMetadata(addon, "Title")
end
local function GetNotes(addon)
local notes = "Notes"
if locale ~= "enUS" then
notes = notes .. "-" .. locale
end
return GetAddOnMetadata(addon, notes) or GetAddOnMetadata(addon, "Notes")
end
local function GetAddOnDate(addon)
local date = GetAddOnMetadata(addon, "X-Date") or GetAddOnMetadata(addon, "X-ReleaseDate")
if not date then return end
date = date:gsub("%$Date: (.-) %$", "%1")
date = date:gsub("%$LastChangedDate: (.-) %$", "%1")
return date
end
local function GetAuthor(addon)
local author = GetAddOnMetadata(addon, "Author")
if not author then return end
author = TitleCase(author)
local server = GetAddOnMetadata(addon, "X-Author-Server")
local guild = GetAddOnMetadata(addon, "X-Author-Guild")
local faction = GetAddOnMetadata(addon, "X-Author-Faction")
if server then
server = TitleCase(server)
author = author .. " " .. L["on the %s realm"]:format(server) .. "."
end
if guild then
author = author .. " " .. "<" .. guild .. ">"
end
if faction then
faction = TitleCase(faction)
faction = faction:gsub("Alliance", FACTION_ALLIANCE)
faction = faction:gsub("Horde", FACTION_HORDE)
author = author .. " " .. "(" .. faction .. ")"
end
return author
end
local function GetVersion(addon)
local version = GetAddOnMetadata(addon, "Version")
if not version then return end
version = version:gsub("%.?%$Revision: (%d+) %$", " -rev.".."%1")
version = version:gsub("%.?%$Rev: (%d+) %$", " -rev.".."%1")
version = version:gsub("%.?%$LastChangedRevision: (%d+) %$", " -rev.".."%1")
-- replace repository keywords
version = version:gsub("r2", L["Repository"]) -- Curse
version = version:gsub("wowi:revision", L["Repository"]) -- WoWInterface
local revision = GetAddOnMetadata(addon, "X-Project-Revision")
version = revision and version.." -rev."..revision or version
return version
end
local function GetCategory(addon)
return GetAddOnMetadata(addon, "X-Category")
end
local function GetLicense(addon)
local license = GetAddOnMetadata(addon, "X-License")
if not license then return end
license = license:gsub("[cC]opyright", "©")
license = license:gsub("%([cC]%)", "©")
license = license:gsub("[aA]ll [rR]ights [rR]eserved", L["All Rights Reserved"])
return license
end
local function GetLocalizations(addon)
return GetAddOnMetadata(addon, "X-Localizations")
end
local function GetCredits(addon)
return GetAddOnMetadata(addon, "X-Credits")
end
local function GetWebsite(addon)
local websites = GetAddOnMetadata(addon, "X-Website")
if not websites then return end
return "|cff77ccff"..websites:gsub("https?://", "")
end
local function GetEmail(addon)
local email = GetAddOnMetadata(addon, "X-Email") or GetAddOnMetadata(addon, "Email") or GetAddOnMetadata(addon, "eMail")
if not email then return end
return "|cff77ccff"..GetAddOnMetadata(addon, "X-Email")
end
-- LibAboutPanel stuff --------------------------
local editbox = CreateFrame("EditBox", nil, nil, "InputBoxTemplate")
editbox:Hide()
editbox:SetFontObject("GameFontHighlightSmall")
AboutPanel.editbox = editbox
editbox:SetScript("OnEscapePressed", editbox.Hide)
editbox:SetScript("OnEnterPressed", editbox.Hide)
editbox:SetScript("OnEditFocusLost", editbox.Hide)
editbox:SetScript("OnEditFocusGained", editbox.HighlightText)
editbox:SetScript("OnTextChanged", function(self)
self:SetText(self:GetParent().value)
self:HighlightText()
end)
local function OpenEditbox(self, ...)
editbox:SetParent(self)
editbox:SetAllPoints(self)
editbox:SetText(self.value)
editbox:Show()
end
local function HideTooltip()
GameTooltip:Hide()
end
local function ShowTooltip(self)
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
GameTooltip:SetText(L["Click and press Ctrl-C to copy"])
end
--- Create a new About panel
-- @name //addon//:CreateAboutPanel
-- @paramsig AddOn[, parent]
-- @param AddOn name of which you are attaching the panel. String
-- @param parent AddOn name in Interface Options. String or nil
-- If parent is provided, panel will be under [+]
-- otherwise the panel will be a normal AddOn category
-- @return frame To do as you wish
-- @usage local aboutFrame = MyAddOn:CreateAboutPanel("MyAddOn", "MyAddOn")
-- -- OR
-- MyAddOn:CreateAboutPanel("MyAddOn", "MyAddOn")
function AboutPanel:CreateAboutPanel(addon, parent)
addon = addon:gsub(" ", "") -- Remove spaces from AddOn because GetMetadata doesn't like those
local addon = parent or addon
local frame = self.aboutFrame[addon]
if not frame then
frame = CreateFrame("Frame", addon.."AboutPanel", UIParent)
local title = GetTitle(addon)
local title_str = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
title_str:SetPoint("TOPLEFT", 16, -16)
title_str:SetText((parent and title or addon) .. " - " .. L["About"])
local notes = GetNotes(addon)
local notes_str
if notes then
notes_str = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
notes_str:SetHeight(32)
notes_str:SetPoint("TOPLEFT", title_str, "BOTTOMLEFT", 0, -8)
notes_str:SetPoint("RIGHT", frame, -32, 0)
notes_str:SetNonSpaceWrap(true)
notes_str:SetJustifyH("LEFT")
notes_str:SetJustifyV("TOP")
notes_str:SetText(GetNotes(addon))
end
local i, title, detail = 0, {}, {}
local function SetAboutInfo(field, text, editbox)
i = i + 1
title[i] = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
if i == 1 then
title[i]:SetPoint("TOPLEFT", notes and notes_str or title_str, "BOTTOMLEFT", -2, -12)
else
title[i]:SetPoint("TOPLEFT", title[i-1], "BOTTOMLEFT", 0, -10)
end
title[i]:SetWidth(80)
title[i]:SetJustifyH("RIGHT")
title[i]:SetJustifyV("TOP")
title[i]:SetText(field)
detail[i] = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
detail[i]:SetPoint("TOPLEFT", title[i], "TOPRIGHT", 4, 0)
detail[i]:SetPoint("RIGHT", frame, -16, 0)
detail[i]:SetJustifyH("LEFT")
detail[i]:SetJustifyV("TOP")
detail[i]:SetText(text)
if editbox then
local button = CreateFrame("Button", nil, frame)
button:SetAllPoints(detail[i])
button.value = text
button:SetScript("OnClick", OpenEditbox)
button:SetScript("OnEnter", ShowTooltip)
button:SetScript("OnLeave", HideTooltip)
end
end
local date = GetAddOnDate(addon)
if date then SetAboutInfo(L["Date"], date) end
local version = GetVersion(addon)
if version then SetAboutInfo(L["Version"], version) end
local author = GetAuthor(addon)
if author then SetAboutInfo(L["Author"], author) end
local category = GetCategory(addon)
if category then SetAboutInfo(L["Category"], category) end
local license = GetLicense(addon)
if license then SetAboutInfo(L["License"], license) end
local credits = GetCredits(addon)
if credits then SetAboutInfo(L["Credits"], credits) end
local email = GetEmail(addon)
if email then SetAboutInfo(L["Email"], email, true) end
local website = GetWebsite(addon)
if website then SetAboutInfo(L["Website"], website, true) end
local localizations = GetLocalizations(addon)
if localizations then SetAboutInfo(L["Localizations"], localizations) end
frame.name = not parent and addon or L["About"]
frame.parent = parent
InterfaceOptions_AddCategory(frame)
self.aboutFrame[addon] = frame
end
return frame
end
--- Creates a table of an AddOn's ToC fields
-- see [url]http://www.wowace.com/addons/ace3/pages/api/ace-config-3-0/[/url]
-- @name //addon//:AboutOptionsTable
-- @param AddOn name string whose ToC you want parsed
-- @return aboutTable suitable for use with AceConfig-3.0
-- @usage -- assuming options is your top-level table
-- local options = {} -- put your regular stuff here
-- options.args.aboutTable = MyAddOn:AboutOptionsTable("MyAddOn")
-- options.args.aboutTable.order = -1 -- use any number in the hierarchy. -1 means "put it last"
-- LibStub("AceConfig-3.0"):RegisterOptionsTable("MyAddOn", options)
function AboutPanel:AboutOptionsTable(addon)
assert(LibStub("AceConfig-3.0"), "LibAboutPanel-2.0: API 'AboutOptionsTable' requires AceConfig-3.0", 2)
addon = addon:gsub(" ", "") -- Remove spaces from AddOn because GetMetadata doesn't like those
local Table = self.aboutTable[addon]
if not Table then
Table = {
name = L["About"],
type = "group",
args = {
title = {
order = 1,
name = "|cffe6cc80" .. GetTitle(addon) .. "|r",
type = "description",
fontSize = "large",
},
},
}
local notes = GetNotes(addon)
if notes then
Table.args.blank = {
order = 2,
name = "",
type = "description",
}
Table.args.notes = {
order = 3,
name = notes,
type = "description",
fontSize = "medium",
}
end
Table.args.blank2 = {
order = 4,
name = "\n",
type = "description",
}
local date = GetAddOnDate(addon)
if date then
Table.args.date = {
order = 5,
name = "|cffe6cc80" .. L["Date"] .. ": |r" .. date,
type = "description",
}
end
local version = GetVersion(addon)
if version then
Table.args.version = {
order = 6,
name = "|cffe6cc80" .. L["Version"] .. ": |r" .. version,
type = "description",
}
end
local author = GetAuthor(addon)
if author then
Table.args.author = {
order = 7,
name = "|cffe6cc80" .. L["Author"] .. ": |r" .. author,
type = "description",
}
end
local category = GetCategory(addon)
if category then
Table.args.category = {
order = 8,
name = "|cffe6cc80" .. L["Category"] .. ": |r" .. category,
type = "description",
}
end
local license = GetLicense(addon)
if license then
Table.args.license = {
order = 9,
name = "|cffe6cc80" .. L["License"] .. ": |r" .. license,
type = "description",
}
end
local credits = GetCredits(addon)
if credits then
Table.args.credits = {
order = 10,
name = "|cffe6cc80" .. L["Credits"] .. ": |r" .. credits,
type = "description",
}
end
local email = GetEmail(addon)
if email then
Table.args.email = {
order = 11,
name = "|cffe6cc80" .. L["Email"] .. ": |r",
desc = L["Click and press Ctrl-C to copy"],
type = "input",
width = "full",
get = function() return email end,
}
end
local website = GetWebsite(addon)
if website then
Table.args.website = {
order = 12,
name = "|cffe6cc80" .. L["Website"] .. ": |r",
desc = L["Click and press Ctrl-C to copy"],
type = "input",
width = "full",
get = function() return website end,
}
end
local localizations = GetLocalizations(addon)
if localizations then
Table.args.localizations = {
order = 13,
name = "|cffe6cc80" .. L["Localizations"] .. ": |r" .. localizations,
type = "description",
}
end
self.aboutTable[addon] = Table
end
return Table
end
-- ---------------------------------------------------------------------
-- Embed handling
local mixins = {
"CreateAboutPanel",
"AboutOptionsTable"
}
-- AboutPanel AceConsole into the target object making the functions from the mixins list available on target:..
-- So you can call LibStub("LibAboutPanel-2.0"):Embed(myAddOn)
-- @param target AddOn table in which to embed
-- @usage
-- local addonname, AddOn = ...
-- LibStub("LibAboutPanel-2.0"):Embed(AddOn)
-- -- **OR**, if using Ace3
-- -- you do not explicitly call :Embed
-- local MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "LibAboutPanel-2.0")
function AboutPanel:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
--- Upgrade our old embeded
for addon in pairs(AboutPanel.embeds) do
AboutPanel:Embed(addon)
end