2949 lines
85 KiB
Lua
2949 lines
85 KiB
Lua
--[[
|
|
Name: Tablet-2.0
|
|
Revision: $Rev: 23368 $
|
|
Author(s): ckknight (ckknight@gmail.com)
|
|
Website: http://ckknight.wowinterface.com/
|
|
Documentation: http://www.wowace.com/index.php/Tablet-2.0
|
|
SVN: http://svn.wowace.com/wowace/trunk/TabletLib/Tablet-2.0
|
|
Description: A library to provide an efficient, featureful tooltip-style display.
|
|
Dependencies: AceLibrary, (optional) Dewdrop-2.0
|
|
License: LGPL v2.1
|
|
]]
|
|
|
|
local MAJOR_VERSION = "Tablet-2.0"
|
|
local MINOR_VERSION = "$Revision: 23368 $"
|
|
|
|
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
|
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
|
|
|
local DEBUG = false
|
|
|
|
local SCROLL_UP = "Scroll up"
|
|
local SCROLL_DOWN = "Scroll down"
|
|
local HINT = "Hint"
|
|
local DETACH = "Detach"
|
|
local DETACH_DESC = "Detach the tablet from its source."
|
|
local SIZE = "Size"
|
|
local SIZE_DESC = "Scale the tablet."
|
|
local CLOSE_MENU = "Close menu"
|
|
local CLOSE_MENU_DESC = "Close the menu."
|
|
local COLOR = "Background color"
|
|
local COLOR_DESC = "Set the background color."
|
|
local LOCK = "Lock"
|
|
local LOCK_DESC = "Lock the tablet in its current position. Alt+Right-click for menu or Alt+drag to drag it when locked."
|
|
|
|
if GetLocale() == "deDE" then
|
|
SCROLL_UP = "Hochscrollen"
|
|
SCROLL_DOWN = "Runterscrollen"
|
|
HINT = "Hinweis"
|
|
DETACH = "L\195\182sen"
|
|
DETACH_DESC = "L\195\182st den Tooltip aus seiner Verankerung."
|
|
SIZE = "Gr\195\182\195\159e"
|
|
SIZE_DESC = "Gr\195\182\195\159e des Tooltips \195\164ndern."
|
|
CLOSE_MENU = "Menu schlie\195\159en"
|
|
CLOSE_MENU_DESC = "Schlie\195\159t das Menu."
|
|
COLOR = "Hintergrundfarbe"
|
|
COLOR_DESC = "Hintergrundfarbe setzen."
|
|
LOCK = "Sperren"
|
|
LOCK_DESC = "Sperrt die aktuelle Position vom Tooltip. Alt+Rechts-klick f\195\188rs Men\195\188 oder Alt+Verschieben f\195\188rs verschieben wenn es gesperrt ist."
|
|
elseif GetLocale() == "koKR" then
|
|
SCROLL_UP = "위로 스크롤"
|
|
SCROLL_DOWN = "아래로 스크롤"
|
|
HINT = "힌트"
|
|
DETACH = "분리"
|
|
DETACH_DESC = "테이블을 분리합니다."
|
|
SIZE = "크기"
|
|
SIZE_DESC = "테이블의 크기입니다."
|
|
CLOSE_MENU = "메뉴 닫기"
|
|
CLOSE_MENU_DESC = "메뉴를 닫습니다."
|
|
COLOR = "배경 색상"
|
|
COLOR_DESC = "배경 색상을 설정합니다."
|
|
LOCK = "고정"
|
|
LOCK_DESC = "현재 위치에 테이블을 고정합니다. 알트+우클릭 : 메뉴열기, 알트+드래그 : 고정된것을 드래그합니다."
|
|
elseif GetLocale() == "zhCN" then
|
|
SCROLL_UP = "向上翻转"
|
|
SCROLL_DOWN = "向上翻转"
|
|
HINT = "提示"
|
|
DETACH = "分离"
|
|
DETACH_DESC = "分离菜单为独立提示."
|
|
SIZE = "尺寸"
|
|
SIZE_DESC = "缩放菜单显示尺寸."
|
|
CLOSE_MENU = "关闭菜单"
|
|
CLOSE_MENU_DESC = "关闭菜单"
|
|
COLOR = "背景颜色"
|
|
COLOR_DESC = "设置菜单背景颜色."
|
|
LOCK = "锁定"
|
|
LOCK_DESC = "锁定菜单当前位置. alt+右键 将显示选项, alt+拖动 可以移动已锁定的菜单."
|
|
elseif GetLocale() == "zhTW" then
|
|
SCROLL_UP = "向上翻轉"
|
|
SCROLL_DOWN = "向上翻轉"
|
|
HINT = "提示"
|
|
DETACH = "分離"
|
|
DETACH_DESC = "分離選單為獨立提示。"
|
|
SIZE = "尺寸"
|
|
SIZE_DESC = "縮放選單顯示尺寸。"
|
|
CLOSE_MENU = "關閉選單"
|
|
CLOSE_MENU_DESC = "關閉選單"
|
|
COLOR = "背景顏色"
|
|
COLOR_DESC = "設置選單背景顏色。"
|
|
LOCK = "鎖定"
|
|
LOCK_DESC = "鎖定選單目前位置. Alt+右鍵 將顯示選項,Alt+拖動 可以移動已鎖定的選單。"
|
|
elseif GetLocale() == "frFR" then
|
|
SCROLL_UP = "Parcourir vers le haut"
|
|
SCROLL_DOWN = "Parcourir vers le bas"
|
|
HINT = "Astuce"
|
|
DETACH = "D\195\169tacher"
|
|
DETACH_DESC = "Permet de d\195\169tacher le tableau de sa source."
|
|
SIZE = "Taille"
|
|
SIZE_DESC = "Permet de changer l'\195\169chelle du tableau."
|
|
CLOSE_MENU = "Fermer le menu"
|
|
CLOSE_MENU_DESC = "Ferme ce menu."
|
|
COLOR = "Couleur du fond"
|
|
COLOR_DESC = "Permet de d\195\169finir la couleur du fond."
|
|
LOCK = "Bloquer"
|
|
LOCK_DESC = "Bloque le tableau \195\160 sa position actuelle. Alt+clic-droit pour le menu ou Alt+glisser pour le d\195\169placer quand il est bloqu\195\169."
|
|
elseif GetLocale() == "esES" then
|
|
SCROLL_UP = "Desplazar hacia arriba"
|
|
SCROLL_DOWN = "Desplazar hacia abajo"
|
|
HINT = "Consejo"
|
|
DETACH = "Separar"
|
|
DETACH_DESC = "Separa el tooltip de su fuente."
|
|
SIZE = "Tama\195\177o"
|
|
SIZE_DESC = "Escala el tooltip"
|
|
CLOSE_MENU = "Cerrar men\195\186"
|
|
CLOSE_MENU_DESC = "Cierra el men\195\186"
|
|
COLOR = "Color de fondo"
|
|
COLOR_DESC = "Establece el color de fondo"
|
|
LOCK = "Bloquear"
|
|
LOCK_DESC = "Bloquea el tooltip en su posici\195\179n actual. Clic+Alt para el men\195\186 y arrastra+Alt para arrastrarlo cuando est\195\161 bloqueado"
|
|
end
|
|
|
|
local start = GetTime()
|
|
local wrap
|
|
local GetProfileInfo
|
|
if DEBUG then
|
|
local tree = {}
|
|
local treeMemories = {}
|
|
local treeTimes = {}
|
|
local memories = {}
|
|
local times = {}
|
|
function wrap(value, name)
|
|
if type(value) == "function" then
|
|
local oldFunction = value
|
|
memories[name] = 0
|
|
times[name] = 0
|
|
return function(self, ...)
|
|
local pos = #tree
|
|
table.insert(tree, name)
|
|
table.insert(treeMemories, 0)
|
|
table.insert(treeTimes, 0)
|
|
local t, mem = GetTime(), gcinfo()
|
|
local r1, r2, r3, r4, r5, r6, r7, r8 = oldFunction(self, ...)
|
|
mem, t = gcinfo() - mem, GetTime() - t
|
|
if pos > 0 then
|
|
treeMemories[pos] = treeMemories[pos] + mem
|
|
treeTimes[pos] = treeTimes[pos] + t
|
|
end
|
|
local otherMem = table.remove(treeMemories)
|
|
if mem - otherMem > 0 then
|
|
memories[name] = memories[name] + mem - otherMem
|
|
end
|
|
times[name] = times[name] + t - table.remove(treeTimes)
|
|
table.remove(tree)
|
|
return r1, r2, r3, r4, r5, r6, r7, r8
|
|
end
|
|
end
|
|
end
|
|
|
|
function GetProfileInfo()
|
|
return GetTime() - start, times, memories
|
|
end
|
|
else
|
|
function wrap(value)
|
|
return value
|
|
end
|
|
end
|
|
|
|
local MIN_TOOLTIP_SIZE = 200
|
|
local TESTSTRING_EXTRA_WIDTH = 8
|
|
local Tablet = {}
|
|
local Dewdrop = nil
|
|
local CleanCategoryPool
|
|
local pool = {}
|
|
|
|
local function del(t)
|
|
if t then
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
setmetatable(t, nil)
|
|
pool[t] = true
|
|
end
|
|
end
|
|
|
|
local new
|
|
|
|
local function copy(parent)
|
|
local t = next(pool) or {}
|
|
pool[t] = nil
|
|
if parent then
|
|
for k,v in pairs(parent) do
|
|
t[k] = v
|
|
end
|
|
setmetatable(t, getmetatable(parent))
|
|
end
|
|
return t
|
|
end
|
|
|
|
function new(...)
|
|
local t = next(pool) or {}
|
|
pool[t] = nil
|
|
|
|
for i = 1, select('#', ...), 2 do
|
|
local k = select(i, ...)
|
|
if k then
|
|
t[k] = select(i+1, ...)
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
local tmp
|
|
tmp = setmetatable({}, {__index = function(self, key)
|
|
local t = {}
|
|
tmp[key] = function(...)
|
|
for k in pairs(t) do
|
|
t[k] = nil
|
|
end
|
|
for i = 1, select('#', ...), 2 do
|
|
local k = select(i, ...)
|
|
if k then
|
|
t[k] = select(i+1, ...)
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
return tmp[key]
|
|
end})
|
|
|
|
local headerSize, normalSize
|
|
if GameTooltipHeaderText then
|
|
_,headerSize = GameTooltipHeaderText:GetFont()
|
|
else
|
|
headerSize = 14
|
|
end
|
|
if GameTooltipText then
|
|
_,normalSize = GameTooltipText:GetFont()
|
|
else
|
|
normalSize = 12
|
|
end
|
|
local tooltip
|
|
local testString-- = CreateFrame("Frame", UIParent):CreateFontString(nil, "OVERLAY")
|
|
local TabletData = {}
|
|
local Category = {}
|
|
local Line = {}
|
|
local function getTestWidth(font, size, text)
|
|
testString:SetWidth(0)
|
|
testString:SetFontObject(font)
|
|
local a,_,b = testString:GetFont()
|
|
testString:SetFont(a, size, b)
|
|
testString:SetText(text)
|
|
return testString:GetStringWidth()-- + TESTSTRING_EXTRA_WIDTH
|
|
end
|
|
do
|
|
local TabletData_mt = { __index = TabletData }
|
|
function TabletData:new(tablet)
|
|
local self = new()
|
|
self.categories = new()
|
|
self.id = 0
|
|
self.width = 0 -- (MIN_TOOLTIP_SIZE - 20)*tablet.fontSizePercent
|
|
self.tablet = tablet
|
|
self.title = "Title"
|
|
self.titleR, self.titleG, self.titleB = nil, nil, nil
|
|
self.num_lines = 0
|
|
setmetatable(self, TabletData_mt)
|
|
return self
|
|
end
|
|
|
|
function TabletData:checkMinWidth()
|
|
local width = (MIN_TOOLTIP_SIZE - 20)*self.tablet.fontSizePercent
|
|
if self.width < width then
|
|
self.width = width
|
|
end
|
|
end
|
|
|
|
function TabletData:del()
|
|
for k, v in ipairs(self.categories) do
|
|
v:del()
|
|
end
|
|
del(self.categories)
|
|
del(self)
|
|
end
|
|
|
|
function TabletData:Display()
|
|
if self.tablet == tooltip or self.tablet.registration.showTitleWhenDetached then
|
|
local info = new(
|
|
'hideBlankLine', true,
|
|
'text', self.title,
|
|
'justify', "CENTER",
|
|
'font', GameTooltipHeaderText,
|
|
'isTitle', true
|
|
)
|
|
if self.titleR then
|
|
info.textR = self.titleR
|
|
info.textG = self.titleG
|
|
info.textB = self.titleB
|
|
end
|
|
self:AddCategory(info, 1)
|
|
del(info)
|
|
end
|
|
if self.tablet == tooltip or self.tablet.registration.showHintWhenDetached then
|
|
if self.hint then
|
|
self:AddCategory(nil):AddLine(
|
|
'text', HINT .. ": " .. self.hint,
|
|
'textR', 0,
|
|
'textG', 1,
|
|
'textB', 0,
|
|
'wrap', true
|
|
)
|
|
end
|
|
end
|
|
|
|
local tabletData = self.tabletData
|
|
for k, v in ipairs(self.categories) do
|
|
local width
|
|
if v.columns <= 2 then
|
|
width = v.x1
|
|
else
|
|
width = v.x1 + v.x2 + v.x3 + v.x4 + v.x5 + v.x6 + (v.columns - 1) * 20
|
|
end
|
|
if self.width < width then
|
|
self.width = width
|
|
end
|
|
end
|
|
|
|
local good = false
|
|
local lastTitle = true
|
|
for k, v in ipairs(self.categories) do
|
|
if lastTitle then
|
|
v.hideBlankLine = true
|
|
lastTitle = false
|
|
end
|
|
if v:Display(self.tablet) and (not v.isTitle or not self.tablet.registration.hideWhenEmpty or next(self.categories, k)) then
|
|
good = true
|
|
end
|
|
if v.isTitle then
|
|
lastTitle = true
|
|
end
|
|
end
|
|
if not good then
|
|
if self.tablet == tooltip or not self.tablet.registration.hideWhenEmpty then
|
|
local width
|
|
local info = new(
|
|
'hideBlankLine', true,
|
|
'text', self.title,
|
|
'justify', "CENTER",
|
|
'font', GameTooltipHeaderText,
|
|
'isTitle', true
|
|
)
|
|
local cat = self:AddCategory(info)
|
|
del(info)
|
|
self.width = self.categories[#self.categories].x1
|
|
cat:Display(self.tablet)
|
|
else
|
|
self.tablet:__Hide()
|
|
self.tablet.tmpHidden = true
|
|
end
|
|
else
|
|
self.tablet:__Show()
|
|
self.tablet.tmpHidden = nil
|
|
end
|
|
end
|
|
|
|
function TabletData:AddCategory(info, index)
|
|
local made = false
|
|
if not info then
|
|
made = true
|
|
info = new()
|
|
end
|
|
local cat = Category:new(self, info)
|
|
if index then
|
|
table.insert(self.categories, index, cat)
|
|
else
|
|
table.insert(self.categories, cat)
|
|
end
|
|
if made then
|
|
del(info)
|
|
end
|
|
return cat
|
|
end
|
|
|
|
function TabletData:SetHint(hint)
|
|
self.hint = hint
|
|
end
|
|
|
|
function TabletData:SetTitle(title)
|
|
self.title = title or "Title"
|
|
end
|
|
|
|
function TabletData:SetTitleColor(r, g, b)
|
|
self.titleR = r
|
|
self.titleG = g
|
|
self.titleB = b
|
|
end
|
|
end
|
|
do
|
|
local Category_mt = { __index = Category }
|
|
function Category:new(tabletData, info, superCategory)
|
|
local self = copy(info)
|
|
if superCategory and not self.noInherit then
|
|
self.superCategory = superCategory.superCategory
|
|
for k, v in pairs(superCategory) do
|
|
if string.find(k, "^child_") then
|
|
local k = strsub(k, 7)
|
|
if self[k] == nil then
|
|
self[k] = v
|
|
end
|
|
end
|
|
end
|
|
self.columns = superCategory.columns
|
|
else
|
|
self.superCategory = self
|
|
end
|
|
self.tabletData = tabletData
|
|
self.lines = new()
|
|
if not self.columns then
|
|
self.columns = 1
|
|
end
|
|
self.x1 = 0
|
|
self.x2 = 0
|
|
self.x3 = 0
|
|
self.x4 = 0
|
|
self.x5 = 0
|
|
self.x6 = 0
|
|
setmetatable(self, Category_mt)
|
|
self.lastWasTitle = nil
|
|
if self.text or self.text2 or self.text3 or self.text4 or self.text5 or self.text6 then
|
|
local x = new(
|
|
'category', category,
|
|
'text', self.text,
|
|
'textR', self.textR or 1,
|
|
'textG', self.textG or 1,
|
|
'textB', self.textB or 1,
|
|
'fakeChild', true,
|
|
'func', self.func,
|
|
'hasCheck', self.hasCheck,
|
|
'checked', self.checked,
|
|
'checkIcon', self.checkIcon,
|
|
'isRadio', self.isRadio,
|
|
'font', self.font,
|
|
'size', self.size,
|
|
'wrap', self.wrap,
|
|
'catStart', true,
|
|
'indentation', self.indentation,
|
|
'noInherit', true,
|
|
'justify', self.justify,
|
|
'justify2', self.justify2,
|
|
'justify3', self.justify3,
|
|
'justify4', self.justify4,
|
|
'justify5', self.justify5,
|
|
'justify6', self.justify6
|
|
)
|
|
local i = 1
|
|
while true do
|
|
local k = 'arg' .. i
|
|
local v = self[k]
|
|
if v == nil then
|
|
break
|
|
end
|
|
x[k] = v
|
|
i = i + 1
|
|
end
|
|
if self.isTitle then
|
|
x.textR = self.textR or 1
|
|
x.textG = self.textG or 0.823529
|
|
x.textB = self.textB or 0
|
|
else
|
|
x.textR = self.textR or 1
|
|
x.textG = self.textG or 1
|
|
x.textB = self.textB or 1
|
|
end
|
|
x.text2 = self.text2
|
|
x.text3 = self.text3
|
|
x.text4 = self.text4
|
|
x.text5 = self.text5
|
|
x.text6 = self.text6
|
|
x.text2R = self.text2R or self.textR2 or 1
|
|
x.text2G = self.text2G or self.textG2 or 1
|
|
x.text2B = self.text2B or self.textB2 or 1
|
|
x.text3R = self.text3R or self.textR3 or 1
|
|
x.text3G = self.text3G or self.textG3 or 1
|
|
x.text3B = self.text3B or self.textB3 or 1
|
|
x.text4R = self.text4R or self.textR4 or 1
|
|
x.text4G = self.text4G or self.textG4 or 1
|
|
x.text4B = self.text4B or self.textB4 or 1
|
|
x.text5R = self.text5R or self.textR5 or 1
|
|
x.text5G = self.text5G or self.textG5 or 1
|
|
x.text5B = self.text5B or self.textB5 or 1
|
|
x.text6R = self.text6R or self.textR6 or 1
|
|
x.text6G = self.text6G or self.textG6 or 1
|
|
x.text6B = self.text6B or self.textB6 or 1
|
|
x.font2 = self.font2
|
|
x.font3 = self.font3
|
|
x.font4 = self.font4
|
|
x.font5 = self.font5
|
|
x.font6 = self.font6
|
|
x.size2 = self.size2
|
|
x.size3 = self.size3
|
|
x.size4 = self.size4
|
|
x.size5 = self.size5
|
|
x.size6 = self.size6
|
|
self:AddLine(x)
|
|
del(x)
|
|
self.lastWasTitle = true
|
|
end
|
|
return self
|
|
end
|
|
|
|
function Category:del()
|
|
local prev = garbageLine
|
|
for k, v in pairs(self.lines) do
|
|
v:del()
|
|
end
|
|
del(self.lines)
|
|
del(self)
|
|
end
|
|
|
|
function Category:AddLine(...)
|
|
self.lastWasTitle = nil
|
|
local line
|
|
local k1 = ...
|
|
if type(k1) == "table" then
|
|
local k2 = select(2, ...)
|
|
Line:new(self, k1, k2)
|
|
else
|
|
local info = new(...)
|
|
Line:new(self, info)
|
|
info = del(info)
|
|
end
|
|
end
|
|
|
|
function Category:AddCategory(...)
|
|
local lastWasTitle = self.lastWasTitle
|
|
self.lastWasTitle = nil
|
|
local info
|
|
local k1 = ...
|
|
if type(k1) == "table" then
|
|
info = k1
|
|
else
|
|
info = new(...)
|
|
end
|
|
if lastWasTitle or #self.lines == 0 then
|
|
info.hideBlankLine = true
|
|
end
|
|
local cat = Category:new(self.tabletData, info, self)
|
|
table.insert(self.lines, cat)
|
|
if info ~= k1 then
|
|
info = del(info)
|
|
end
|
|
return cat
|
|
end
|
|
|
|
function Category:HasChildren()
|
|
local hasChildren = false
|
|
for k, v in ipairs(self.lines) do
|
|
if v.HasChildren then
|
|
if v:HasChildren() then
|
|
return true
|
|
end
|
|
end
|
|
if not v.fakeChild then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local lastWasTitle = false
|
|
function Category:Display(tablet)
|
|
if not self.isTitle and not self.showWithoutChildren and not self:HasChildren() then
|
|
return false
|
|
end
|
|
if not self.hideBlankLine and not lastWasTitle then
|
|
local info = new(
|
|
'blank', true,
|
|
'fakeChild', true
|
|
)
|
|
self:AddLine(info, 1)
|
|
del(info)
|
|
end
|
|
local good = false
|
|
if #self.lines > 0 then
|
|
self.tabletData.id = self.tabletData.id + 1
|
|
self.id = self.tabletData.id
|
|
for k, v in ipairs(self.lines) do
|
|
if v:Display(tablet) then
|
|
good = true
|
|
end
|
|
end
|
|
end
|
|
lastWasTitle = self.isTitle
|
|
return good
|
|
end
|
|
end
|
|
do
|
|
local Line_mt = { __index = Line }
|
|
function Line:new(category, info, position)
|
|
local self = copy(info)
|
|
if not info.noInherit then
|
|
for k, v in pairs(category) do
|
|
if string.find(k, "^child_") then
|
|
local k = strsub(k, 7)
|
|
if self[k] == nil then
|
|
self[k] = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
self.category = category
|
|
if position then
|
|
table.insert(category.lines, position, self)
|
|
else
|
|
table.insert(category.lines, self)
|
|
end
|
|
setmetatable(self, Line_mt)
|
|
local n = category.tabletData.num_lines + 1
|
|
category.tabletData.num_lines = n
|
|
if n == 15 then
|
|
category.tabletData:checkMinWidth()
|
|
end
|
|
local columns = category.columns
|
|
if columns == 1 then
|
|
if not self.justify then
|
|
self.justify = "LEFT"
|
|
end
|
|
elseif columns == 2 then
|
|
self.justify = "LEFT"
|
|
self.justify2 = "RIGHT"
|
|
if self.wrap then
|
|
self.wrap2 = false
|
|
end
|
|
elseif columns == 3 then
|
|
if not self.justify then
|
|
self.justify = "LEFT"
|
|
end
|
|
if not self.justify2 then
|
|
self.justify2 = "CENTER"
|
|
end
|
|
if not self.justify3 then
|
|
self.justify3 = "RIGHT"
|
|
end
|
|
if self.wrap then
|
|
self.wrap2 = false
|
|
self.wrap3 = false
|
|
elseif self.wrap2 then
|
|
self.wrap3 = false
|
|
end
|
|
elseif columns == 4 then
|
|
if not self.justify then
|
|
self.justify = "LEFT"
|
|
end
|
|
if not self.justify2 then
|
|
self.justify2 = "CENTER"
|
|
end
|
|
if not self.justify3 then
|
|
self.justify3 = "CENTER"
|
|
end
|
|
if not self.justify4 then
|
|
self.justify4 = "RIGHT"
|
|
end
|
|
if self.wrap then
|
|
self.wrap2 = false
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
elseif self.wrap2 then
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
elseif self.wrap3 then
|
|
self.wrap4 = false
|
|
end
|
|
elseif columns == 5 then
|
|
if not self.justify then
|
|
self.justify = "LEFT"
|
|
end
|
|
if not self.justify2 then
|
|
self.justify2 = "CENTER"
|
|
end
|
|
if not self.justify3 then
|
|
self.justify3 = "CENTER"
|
|
end
|
|
if not self.justify4 then
|
|
self.justify4 = "CENTER"
|
|
end
|
|
if not self.justify5 then
|
|
self.justify5 = "RIGHT"
|
|
end
|
|
if self.wrap then
|
|
self.wrap2 = false
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
elseif self.wrap2 then
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
elseif self.wrap3 then
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
elseif self.wrap4 then
|
|
self.wrap5 = false
|
|
end
|
|
elseif columns == 6 then
|
|
if not self.justify then
|
|
self.justify = "LEFT"
|
|
end
|
|
if not self.justify2 then
|
|
self.justify2 = "CENTER"
|
|
end
|
|
if not self.justify3 then
|
|
self.justify3 = "CENTER"
|
|
end
|
|
if not self.justify4 then
|
|
self.justify4 = "CENTER"
|
|
end
|
|
if not self.justify5 then
|
|
self.justify5 = "CENTER"
|
|
end
|
|
if not self.justify6 then
|
|
self.justify6 = "RIGHT"
|
|
end
|
|
if self.wrap then
|
|
self.wrap2 = false
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
self.wrap6 = false
|
|
elseif self.wrap2 then
|
|
self.wrap3 = false
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
self.wrap6 = false
|
|
elseif self.wrap3 then
|
|
self.wrap4 = false
|
|
self.wrap5 = false
|
|
self.wrap6 = false
|
|
elseif self.wrap4 then
|
|
self.wrap5 = false
|
|
self.wrap6 = false
|
|
elseif self.wrap5 then
|
|
self.wrap6 = false
|
|
end
|
|
end
|
|
if self.textR2 then
|
|
self.text2R, self.textR2 = self.text2R or self.textR2
|
|
self.text2G, self.textG2 = self.text2G or self.textG2
|
|
self.text2B, self.textB2 = self.text2B or self.textB2
|
|
if self.textR3 then
|
|
self.text3R, self.textR3 = self.text3R or self.textR3
|
|
self.text3G, self.textG3 = self.text3G or self.textG3
|
|
self.text3B, self.textB3 = self.text3B or self.textB3
|
|
if self.textR4 then
|
|
self.text4R, self.textR4 = self.text4R or self.textR4
|
|
self.text4G, self.textG4 = self.text4G or self.textG4
|
|
self.text4B, self.textB4 = self.text4B or self.textB4
|
|
if self.textR5 then
|
|
self.text5R, self.textR5 = self.text5R or self.textR5
|
|
self.text5G, self.textG5 = self.text5G or self.textG5
|
|
self.text5B, self.textB5 = self.text5B or self.textB5
|
|
if self.textR5 then
|
|
self.text6R, self.textR6 = self.text6R or self.textR6
|
|
self.text6G, self.textG6 = self.text6G or self.textG6
|
|
self.text6B, self.textB6 = self.text6B or self.textB6
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not self.indentation or self.indentation < 0 then
|
|
self.indentation = 0
|
|
end
|
|
if not self.font then
|
|
self.font = GameTooltipText
|
|
end
|
|
if not self.font2 then
|
|
self.font2 = self.font
|
|
end
|
|
if not self.font3 then
|
|
self.font3 = self.font
|
|
end
|
|
if not self.font4 then
|
|
self.font4 = self.font
|
|
end
|
|
if not self.font5 then
|
|
self.font5 = self.font
|
|
end
|
|
if not self.font6 then
|
|
self.font6 = self.font
|
|
end
|
|
if not self.size then
|
|
_,self.size = self.font:GetFont()
|
|
end
|
|
if not self.size2 then
|
|
_,self.size2 = self.font2:GetFont()
|
|
end
|
|
if not self.size3 then
|
|
_,self.size3 = self.font3:GetFont()
|
|
end
|
|
if not self.size4 then
|
|
_,self.size4 = self.font4:GetFont()
|
|
end
|
|
if not self.size5 then
|
|
_,self.size5 = self.font5:GetFont()
|
|
end
|
|
if not self.size6 then
|
|
_,self.size6 = self.font6:GetFont()
|
|
end
|
|
|
|
local fontSizePercent = category.tabletData.tablet.fontSizePercent
|
|
local w = 0
|
|
self.checkWidth = 0
|
|
testString = category.tabletData.tablet.lefts[1]
|
|
if self.text then
|
|
if not self.wrap then
|
|
local testWidth = getTestWidth(self.font, self.size * fontSizePercent, self.text)
|
|
local checkWidth = self.hasCheck and self.size * fontSizePercent or 0
|
|
self.checkWidth = checkWidth
|
|
w = testWidth + self.indentation * fontSizePercent + checkWidth
|
|
if category.superCategory.x1 < w then
|
|
category.superCategory.x1 = w
|
|
end
|
|
else
|
|
if columns == 1 then
|
|
local testWidth = getTestWidth(self.font, self.size * fontSizePercent, self.text)
|
|
local checkWidth = self.hasCheck and self.size * fontSizePercent or 0
|
|
self.checkWidth = checkWidth
|
|
w = testWidth + self.indentation * fontSizePercent + checkWidth
|
|
if w > (MIN_TOOLTIP_SIZE - 20) * fontSizePercent then
|
|
w = (MIN_TOOLTIP_SIZE - 20) * fontSizePercent
|
|
end
|
|
else
|
|
w = MIN_TOOLTIP_SIZE * fontSizePercent / 2
|
|
end
|
|
if category.superCategory.x1 < w then
|
|
category.superCategory.x1 = w
|
|
end
|
|
end
|
|
end
|
|
if columns == 2 and self.text2 then
|
|
if not self.wrap2 then
|
|
local testWidth = getTestWidth(self.font2, self.size2 * fontSizePercent, self.text2)
|
|
w = w + 40 * fontSizePercent + testWidth
|
|
if category.superCategory.x1 < w then
|
|
category.superCategory.x1 = w
|
|
end
|
|
else
|
|
w = w + 40 * fontSizePercent + MIN_TOOLTIP_SIZE * fontSizePercent / 2
|
|
if category.superCategory.x1 < w then
|
|
category.superCategory.x1 = w
|
|
end
|
|
end
|
|
elseif columns >= 3 then
|
|
if self.text2 then
|
|
if not self.wrap2 then
|
|
local testWidth = getTestWidth(self.font2, self.size2 * fontSizePercent, self.text2)
|
|
local w = testWidth
|
|
if category.superCategory.x2 < w then
|
|
category.superCategory.x2 = w
|
|
end
|
|
else
|
|
local w = MIN_TOOLTIP_SIZE / 2
|
|
if category.superCategory.x2 < w then
|
|
category.superCategory.x2 = w
|
|
end
|
|
end
|
|
end
|
|
if self.text3 then
|
|
if not self.wrap3 then
|
|
local testWidth = getTestWidth(self.font3, self.size3 * fontSizePercent, self.text3)
|
|
local w = testWidth
|
|
if category.superCategory.x3 < w then
|
|
category.superCategory.x3 = w
|
|
end
|
|
else
|
|
local w = MIN_TOOLTIP_SIZE / 2
|
|
if category.superCategory.x3 < w then
|
|
category.superCategory.x3 = w
|
|
end
|
|
end
|
|
end
|
|
if columns >= 4 then
|
|
if self.text4 then
|
|
if not self.wrap4 then
|
|
local testWidth = getTestWidth(self.font4, self.size4 * fontSizePercent, self.text4)
|
|
w = testWidth
|
|
if category.superCategory.x4 < w then
|
|
category.superCategory.x4 = w
|
|
end
|
|
else
|
|
local w = MIN_TOOLTIP_SIZE / 2
|
|
if category.superCategory.x4 < w then
|
|
category.superCategory.x4 = w
|
|
end
|
|
end
|
|
end
|
|
if columns >= 5 then
|
|
if self.text5 then
|
|
if not self.wrap5 then
|
|
local testWidth = getTestWidth(self.font5, self.size5 * fontSizePercent, self.text5)
|
|
w = testWidth
|
|
if category.superCategory.x5 < w then
|
|
category.superCategory.x5 = w
|
|
end
|
|
else
|
|
local w = MIN_TOOLTIP_SIZE / 2
|
|
if category.superCategory.x5 < w then
|
|
category.superCategory.x5 = w
|
|
end
|
|
end
|
|
end
|
|
if columns >= 6 then
|
|
if self.text6 then
|
|
if not self.wrap6 then
|
|
local testWidth = getTestWidth(self.font6, self.size6 * fontSizePercent, self.text6)
|
|
w = testWidth
|
|
if category.superCategory.x6 < w then
|
|
category.superCategory.x6 = w
|
|
end
|
|
else
|
|
local w = MIN_TOOLTIP_SIZE / 2
|
|
if category.superCategory.x6 < w then
|
|
category.superCategory.x6 = w
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
function Line:del()
|
|
del(self)
|
|
end
|
|
|
|
function Line:Display(tablet)
|
|
tablet:AddLine(self)
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function button_OnEnter()
|
|
if type(this.self:GetScript("OnEnter")) == "function" then
|
|
this.self:GetScript("OnEnter")()
|
|
end
|
|
this.highlight:Show()
|
|
end
|
|
|
|
local function button_OnLeave()
|
|
if type(this.self:GetScript("OnLeave")) == "function" then
|
|
this.self:GetScript("OnLeave")()
|
|
end
|
|
this.highlight:Hide()
|
|
end
|
|
|
|
local num_buttons = 0
|
|
local function NewLine(self)
|
|
if self.maxLines <= self.numLines then
|
|
self.maxLines = self.maxLines + 1
|
|
num_buttons = num_buttons + 1
|
|
local button = CreateFrame("Button", "Tablet20Button" .. num_buttons, self)
|
|
button:SetFrameLevel(self:GetFrameLevel()+2)
|
|
button.indentation = 0
|
|
local check = button:CreateTexture(nil, "ARTWORK")
|
|
local left = button:CreateFontString(nil, "ARTWORK")
|
|
testString = left
|
|
local right = button:CreateFontString(nil, "ARTWORK")
|
|
local third = button:CreateFontString(nil, "ARTWORK")
|
|
local fourth = button:CreateFontString(nil, "ARTWORK")
|
|
local fifth = button:CreateFontString(nil, "ARTWORK")
|
|
local sixth = button:CreateFontString(nil, "ARTWORK")
|
|
local highlight = button:CreateTexture(nil, "BACKGROUND")
|
|
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
|
button.highlight = highlight
|
|
highlight:SetBlendMode("ADD")
|
|
highlight:SetAllPoints(button)
|
|
highlight:Hide()
|
|
table.insert(self.buttons, button)
|
|
table.insert(self.checks, check)
|
|
table.insert(self.lefts, left)
|
|
table.insert(self.rights, right)
|
|
table.insert(self.thirds, third)
|
|
table.insert(self.fourths, fourth)
|
|
table.insert(self.fifths, fifth)
|
|
table.insert(self.sixths, sixth)
|
|
left:SetWidth(0)
|
|
if self.maxLines == 1 then
|
|
left:SetFontObject(GameTooltipHeaderText)
|
|
right:SetFontObject(GameTooltipHeaderText)
|
|
third:SetFontObject(GameTooltipHeaderText)
|
|
fourth:SetFontObject(GameTooltipHeaderText)
|
|
fifth:SetFontObject(GameTooltipHeaderText)
|
|
sixth:SetFontObject(GameTooltipHeaderText)
|
|
left:SetJustifyH("CENTER")
|
|
button:SetPoint("TOPLEFT", self, "TOPLEFT", 8, -10)
|
|
else
|
|
left:SetFontObject(GameTooltipText)
|
|
right:SetFontObject(GameTooltipText)
|
|
third:SetFontObject(GameTooltipText)
|
|
fourth:SetFontObject(GameTooltipText)
|
|
fifth:SetFontObject(GameTooltipText)
|
|
sixth:SetFontObject(GameTooltipText)
|
|
button:SetPoint("TOPLEFT", self.buttons[self.maxLines - 1], "BOTTOMLEFT", 0, -2)
|
|
end
|
|
button:SetScript("OnEnter", button_OnEnter)
|
|
button:SetScript("OnLeave", button_OnLeave)
|
|
button.check = check
|
|
button.self = self
|
|
button:SetPoint("RIGHT", self, "RIGHT", -12, 0)
|
|
check.shown = false
|
|
check:SetPoint("TOPLEFT", button, "TOPLEFT")
|
|
left:SetPoint("TOPLEFT", check, "TOPLEFT")
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * self.fontSizePercent, 0)
|
|
third:SetPoint("TOPLEFT", right, "TOPRIGHT", 20 * self.fontSizePercent, 0)
|
|
fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", 20 * self.fontSizePercent, 0)
|
|
fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", 20 * self.fontSizePercent, 0)
|
|
sixth:SetPoint("TOPLEFT", fifth, "TOPRIGHT", 20 * self.fontSizePercent, 0)
|
|
right:SetJustifyH("RIGHT")
|
|
local _,size = GameTooltipText:GetFont()
|
|
check:SetHeight(size * 1.5)
|
|
check:SetWidth(size * 1.5)
|
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
check:SetAlpha(0)
|
|
if not button.clicked then
|
|
button:SetScript("OnMouseWheel", self:GetScript("OnMouseWheel"))
|
|
button:EnableMouseWheel(true)
|
|
button:Hide()
|
|
end
|
|
check:Show()
|
|
left:Hide()
|
|
right:Hide()
|
|
third:Hide()
|
|
fourth:Hide()
|
|
fifth:Hide()
|
|
sixth:Hide()
|
|
end
|
|
end
|
|
NewLine = wrap(NewLine, "NewLine")
|
|
|
|
local function GetMaxLinesPerScreen(self)
|
|
if self.height_ then
|
|
local height = self:GetTop() and self:GetBottom() and self:GetTop() - self:GetBottom() or self:GetHeight()
|
|
if height == 0 then
|
|
height = self.height_
|
|
end
|
|
height = height - 20
|
|
return floor(height / (12*self.fontSizePercent+2))
|
|
end
|
|
if self == tooltip then
|
|
return floor(50 / self.fontSizePercent)
|
|
else
|
|
return floor(30 / self.fontSizePercent)
|
|
end
|
|
end
|
|
GetMaxLinesPerScreen = wrap(GetMaxLinesPerScreen, "GetMaxLinesPerScreen")
|
|
|
|
local overFrame = nil
|
|
local detachedTooltips = {}
|
|
local AcquireDetachedFrame, ReleaseDetachedFrame
|
|
local function AcquireFrame(self, registration, data, detachedData)
|
|
if not detachedData then
|
|
detachedData = data
|
|
end
|
|
if tooltip then
|
|
tooltip.data = data
|
|
tooltip.detachedData = detachedData
|
|
local fontSizePercent = tooltip.data and tooltip.data.fontSizePercent or 1
|
|
local transparency = tooltip.data and tooltip.data.transparency or 0.75
|
|
local r = tooltip.data and tooltip.data.r or 0
|
|
local g = tooltip.data and tooltip.data.g or 0
|
|
local b = tooltip.data and tooltip.data.b or 0
|
|
tooltip:SetFontSizePercent(fontSizePercent)
|
|
tooltip:SetTransparency(transparency)
|
|
tooltip:SetColor(r, g, b)
|
|
tooltip:SetFrameStrata(registration.strata or "TOOLTIP")
|
|
else
|
|
tooltip = CreateFrame("Frame", "Tablet20Frame", UIParent)
|
|
self.tooltip = tooltip
|
|
tooltip.data = data
|
|
tooltip.detachedData = detachedData
|
|
tooltip:EnableMouse(true)
|
|
tooltip:EnableMouseWheel(true)
|
|
tooltip:SetFrameStrata(registration.strata or "TOOLTIP")
|
|
tooltip:SetFrameLevel(10)
|
|
local backdrop = new(
|
|
'bgFile', "Interface\\Buttons\\WHITE8X8",
|
|
'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
'tile', true,
|
|
'tileSize', 16,
|
|
'edgeSize', 16,
|
|
'insets', new(
|
|
'left', 5,
|
|
'right', 5,
|
|
'top', 5,
|
|
'bottom', 5
|
|
)
|
|
)
|
|
tooltip:SetBackdrop(backdrop)
|
|
del(backdrop.insets)
|
|
del(backdrop)
|
|
tooltip:SetBackdropColor(0, 0, 0, 1)
|
|
|
|
tooltip.numLines = 0
|
|
tooltip.owner = nil
|
|
tooltip.fontSizePercent = tooltip.data and tooltip.data.fontSizePercent or 1
|
|
tooltip.maxLines = 0
|
|
tooltip.buttons = {}
|
|
tooltip.checks = {}
|
|
tooltip.lefts = {}
|
|
tooltip.rights = {}
|
|
tooltip.thirds = {}
|
|
tooltip.fourths = {}
|
|
tooltip.fifths = {}
|
|
tooltip.sixths = {}
|
|
tooltip.transparency = tooltip.data and tooltip.data.transparency or 0.75
|
|
tooltip:SetBackdropColor(0, 0, 0, tooltip.transparency)
|
|
tooltip:SetBackdropBorderColor(1, 1, 1, tooltip.transparency)
|
|
tooltip.scroll = 0
|
|
|
|
tooltip:SetScript("OnUpdate", function()
|
|
if not tooltip.updating and (not tooltip.enteredFrame or (overFrame and not MouseIsOver(overFrame))) then
|
|
tooltip.scroll = 0
|
|
tooltip:Hide()
|
|
tooltip.registration.tooltip = nil
|
|
tooltip.registration = nil
|
|
overFrame = nil
|
|
end
|
|
end)
|
|
|
|
tooltip:SetScript("OnEnter", function()
|
|
if tooltip.clickable then
|
|
tooltip.enteredFrame = true
|
|
overFrame = nil
|
|
end
|
|
end)
|
|
|
|
tooltip:SetScript("OnLeave", function()
|
|
if not tooltip.updating then
|
|
tooltip.enteredFrame = false
|
|
end
|
|
end)
|
|
|
|
tooltip:SetScript("OnMouseWheel", function()
|
|
tooltip.updating = true
|
|
tooltip:Scroll(arg1 < 0)
|
|
tooltip.updating = false
|
|
end)
|
|
|
|
NewLine(tooltip)
|
|
|
|
tooltip.scrollUp = tooltip:CreateFontString(nil, "ARTWORK")
|
|
tooltip.scrollUp:SetPoint("TOPLEFT", tooltip.buttons[1], "BOTTOMLEFT", 0, -2)
|
|
tooltip.scrollUp:SetPoint("RIGHT", tooltip, "RIGHT", 0, -10)
|
|
tooltip.scrollUp:SetFontObject(GameTooltipText)
|
|
tooltip.scrollUp:Hide()
|
|
local font,_,flags = tooltip.scrollUp:GetFont()
|
|
tooltip.scrollUp:SetFont(font, normalSize * tooltip.fontSizePercent, flags)
|
|
tooltip.scrollUp:SetJustifyH("CENTER")
|
|
tooltip.scrollUp:SetTextColor(1, 0.823529, 0)
|
|
tooltip.scrollUp:SetText(" ")
|
|
|
|
tooltip.scrollDown = tooltip:CreateFontString(nil, "ARTWORK")
|
|
tooltip.scrollDown:SetPoint("TOPLEFT", tooltip.buttons[1], "BOTTOMLEFT", 0, -2)
|
|
tooltip.scrollDown:SetPoint("RIGHT", tooltip, "RIGHT", 0, -10)
|
|
tooltip.scrollDown:SetFontObject(GameTooltipText)
|
|
tooltip.scrollDown:Hide()
|
|
local font,_,flags = tooltip.scrollUp:GetFont()
|
|
tooltip.scrollDown:SetFont(font, normalSize * tooltip.fontSizePercent, flags)
|
|
tooltip.scrollDown:SetJustifyH("CENTER")
|
|
tooltip.scrollDown:SetTextColor(1, 0.823529, 0)
|
|
tooltip.scrollDown:SetText(" ")
|
|
|
|
function tooltip:SetOwner(o)
|
|
self:Hide(o)
|
|
self.owner = o
|
|
end
|
|
tooltip.SetOwner = wrap(tooltip.SetOwner, "tooltip:SetOwner")
|
|
|
|
function tooltip:IsOwned(o)
|
|
return self.owner == o
|
|
end
|
|
tooltip.IsOwned = wrap(tooltip.IsOwned, "tooltip:IsOwned")
|
|
|
|
function tooltip:ClearLines(hide)
|
|
CleanCategoryPool(self)
|
|
for i = 1, self.numLines do
|
|
local button = self.buttons[i]
|
|
local check = self.checks[i]
|
|
if not button.clicked or hide then
|
|
button:Hide()
|
|
end
|
|
check.shown = false
|
|
check:SetAlpha(0)
|
|
end
|
|
self.numLines = 0
|
|
end
|
|
tooltip.ClearLines = wrap(tooltip.ClearLines, "tooltip:ClearLines")
|
|
|
|
function tooltip:NumLines()
|
|
return self.numLines
|
|
end
|
|
|
|
local lastWidth
|
|
local old_tooltip_Hide = tooltip.Hide
|
|
tooltip.__Hide = old_tooltip_Hide
|
|
function tooltip:Hide(newOwner)
|
|
if self == tooltip or newOwner == nil then
|
|
old_tooltip_Hide(self)
|
|
end
|
|
self:ClearLines(true)
|
|
self.owner = nil
|
|
self.lastWidth = nil
|
|
self.tmpHidden = nil
|
|
end
|
|
tooltip.Hide = wrap(tooltip.Hide, "tooltip:Hide")
|
|
|
|
local old_tooltip_Show = tooltip.Show
|
|
tooltip.__Show = old_tooltip_Show
|
|
function tooltip:Show(tabletData)
|
|
if self.owner == nil or self.notInUse then
|
|
return
|
|
end
|
|
if not self.tmpHidden then
|
|
old_tooltip_Show(self)
|
|
end
|
|
|
|
testString = self.lefts[1]
|
|
|
|
local maxWidth = tabletData and tabletData.width or self:GetWidth() - 20
|
|
local hasWrap = false
|
|
local screenWidth = GetScreenWidth()
|
|
local scrollMax = self.numLines
|
|
local maxLinesPerScreen = GetMaxLinesPerScreen(self)
|
|
if scrollMax > maxLinesPerScreen + self.scroll then
|
|
scrollMax = maxLinesPerScreen + self.scroll
|
|
end
|
|
local numColumns
|
|
|
|
local height = 20
|
|
if scrollMax ~= self.numLines then
|
|
self.scrollDown:SetWidth(maxWidth)
|
|
height = height + self.scrollDown:GetHeight() + 2
|
|
end
|
|
if self.scroll ~= 0 then
|
|
self.scrollUp:SetWidth(maxWidth)
|
|
height = height + self.scrollUp:GetHeight() + 2
|
|
end
|
|
self:SetWidth(maxWidth + 20)
|
|
|
|
local tmp = self.scroll + 1
|
|
if tmp ~= 1 then
|
|
tmp = tmp + 1
|
|
end
|
|
for i = 1, self.numLines do
|
|
if i < tmp or i > scrollMax or (i == scrollMax and i ~= self.numLines) then
|
|
self.buttons[i]:ClearAllPoints()
|
|
self.buttons[i]:Hide()
|
|
else
|
|
local button = self.buttons[i]
|
|
local left = self.lefts[i]
|
|
local right = self.rights[i]
|
|
local check = self.checks[i]
|
|
button:SetWidth(maxWidth)
|
|
button:SetHeight(math.max(left:GetHeight(), right:GetHeight()))
|
|
height = height + button:GetHeight() + 2
|
|
if i == self.scroll + 1 then
|
|
button:SetPoint("TOPLEFT", self, "TOPLEFT", 10, -10)
|
|
else
|
|
button:SetPoint("TOPLEFT", self.buttons[i - 1], "BOTTOMLEFT", 0, -2)
|
|
end
|
|
if button.clicked then
|
|
check:SetPoint("TOPLEFT", button, "TOPLEFT", button.indentation * self.fontSizePercent + (check.width - check:GetWidth()) / 2 + 1, -1)
|
|
else
|
|
check:SetPoint("TOPLEFT", button, "TOPLEFT", button.indentation * self.fontSizePercent + (check.width - check:GetWidth()) / 2, 0)
|
|
end
|
|
button:Show()
|
|
end
|
|
end
|
|
if self.scroll ~= 0 then
|
|
self.scrollUp:SetPoint("TOPLEFT", self, "TOPLEFT", 10, -10)
|
|
self.buttons[self.scroll + 2]:SetPoint("TOPLEFT", self.scrollUp, "BOTTOMLEFT", 0, -2)
|
|
self.scrollUp:SetText(SCROLL_UP .. " (" .. self.scroll + 2 .. " / " .. self.numLines .. ")")
|
|
self.scrollUp:Show()
|
|
else
|
|
self.scrollUp:Hide()
|
|
end
|
|
if scrollMax ~= self.numLines and self.buttons[scrollMax - 1] then
|
|
self.scrollDown:SetPoint("TOPLEFT", self.buttons[scrollMax - 1], "BOTTOMLEFT", 0, -2)
|
|
self.scrollDown:SetText(SCROLL_DOWN .. " (" .. scrollMax - 1 .. " / " .. self.numLines .. ")")
|
|
self.scrollDown:Show()
|
|
else
|
|
self.scrollDown:Hide()
|
|
end
|
|
self:SetHeight(height)
|
|
end
|
|
tooltip.Show = wrap(tooltip.Show, "tooltip:Show")
|
|
|
|
local lastMouseDown
|
|
local function button_OnClick()
|
|
if this.self:HasScript("OnClick") and type(this.self:GetScript("OnClick")) == "function" then
|
|
this.self:GetScript("OnClick")()
|
|
end
|
|
if arg1 == "RightButton" then
|
|
if this.self:HasScript("OnClick") and type(this.self:GetScript("OnClick")) == "function" then
|
|
this.self:GetScript("OnClick")()
|
|
end
|
|
elseif arg1 == "LeftButton" then
|
|
if this.self.preventClick == nil or GetTime() > this.self.preventClick and GetTime() < lastMouseDown + 0.5 then
|
|
this.self.preventClick = nil
|
|
this.self.updating = true
|
|
this.self.preventRefresh = true
|
|
this.func(unpack(this))
|
|
if this.self and this.self.registration then
|
|
this.self.preventRefresh = false
|
|
this.self:children()
|
|
this.self.updating = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local function button_OnMouseUp()
|
|
if this.self:HasScript("OnMouseUp") and type(this.self:GetScript("OnMouseUp")) == "function" then
|
|
this.self:GetScript("OnMouseUp")()
|
|
end
|
|
if arg1 ~= "RightButton" then
|
|
if this.clicked then
|
|
local a,b,c,d,e = this.check:GetPoint(1)
|
|
this.check:SetPoint(a,b,c,d-1,e+1)
|
|
this.clicked = false
|
|
end
|
|
end
|
|
end
|
|
local function button_OnMouseDown()
|
|
if this.self:HasScript("OnMouseDown") and type(this.self:GetScript("OnMouseDown")) == "function" then
|
|
this.self:GetScript("OnMouseDown")()
|
|
end
|
|
lastMouseDown = GetTime()
|
|
if arg1 ~= "RightButton" then
|
|
local a,b,c,d,e = this.check:GetPoint(1)
|
|
this.check:SetPoint(a,b,c,d+1,e-1)
|
|
this.clicked = true
|
|
end
|
|
end
|
|
function tooltip:AddLine(info)
|
|
local category = info.category.superCategory
|
|
local maxWidth = category.tabletData.width
|
|
local text = info.blank and "\n" or info.text
|
|
local id = info.id
|
|
local func = info.func
|
|
local checked = info.checked
|
|
local isRadio = info.isRadio
|
|
local checkTexture = info.checkTexture
|
|
local fontSizePercent = self.fontSizePercent
|
|
if not info.font then
|
|
info.font = GameTooltipText
|
|
end
|
|
if not info.size then
|
|
_,info.size = info.font:GetFont()
|
|
end
|
|
local catStart = false
|
|
local columns = category and category.columns or 1
|
|
local x1, x2, x3, x4, x5, x6
|
|
if category then
|
|
x1, x2, x3, x4, x5, x6 = category.x1, category.x2, category.x3, category.x4, category.x5, category.x6
|
|
else
|
|
x1, x2, x3, x4, x5, x6 = 0, 0, 0, 0, 0, 0
|
|
end
|
|
if info.isTitle then
|
|
justAddedTitle = true
|
|
end
|
|
|
|
self.numLines = self.numLines + 1
|
|
NewLine(self)
|
|
self.lefts[self.numLines]:Show()
|
|
self.buttons[self.numLines]:Show()
|
|
num = self.numLines
|
|
|
|
local button = self.buttons[num]
|
|
button.indentation = info.indentation
|
|
local left = self.lefts[num]
|
|
-- testString = left
|
|
|
|
local right = self.rights[num]
|
|
local third = self.thirds[num]
|
|
local fourth = self.fourths[num]
|
|
local fifth = self.fifths[num]
|
|
local sixth = self.sixths[num]
|
|
local check = self.checks[num]
|
|
do -- if columns >= 1 then
|
|
left:SetWidth(0)
|
|
left:SetFontObject(info.font)
|
|
local font,_,flags = left:GetFont()
|
|
left:SetFont(font, info.size * fontSizePercent, flags)
|
|
left:SetText(text)
|
|
left:SetJustifyH(info.justify)
|
|
left:Show()
|
|
|
|
if info.textR and info.textG and info.textB then
|
|
left:SetTextColor(info.textR, info.textG, info.textB)
|
|
else
|
|
left:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
if columns < 2 then
|
|
right:SetText(nil)
|
|
right:Hide()
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * fontSizePercent, 0)
|
|
right:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, 0)
|
|
third:SetText(nil)
|
|
third:Hide()
|
|
fourth:SetText(nil)
|
|
fourth:Hide()
|
|
fifth:SetText(nil)
|
|
fifth:Hide()
|
|
sixth:SetText(nil)
|
|
sixth:Hide()
|
|
else
|
|
right:SetFontObject(info.font2)
|
|
right:SetText(info.text2)
|
|
right:Show()
|
|
if info.text2R and info.text2G and info.text2B then
|
|
right:SetTextColor(info.text2R, info.text2G, info.text2B)
|
|
else
|
|
right:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
local a,_,b = right:GetFont()
|
|
right:SetFont(a, info.size2 * fontSizePercent, b)
|
|
right:SetJustifyH(info.justify2)
|
|
if columns < 3 then
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * fontSizePercent, 0)
|
|
right:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, 0)
|
|
third:SetText(nil)
|
|
third:Hide()
|
|
fourth:SetText(nil)
|
|
fourth:Hide()
|
|
fifth:SetText(nil)
|
|
fifth:Hide()
|
|
sixth:SetText(nil)
|
|
sixth:Hide()
|
|
else
|
|
third:SetFontObject(info.font3)
|
|
third:SetText(info.text3)
|
|
third:Show()
|
|
if info.text3R and info.text3G and info.text3B then
|
|
third:SetTextColor(info.text3R, info.text3G, info.text3B)
|
|
else
|
|
third:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
local a,_,b = third:GetFont()
|
|
third:SetFont(a, info.size3 * fontSizePercent, b)
|
|
right:ClearAllPoints()
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", (20 - info.indentation) * fontSizePercent, 0)
|
|
third:SetJustifyH(info.justify3)
|
|
if columns < 4 then
|
|
fourth:SetText(nil)
|
|
fourth:Hide()
|
|
fifth:SetText(nil)
|
|
fifth:Hide()
|
|
sixth:SetText(nil)
|
|
sixth:Hide()
|
|
else
|
|
fourth:SetFontObject(info.font4)
|
|
fourth:SetText(info.text4)
|
|
fourth:Show()
|
|
if info.text4R and info.text4G and info.text4B then
|
|
fourth:SetTextColor(info.text4R, info.text4G, info.text4B)
|
|
else
|
|
fourth:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
local a,_,b = fourth:GetFont()
|
|
fourth:SetFont(a, info.size4 * fontSizePercent, b)
|
|
fourth:SetJustifyH(info.justify4)
|
|
if columns < 5 then
|
|
fifth:SetText(nil)
|
|
fifth:Hide()
|
|
sixth:SetText(nil)
|
|
sixth:Hide()
|
|
else
|
|
fifth:SetFontObject(info.font5)
|
|
fifth:SetText(info.text5)
|
|
fifth:Show()
|
|
if info.text5R and info.text5G and info.text5B then
|
|
fifth:SetTextColor(info.text5R, info.text5G, info.text5B)
|
|
else
|
|
fifth:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
local a,_,b = fourth:GetFont()
|
|
fifth:SetFont(a, info.size5 * fontSizePercent, b)
|
|
fifth:SetJustifyH(info.justify5)
|
|
if columns < 6 then
|
|
sixth:SetText(nil)
|
|
sixth:Hide()
|
|
else
|
|
sixth:SetFontObject(info.font6)
|
|
sixth:SetText(info.text6)
|
|
sixth:Show()
|
|
if info.text5R and info.text6G and info.text6B then
|
|
sixth:SetTextColor(info.text6R, info.text6G, info.text6B)
|
|
else
|
|
sixth:SetTextColor(1, 0.823529, 0)
|
|
end
|
|
local a,_,b = fourth:GetFont()
|
|
sixth:SetFont(a, info.size6 * fontSizePercent, b)
|
|
sixth:SetJustifyH(info.justify6)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
check:SetWidth(info.size * fontSizePercent)
|
|
check:SetHeight(info.size * fontSizePercent)
|
|
check.width = info.size * fontSizePercent
|
|
if info.hasCheck then
|
|
check.shown = true
|
|
check:Show()
|
|
if isRadio then
|
|
check:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
|
|
if info.checked then
|
|
check:SetAlpha(1)
|
|
check:SetTexCoord(0.25, 0.5, 0, 1)
|
|
else
|
|
check:SetAlpha(self.transparency)
|
|
check:SetTexCoord(0, 0.25, 0, 1)
|
|
end
|
|
else
|
|
if info.checkIcon then
|
|
check:SetTexture(info.checkIcon)
|
|
if string.sub(info.checkIcon, 1, 16) == "Interface\\Icons\\" then
|
|
check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
|
|
else
|
|
check:SetTexCoord(0, 1, 0, 1)
|
|
end
|
|
else
|
|
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
|
check:SetWidth(info.size * fontSizePercent * 1.5)
|
|
check:SetHeight(info.size * fontSizePercent * 1.5)
|
|
check.width = info.size * fontSizePercent * 1.2
|
|
check:SetTexCoord(0, 1, 0, 1)
|
|
end
|
|
check:SetAlpha(info.checked and 1 or 0)
|
|
end
|
|
left:SetPoint("TOPLEFT", check, "TOPLEFT", check.width, 0)
|
|
else
|
|
left:SetPoint("TOPLEFT", check, "TOPLEFT")
|
|
end
|
|
if columns == 1 then
|
|
left:SetWidth(maxWidth)
|
|
elseif columns == 2 then
|
|
left:SetWidth(0)
|
|
right:SetWidth(0)
|
|
if info.wrap then
|
|
left:SetWidth(maxWidth - right:GetWidth() - 40 * fontSizePercent)
|
|
elseif info.wrap2 then
|
|
right:SetWidth(maxWidth - left:GetWidth() - 40 * fontSizePercent)
|
|
end
|
|
right:ClearAllPoints()
|
|
right:SetPoint("TOPRIGHT", button, "TOPRIGHT", 0, 0)
|
|
if not info.text2 then
|
|
left:SetJustifyH(info.justify or "LEFT")
|
|
end
|
|
elseif columns == 3 then
|
|
left:SetWidth(x1 - info.checkWidth)
|
|
right:SetWidth(x2)
|
|
third:SetWidth(x3)
|
|
right:ClearAllPoints()
|
|
local num = (category.tabletData.width - x1 - x2 - x3) / 2
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", num - info.indentation * fontSizePercent, 0)
|
|
third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
|
|
elseif columns == 4 then
|
|
left:SetWidth(x1 - info.checkWidth)
|
|
right:SetWidth(x2)
|
|
third:SetWidth(x3)
|
|
fourth:SetWidth(x4)
|
|
local num = (category.tabletData.width - x1 - x2 - x3 - x4) / 3
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", num - info.indentation * fontSizePercent, 0)
|
|
third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
|
|
fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
|
|
elseif columns == 5 then
|
|
left:SetWidth(x1 - info.checkWidth)
|
|
right:SetWidth(x2)
|
|
third:SetWidth(x3)
|
|
fourth:SetWidth(x4)
|
|
fifth:SetWidth(x5)
|
|
local num = (category.tabletData.width - x1 - x2 - x3 - x4 - x5) / 4
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", num - info.indentation * fontSizePercent, 0)
|
|
third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
|
|
fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
|
|
fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", num, 0)
|
|
elseif columns == 6 then
|
|
left:SetWidth(x1 - info.checkWidth)
|
|
right:SetWidth(x2)
|
|
third:SetWidth(x3)
|
|
fourth:SetWidth(x4)
|
|
fifth:SetWidth(x5)
|
|
sixth:SetWidth(x6)
|
|
local num = (category.tabletData.width - x1 - x2 - x3 - x4 - x5 - x6) / 5
|
|
right:SetPoint("TOPLEFT", left, "TOPRIGHT", num - info.indentation * fontSizePercent, 0)
|
|
third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
|
|
fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
|
|
fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", num, 0)
|
|
sixth:SetPoint("TOPLEFT", fifth, "TOPRIGHT", num, 0)
|
|
end
|
|
if not self.locked or IsAltKeyDown() then
|
|
local func = info.func
|
|
if func then
|
|
if type(func) == "string" then
|
|
if type(info.arg1) ~= "table" then
|
|
Tablet:error("Cannot call method " .. info.func .. " on a non-table")
|
|
end
|
|
func = info.arg1[func]
|
|
if type(func) ~= "function" then
|
|
Tablet:error("Method " .. info.func .. " nonexistant")
|
|
end
|
|
else
|
|
if type(func) ~= "function" then
|
|
Tablet:error("func must be a function or method")
|
|
end
|
|
end
|
|
button.func = func
|
|
local i = 1
|
|
while true do
|
|
if button[i] ~= nil then
|
|
button[i] = nil
|
|
else
|
|
break
|
|
end
|
|
i = i + 1
|
|
end
|
|
i = 1
|
|
while true do
|
|
local k = 'arg' .. i
|
|
local v = info[k]
|
|
if v == nil then
|
|
break
|
|
end
|
|
button[i] = v
|
|
i = i + 1
|
|
end
|
|
button.self = self
|
|
button:SetScript("OnMouseUp", button_OnMouseUp)
|
|
button:SetScript("OnMouseDown", button_OnMouseDown)
|
|
button:SetScript("OnClick", button_OnClick)
|
|
if button.clicked then
|
|
button:SetButtonState("PUSHED")
|
|
end
|
|
button:EnableMouse(true)
|
|
else
|
|
button:SetScript("OnMouseDown", nil)
|
|
button:SetScript("OnMouseUp", nil)
|
|
button:SetScript("OnClick", nil)
|
|
button:EnableMouse(false)
|
|
end
|
|
else
|
|
button:SetScript("OnMouseDown", nil)
|
|
button:SetScript("OnMouseUp", nil)
|
|
button:SetScript("OnClick", nil)
|
|
button:EnableMouse(false)
|
|
end
|
|
end
|
|
tooltip.AddLine = wrap(tooltip.AddLine, "tooltip:AddLine")
|
|
|
|
function tooltip:SetFontSizePercent(percent)
|
|
local data, detachedData = self.data, self.detachedData
|
|
if detachedData and detachedData.detached then
|
|
data = detachedData
|
|
end
|
|
local lastSize = self.fontSizePercent
|
|
percent = tonumber(percent) or 1
|
|
if percent < 0.25 then
|
|
percent = 0.25
|
|
elseif percent > 4 then
|
|
percent = 4
|
|
end
|
|
self.fontSizePercent = percent
|
|
if data then
|
|
data.fontSizePercent = percent
|
|
end
|
|
self.scrollUp:SetFont(font, normalSize * self.fontSizePercent, flags)
|
|
self.scrollDown:SetFont(font, normalSize * self.fontSizePercent, flags)
|
|
local ratio = self.fontSizePercent / lastSize
|
|
for i = 1, self.numLines do
|
|
local left = self.lefts[i]
|
|
local right = self.rights[i]
|
|
local third = self.thirds[i]
|
|
local fourth = self.fourths[i]
|
|
local fifth = self.fifths[i]
|
|
local sixth = self.sixths[i]
|
|
local check = self.checks[i]
|
|
local font, size, flags = left:GetFont()
|
|
left:SetFont(font, size * ratio, flags)
|
|
font, size, flags = right:GetFont()
|
|
right:SetFont(font, size * ratio, flags)
|
|
font, size, flags = third:GetFont()
|
|
third:SetFont(font, size * ratio, flags)
|
|
font, size, flags = fourth:GetFont()
|
|
fourth:SetFont(font, size * ratio, flags)
|
|
font, size, flags = fifth:GetFont()
|
|
fifth:SetFont(font, size * ratio, flags)
|
|
font, size, flags = sixth:GetFont()
|
|
sixth:SetFont(font, size * ratio, flags)
|
|
check.width = check.width * ratio
|
|
check:SetWidth(check:GetWidth() * ratio)
|
|
check:SetHeight(check:GetHeight() * ratio)
|
|
end
|
|
self:SetWidth((self:GetWidth() - 51) * ratio + 51)
|
|
self:SetHeight((self:GetHeight() - 51) * ratio + 51)
|
|
if self:IsShown() and self.children then
|
|
self:children()
|
|
self:Show()
|
|
end
|
|
end
|
|
tooltip.SetFontSizePercent = wrap(tooltip.SetFontSizePercent, "tooltip:SetFontSizePercent")
|
|
|
|
function tooltip:GetFontSizePercent()
|
|
return self.fontSizePercent
|
|
end
|
|
|
|
function tooltip:SetTransparency(alpha)
|
|
local data, detachedData = self.data, self.detachedData
|
|
if detachedData and detachedData.detached then
|
|
data = detachedData
|
|
end
|
|
self.transparency = alpha
|
|
if data then
|
|
data.transparency = alpha ~= 0.75 and alpha or nil
|
|
end
|
|
self:SetBackdropColor(self.r or 0, self.g or 0, self.b or 0, alpha)
|
|
self:SetBackdropBorderColor(1, 1, 1, alpha)
|
|
end
|
|
tooltip.SetTransparency = wrap(tooltip.SetTransparency, "tooltip:SetTransparency")
|
|
|
|
function tooltip:GetTransparency()
|
|
return self.transparency
|
|
end
|
|
|
|
function tooltip:SetColor(r, g, b)
|
|
local data, detachedData = self.data, self.detachedData
|
|
if detachedData and detachedData.detached then
|
|
data = detachedData
|
|
end
|
|
self.r = r
|
|
self.g = g
|
|
self.b = b
|
|
if data then
|
|
data.r = r ~= 0 and r or nil
|
|
data.g = g ~= 0 and g or nil
|
|
data.b = b ~= 0 and b or nil
|
|
end
|
|
self:SetBackdropColor(r or 0, g or 0, b or 0, self.transparency)
|
|
self:SetBackdropBorderColor(1, 1, 1, self.transparency)
|
|
end
|
|
tooltip.SetColor = wrap(tooltip.SetColor, "tooltip:SetColor")
|
|
|
|
function tooltip:GetColor()
|
|
return self.r, self.g, self.b
|
|
end
|
|
|
|
function tooltip:Scroll(down)
|
|
local maxLinesPerScreen = GetMaxLinesPerScreen(self)
|
|
if down then
|
|
if IsShiftKeyDown() then
|
|
self.scroll = self.numLines - maxLinesPerScreen
|
|
else
|
|
self.scroll = self.scroll + 3
|
|
end
|
|
else
|
|
if IsShiftKeyDown() then
|
|
self.scroll = 0
|
|
else
|
|
self.scroll = self.scroll - 3
|
|
end
|
|
end
|
|
if self.scroll > self.numLines - maxLinesPerScreen then
|
|
self.scroll = self.numLines - maxLinesPerScreen
|
|
end
|
|
if self.scroll < 0 then
|
|
self.scroll = 0
|
|
end
|
|
if self:IsShown() then
|
|
self:Show()
|
|
end
|
|
end
|
|
tooltip.Scroll = wrap(tooltip.Scroll, "tooltip:Scroll")
|
|
|
|
function tooltip.Detach(tooltip)
|
|
local owner = tooltip.owner
|
|
tooltip:Hide()
|
|
if not tooltip.detachedData then
|
|
self:error("You cannot detach if detachedData is not present")
|
|
end
|
|
tooltip.detachedData.detached = true
|
|
local detached = AcquireDetachedFrame(self, tooltip.registration, tooltip.data, tooltip.detachedData)
|
|
|
|
detached.menu, tooltip.menu = tooltip.menu, nil
|
|
detached.children = tooltip.children
|
|
tooltip.children = nil
|
|
detached:SetOwner(owner)
|
|
detached:children()
|
|
detached:Show()
|
|
end
|
|
tooltip.Detach = wrap(tooltip.Detach, "tooltip:Detach")
|
|
|
|
end
|
|
|
|
tooltip.registration = registration
|
|
registration.tooltip = tooltip
|
|
return tooltip
|
|
end
|
|
AcquireFrame = wrap(AcquireFrame, "AcquireFrame")
|
|
|
|
function ReleaseDetachedFrame(self, data, detachedData)
|
|
if not detachedData then
|
|
detachedData = data
|
|
end
|
|
for _, detached in ipairs(detachedTooltips) do
|
|
if detached.detachedData == detachedData then
|
|
detached.notInUse = true
|
|
detached:Hide()
|
|
detached.registration.tooltip = nil
|
|
detached.registration = nil
|
|
detached.detachedData = nil
|
|
end
|
|
end
|
|
end
|
|
ReleaseDetachedFrame = wrap(ReleaseDetachedFrame, "ReleaseDetachedFrame")
|
|
|
|
local StartCheckingAlt, StopCheckingAlt
|
|
do
|
|
local frame
|
|
function StartCheckingAlt(func)
|
|
if not frame then
|
|
frame = CreateFrame("Frame")
|
|
frame:SetScript("OnEvent", function(this, _, modifier)
|
|
if modifier == "ALT" then
|
|
this.func()
|
|
end
|
|
end)
|
|
end
|
|
frame:RegisterEvent("MODIFIER_STATE_CHANGED")
|
|
frame.func = func
|
|
end
|
|
function StopCheckingAlt()
|
|
if frame then
|
|
frame:UnregisterEvent("MODIFIER_STATE_CHANGED")
|
|
end
|
|
end
|
|
end
|
|
|
|
local fake_ipairs
|
|
do
|
|
local function iter(tmp, i)
|
|
i = i + 1
|
|
local x = tmp[i]
|
|
tmp[i] = nil
|
|
if x then
|
|
return i, x
|
|
end
|
|
end
|
|
|
|
local tmp = {}
|
|
function fake_ipairs(...)
|
|
for i = 1, select('#', ...) do
|
|
tmp[i] = select(i, ...)
|
|
end
|
|
return iter, tmp, 0
|
|
end
|
|
end
|
|
|
|
function AcquireDetachedFrame(self, registration, data, detachedData)
|
|
if not detachedData then
|
|
detachedData = data
|
|
end
|
|
for _, detached in ipairs(detachedTooltips) do
|
|
if detached.notInUse then
|
|
detached.data = data
|
|
detached.detachedData = detachedData
|
|
detached.notInUse = nil
|
|
local fontSizePercent = detachedData.fontSizePercent or 1
|
|
local transparency = detachedData.transparency or 0.75
|
|
local r = detachedData.r or 0
|
|
local g = detachedData.g or 0
|
|
local b = detachedData.b or 0
|
|
detached:SetFontSizePercent(fontSizePercent)
|
|
detached:SetTransparency(transparency)
|
|
detached:SetColor(r, g, b)
|
|
detached:ClearAllPoints()
|
|
detached:SetWidth(0)
|
|
detached:SetHeight(0)
|
|
if not registration.strata then
|
|
detached:SetFrameStrata("BACKGROUND")
|
|
end
|
|
if not registration.frameLevel then
|
|
detached:SetFrameLevel(10)
|
|
for _,frame in fake_ipairs(detached:GetChildren()) do
|
|
frame:SetFrameLevel(12)
|
|
end
|
|
end
|
|
detached:SetParent(registration.parent or UIParent)
|
|
if registration.strata then
|
|
detached:SetFrameStrata(registration.strata)
|
|
end
|
|
if registration.frameLevel then
|
|
detached:SetFrameLevel(registration.frameLevel)
|
|
for _,frame in fake_ipairs(detached:GetChildren()) do
|
|
frame:SetFrameLevel(registration.frameLevel+2)
|
|
end
|
|
end
|
|
detached.height_ = nil
|
|
if registration.positionFunc then
|
|
registration.positionFunc(detached)
|
|
local height = detached:GetHeight()
|
|
if height > 0 then
|
|
detached.height_ = height
|
|
else
|
|
local top, bottom
|
|
for i = 1, detached:GetNumPoints() do
|
|
local a,b,c,d,e = detached:GetPoint(i)
|
|
|
|
if a:find("^TOP") then
|
|
if c:find("^TOP") then
|
|
top = b:GetTop()
|
|
elseif c:find("^BOTTOM") then
|
|
top = b:GetBottom()
|
|
else
|
|
_,top = b:GetCenter()
|
|
end
|
|
if top then
|
|
top = top + e
|
|
end
|
|
elseif a:find("^BOTTOM") then
|
|
if c:find("^TOP") then
|
|
bottom = b:GetTop()
|
|
elseif c:find("^BOTTOM") then
|
|
bottom = b:GetBottom()
|
|
else
|
|
_,bottom = b:GetCenter()
|
|
end
|
|
if bottom then
|
|
bottom = bottom + e
|
|
end
|
|
end
|
|
end
|
|
if top and bottom then
|
|
detached.height_ = top - bottom
|
|
end
|
|
end
|
|
else
|
|
detached:SetPoint(detachedData.anchor or "CENTER", UIParent, detachedData.anchor or "CENTER", detachedData.offsetx or 0, detachedData.offsety or 0)
|
|
end
|
|
detached.registration = registration
|
|
registration.tooltip = detached
|
|
if registration.movable == false then
|
|
detached:RegisterForDrag()
|
|
else
|
|
detached:RegisterForDrag("LeftButton")
|
|
end
|
|
return detached
|
|
end
|
|
end
|
|
|
|
if not Dewdrop and AceLibrary:HasInstance("Dewdrop-2.0") then
|
|
Dewdrop = AceLibrary("Dewdrop-2.0")
|
|
end
|
|
StartCheckingAlt(function()
|
|
for _, detached in ipairs(detachedTooltips) do
|
|
if detached:IsShown() and detached.locked then
|
|
detached:EnableMouse(IsAltKeyDown())
|
|
detached:children()
|
|
if detached.moving then
|
|
local a1 = arg1
|
|
arg1 = "LeftButton"
|
|
if type(detached:GetScript("OnMouseUp")) == "function" then
|
|
detached:GetScript("OnMouseUp")(detached, arg1)
|
|
end
|
|
arg1 = a1
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
if not tooltip then
|
|
AcquireFrame(self, {})
|
|
end
|
|
local detached = CreateFrame("Frame", "Tablet20DetachedFrame" .. (#detachedTooltips + 1), UIParent)
|
|
table.insert(detachedTooltips, detached)
|
|
detached.notInUse = true
|
|
detached:EnableMouse(not data.locked)
|
|
detached:EnableMouseWheel(true)
|
|
detached:SetMovable(true)
|
|
detached:SetPoint(data.anchor or "CENTER", UIParent, data.anchor or "CENTER", data.offsetx or 0, data.offsety or 0)
|
|
|
|
detached.numLines = 0
|
|
detached.owner = nil
|
|
detached.fontSizePercent = 1
|
|
detached.maxLines = 0
|
|
detached.buttons = {}
|
|
detached.checks = {}
|
|
detached.lefts = {}
|
|
detached.rights = {}
|
|
detached.thirds = {}
|
|
detached.fourths = {}
|
|
detached.fifths = {}
|
|
detached.sixths = {}
|
|
detached.transparency = 0.75
|
|
detached.r = 0
|
|
detached.g = 0
|
|
detached.b = 0
|
|
detached:SetFrameStrata(registration.strata or "BACKGROUND")
|
|
detached:SetBackdrop(tmp.a(
|
|
'bgFile', "Interface\\Buttons\\WHITE8X8",
|
|
'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
'tile', true,
|
|
'tileSize', 16,
|
|
'edgeSize', 16,
|
|
'insets', tmp.b(
|
|
'left', 5,
|
|
'right', 5,
|
|
'top', 5,
|
|
'bottom', 5
|
|
)
|
|
))
|
|
detached.locked = detachedData.locked
|
|
detached.scroll = 0
|
|
detached:EnableMouse(not detached.locked)
|
|
|
|
local width = GetScreenWidth()
|
|
local height = GetScreenHeight()
|
|
if registration.movable == false then
|
|
detached:RegisterForDrag()
|
|
else
|
|
detached:RegisterForDrag("LeftButton")
|
|
end
|
|
detached:SetScript("OnDragStart", function()
|
|
detached:StartMoving()
|
|
detached.moving = true
|
|
end)
|
|
|
|
detached:SetScript("OnDragStop", function()
|
|
detached:StopMovingOrSizing()
|
|
detached.moving = nil
|
|
local anchor
|
|
local offsetx
|
|
local offsety
|
|
if detached:GetTop() + detached:GetBottom() < height then
|
|
anchor = "BOTTOM"
|
|
offsety = detached:GetBottom()
|
|
if offsety < 0 then
|
|
offsety = 0
|
|
end
|
|
if offsety < MainMenuBar:GetTop() and MainMenuBar:IsVisible() then
|
|
offsety = MainMenuBar:GetTop()
|
|
end
|
|
local top = 0
|
|
if FuBar then
|
|
for i = 1, FuBar:GetNumPanels() do
|
|
local panel = FuBar:GetPanel(i)
|
|
if panel:GetAttachPoint() == "BOTTOM" then
|
|
if panel.frame:GetTop() > top then
|
|
top = panel.frame:GetTop()
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if offsety < top then
|
|
offsety = top
|
|
end
|
|
else
|
|
anchor = "TOP"
|
|
offsety = detached:GetTop() - height
|
|
if offsety > 0 then
|
|
offsety = 0
|
|
end
|
|
local bottom = GetScreenHeight()
|
|
if FuBar then
|
|
for i = 1, FuBar:GetNumPanels() do
|
|
local panel = FuBar:GetPanel(i)
|
|
if panel:GetAttachPoint() == "TOP" then
|
|
if panel.frame:GetBottom() < bottom then
|
|
bottom = panel.frame:GetBottom()
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
bottom = bottom - GetScreenHeight()
|
|
if offsety > bottom then
|
|
offsety = bottom
|
|
end
|
|
end
|
|
if detached:GetLeft() + detached:GetRight() < width * 2 / 3 then
|
|
anchor = anchor .. "LEFT"
|
|
offsetx = detached:GetLeft()
|
|
if offsetx < 0 then
|
|
offsetx = 0
|
|
end
|
|
elseif detached:GetLeft() + detached:GetRight() < width * 4 / 3 then
|
|
if anchor == "" then
|
|
anchor = "CENTER"
|
|
end
|
|
offsetx = (detached:GetLeft() + detached:GetRight() - GetScreenWidth()) / 2
|
|
else
|
|
anchor = anchor .. "RIGHT"
|
|
offsetx = detached:GetRight() - width
|
|
if offsetx > 0 then
|
|
offsetx = 0
|
|
end
|
|
end
|
|
detached:ClearAllPoints()
|
|
detached:SetPoint(anchor, UIParent, anchor, offsetx, offsety)
|
|
local t = detached.detachedData
|
|
if t.anchor ~= anchor or math.abs(t.offsetx - offsetx) > 8 or math.abs(t.offsety - offsety) > 8 then
|
|
detached.preventClick = GetTime() + 0.05
|
|
end
|
|
t.anchor = anchor
|
|
t.offsetx = offsetx
|
|
t.offsety = offsety
|
|
detached:Show()
|
|
end)
|
|
|
|
if Dewdrop then
|
|
Dewdrop:Register(detached,
|
|
'children', function(level, value)
|
|
if not detached.registration then
|
|
return
|
|
end
|
|
if detached.menu then
|
|
detached.menu(level, value)
|
|
if level == 1 then
|
|
Dewdrop:AddLine()
|
|
end
|
|
end
|
|
if level == 1 then
|
|
if not detached.registration.cantAttach then
|
|
Dewdrop:AddLine(
|
|
'text', DETACH,
|
|
'tooltipTitle', DETACH,
|
|
'tooltipText', DETACH_DESC,
|
|
'checked', true,
|
|
'arg1', detached,
|
|
'func', "Attach",
|
|
'closeWhenClicked', true
|
|
)
|
|
end
|
|
Dewdrop:AddLine(
|
|
'text', LOCK,
|
|
'tooltipTitle', LOCK,
|
|
'tooltipText', LOCK_DESC,
|
|
'checked', detached:IsLocked(),
|
|
'arg1', detached,
|
|
'func', "Lock",
|
|
'closeWhenClicked', not detached:IsLocked()
|
|
)
|
|
Dewdrop:AddLine(
|
|
'text', COLOR,
|
|
'tooltipTitle', COLOR,
|
|
'tooltipText', COLOR_DESC,
|
|
'hasColorSwatch', true,
|
|
'r', detached.r,
|
|
'g', detached.g,
|
|
'b', detached.b,
|
|
'hasOpacity', true,
|
|
'opacity', detached.transparency,
|
|
'colorFunc', function(r, g, b, a)
|
|
detached:SetColor(r, g, b)
|
|
detached:SetTransparency(a)
|
|
end
|
|
)
|
|
Dewdrop:AddLine(
|
|
'text', SIZE,
|
|
'tooltipTitle', SIZE,
|
|
'tooltipText', SIZE_DESC,
|
|
'hasArrow', true,
|
|
'hasSlider', true,
|
|
'sliderFunc', function(value)
|
|
detached:SetFontSizePercent(value)
|
|
end,
|
|
'sliderMax', 2,
|
|
'sliderMin', 0.5,
|
|
'sliderStep', 0.05,
|
|
'sliderIsPercent', true,
|
|
'sliderValue', detached:GetFontSizePercent()
|
|
)
|
|
Dewdrop:AddLine(
|
|
'text', CLOSE_MENU,
|
|
'tooltipTitle', CLOSE_MENU,
|
|
'tooltipText', CLOSE_MENU_DESC,
|
|
'func', function()
|
|
Dewdrop:Close()
|
|
end
|
|
)
|
|
end
|
|
end,
|
|
'point', function()
|
|
local x, y = detached:GetCenter()
|
|
if x < GetScreenWidth() / 2 then
|
|
if y < GetScreenHeight() / 2 then
|
|
return "BOTTOMLEFT", "BOTTOMRIGHT"
|
|
else
|
|
return "TOPLEFT", "TOPRIGHT"
|
|
end
|
|
else
|
|
if y < GetScreenHeight() / 2 then
|
|
return "BOTTOMRIGHT", "BOTTOMLEFT"
|
|
else
|
|
return "TOPRIGHT", "TOPLEFT"
|
|
end
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
NewLine(detached)
|
|
|
|
detached.scrollUp = detached:CreateFontString(nil, "ARTWORK")
|
|
detached.scrollUp:SetPoint("TOPLEFT", detached.buttons[1], "BOTTOMLEFT", 0, -2)
|
|
detached.scrollUp:SetPoint("RIGHT", detached, "RIGHT", 0, -10)
|
|
detached.scrollUp:SetFontObject(GameTooltipText)
|
|
detached.scrollUp:Hide()
|
|
local font,_,flags = detached.scrollUp:GetFont()
|
|
detached.scrollUp:SetFont(font, normalSize * detached.fontSizePercent, flags)
|
|
detached.scrollUp:SetJustifyH("CENTER")
|
|
detached.scrollUp:SetTextColor(1, 0.823529, 0)
|
|
detached.scrollUp:SetText(" ")
|
|
|
|
detached.scrollDown = detached:CreateFontString(nil, "ARTWORK")
|
|
detached.scrollDown:SetPoint("TOPLEFT", detached.buttons[1], "BOTTOMLEFT", 0, -2)
|
|
detached.scrollDown:SetPoint("RIGHT", detached, "RIGHT", 0, -10)
|
|
detached.scrollDown:SetFontObject(GameTooltipText)
|
|
detached.scrollDown:Hide()
|
|
local font,_,flags = detached.scrollUp:GetFont()
|
|
detached.scrollDown:SetFont(font, normalSize * detached.fontSizePercent, flags)
|
|
detached.scrollDown:SetJustifyH("CENTER")
|
|
detached.scrollDown:SetTextColor(1, 0.823529, 0)
|
|
detached.scrollDown:SetText(" ")
|
|
|
|
detached:SetScript("OnMouseWheel", function()
|
|
detached:Scroll(arg1 < 0)
|
|
end)
|
|
|
|
detached.SetTransparency = tooltip.SetTransparency
|
|
detached.GetTransparency = tooltip.GetTransparency
|
|
detached.SetColor = tooltip.SetColor
|
|
detached.GetColor = tooltip.GetColor
|
|
detached.SetFontSizePercent = tooltip.SetFontSizePercent
|
|
detached.GetFontSizePercent = tooltip.GetFontSizePercent
|
|
detached.SetOwner = tooltip.SetOwner
|
|
detached.IsOwned = tooltip.IsOwned
|
|
detached.ClearLines = tooltip.ClearLines
|
|
detached.NumLines = tooltip.NumLines
|
|
detached.__Hide = detached.Hide
|
|
detached.__Show = detached.Show
|
|
detached.Hide = tooltip.Hide
|
|
detached.Show = tooltip.Show
|
|
local old_IsShown = detached.IsShown
|
|
function detached:IsShown()
|
|
if self.tmpHidden then
|
|
return true
|
|
else
|
|
return old_IsShown(self)
|
|
end
|
|
end
|
|
detached.AddLine = tooltip.AddLine
|
|
detached.Scroll = tooltip.Scroll
|
|
function detached:IsLocked()
|
|
return self.locked
|
|
end
|
|
function detached:Lock()
|
|
self:EnableMouse(self.locked)
|
|
self.locked = not self.locked
|
|
self.detachedData.locked = self.locked or nil
|
|
self:children()
|
|
end
|
|
|
|
function detached.Attach(detached)
|
|
if not detached then
|
|
self:error("Detached tooltip not given.")
|
|
end
|
|
if not detached.AddLine then
|
|
self:error("detached argument not a Tooltip.")
|
|
end
|
|
if not detached.owner then
|
|
self:error("Detached tooltip has no owner.")
|
|
end
|
|
if detached.notInUse then
|
|
self:error("Detached tooltip not in use.")
|
|
end
|
|
detached.menu = nil
|
|
detached.detachedData.detached = nil
|
|
detached:SetOwner(nil)
|
|
detached.notInUse = true
|
|
end
|
|
|
|
return AcquireDetachedFrame(self, registration, data, detachedData)
|
|
end
|
|
AcquireDetachedFrame = wrap(AcquireDetachedFrame, "AcquireDetachedFrame")
|
|
|
|
function Tablet:Close(parent)
|
|
if not parent then
|
|
if tooltip and tooltip:IsShown() then
|
|
tooltip:Hide()
|
|
tooltip.registration.tooltip = nil
|
|
tooltip.registration = nil
|
|
tooltip.enteredFrame = false
|
|
end
|
|
return
|
|
else
|
|
self:argCheck(parent, 2, "table", "string")
|
|
end
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot close a tablet with an unregistered parent frame.")
|
|
end
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData and detachedData.detached then
|
|
ReleaseDetachedFrame(self, data, detachedData)
|
|
elseif tooltip.data == data then
|
|
tooltip:Hide()
|
|
tooltip.registration.tooltip = nil
|
|
tooltip.registration = nil
|
|
end
|
|
tooltip.enteredFrame = false
|
|
end
|
|
Tablet.Close = wrap(Tablet.Close, "Tablet:Close")
|
|
|
|
local currentFrame
|
|
local currentTabletData
|
|
|
|
function Tablet:Open(fakeParent, parent)
|
|
self:argCheck(fakeParent, 2, "table", "string")
|
|
self:argCheck(parent, 3, "nil", "table", "string")
|
|
if not parent then
|
|
parent = fakeParent
|
|
end
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot open a tablet with an unregistered parent frame.")
|
|
end
|
|
local detachedData = info.detachedData
|
|
if detachedData then
|
|
for _, detached in ipairs(detachedTooltips) do
|
|
if not detached.notInUse and detached.detachedData == detachedData then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
-- self:Close(fakeParent)
|
|
local data = info.data
|
|
local children = info.children
|
|
if not children then
|
|
return
|
|
end
|
|
local frame = AcquireFrame(self, info, data, detachedData)
|
|
frame.clickable = info.clickable
|
|
frame.menu = info.menu
|
|
local children = info.children
|
|
function frame:children()
|
|
if not self.preventRefresh and self:GetParent():IsVisible() then
|
|
currentFrame = self
|
|
currentTabletData = TabletData:new(self)
|
|
-- if info.width then
|
|
-- currentTabletData.width = info.width
|
|
-- end
|
|
self:ClearLines()
|
|
if children then
|
|
children()
|
|
end
|
|
currentTabletData:Display(currentFrame)
|
|
self:Show(currentTabletData)
|
|
currentTabletData:del()
|
|
currentTabletData = nil
|
|
currentFrame = nil
|
|
end
|
|
end
|
|
frame:SetOwner(fakeParent)
|
|
frame:children()
|
|
local point = info.point
|
|
local relativePoint = info.relativePoint
|
|
if type(point) == "function" then
|
|
local b
|
|
point, b = point(fakeParent)
|
|
if b then
|
|
relativePoint = b
|
|
end
|
|
end
|
|
if type(relativePoint) == "function" then
|
|
relativePoint = relativePoint(fakeParent)
|
|
end
|
|
if not point then
|
|
point = "CENTER"
|
|
end
|
|
if not relativePoint then
|
|
relativePoint = point
|
|
end
|
|
frame:ClearAllPoints()
|
|
if type(parent) ~= "string" then
|
|
frame:SetPoint(point, fakeParent, relativePoint)
|
|
end
|
|
local offsetx = 0
|
|
local offsety = 0
|
|
if frame:GetBottom() and frame:GetLeft() then
|
|
if frame:GetRight() > GetScreenWidth() then
|
|
offsetx = frame:GetRight() - GetScreenWidth()
|
|
elseif frame:GetLeft() < 0 then
|
|
offsetx = -frame:GetLeft()
|
|
end
|
|
local ratio = GetScreenWidth() / GetScreenHeight()
|
|
if ratio >= 2.4 and frame:GetRight() > GetScreenWidth() / 2 and frame:GetLeft() < GetScreenWidth() / 2 then
|
|
if frame:GetCenter() < GetScreenWidth() / 2 then
|
|
offsetx = frame:GetRight() - GetScreenWidth() / 2
|
|
else
|
|
offsetx = frame:GetLeft() - GetScreenWidth() / 2
|
|
end
|
|
end
|
|
if frame:GetBottom() < 0 then
|
|
offsety = frame:GetBottom()
|
|
elseif frame:GetTop() and frame:GetTop() > GetScreenHeight() then
|
|
offsety = frame:GetTop() - GetScreenHeight()
|
|
end
|
|
if MainMenuBar:IsVisible() and frame:GetBottom() < MainMenuBar:GetTop() and offsety < frame:GetBottom() - MainMenuBar:GetTop() then
|
|
offsety = frame:GetBottom() - MainMenuBar:GetTop()
|
|
end
|
|
|
|
if FuBar then
|
|
local top = 0
|
|
if FuBar then
|
|
for i = 1, FuBar:GetNumPanels() do
|
|
local panel = FuBar:GetPanel(i)
|
|
if panel:GetAttachPoint() == "BOTTOM" then
|
|
if panel.frame:GetTop() and panel.frame:GetTop() > top then
|
|
top = panel.frame:GetTop()
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if frame:GetBottom() < top and offsety < frame:GetBottom() - top then
|
|
offsety = frame:GetBottom() - top
|
|
end
|
|
local bottom = GetScreenHeight()
|
|
if FuBar then
|
|
for i = 1, FuBar:GetNumPanels() do
|
|
local panel = FuBar:GetPanel(i)
|
|
if panel:GetAttachPoint() == "TOP" then
|
|
if panel.frame:GetBottom() and panel.frame:GetBottom() < bottom then
|
|
bottom = panel.frame:GetBottom()
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if frame:GetTop() > bottom and offsety < frame:GetTop() - bottom then
|
|
offsety = frame:GetTop() - bottom
|
|
end
|
|
end
|
|
end
|
|
if type(fakeParent) ~= "string" then
|
|
frame:SetPoint(point, fakeParent, relativePoint, -offsetx, -offsety)
|
|
end
|
|
|
|
if detachedData and (info.cantAttach or detachedData.detached) and frame == tooltip then
|
|
detachedData.detached = false
|
|
frame:Detach()
|
|
end
|
|
if (not detachedData or not detachedData.detached) and GetMouseFocus() == fakeParent then
|
|
self.tooltip.enteredFrame = true
|
|
end
|
|
overFrame = type(fakeParent) == "table" and MouseIsOver(fakeParent) and fakeParent
|
|
end
|
|
Tablet.Open = wrap(Tablet.Open, "Tablet:Open")
|
|
|
|
function Tablet:Register(parent, ...)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
if self.registry[parent] then
|
|
self:Unregister(parent)
|
|
end
|
|
local info
|
|
local k1 = ...
|
|
if type(k1) == "table" and k1[0] then
|
|
if type(self.registry[k1]) ~= "table" then
|
|
self:error("Other parent not registered")
|
|
end
|
|
info = copy(self.registry[k1])
|
|
local v1 = select(2, ...)
|
|
if type(v1) == "function" then
|
|
info.point = v1
|
|
info.relativePoint = nil
|
|
end
|
|
else
|
|
info = new(...)
|
|
end
|
|
self.registry[parent] = info
|
|
info.data = info.data or info.detachedData or {}
|
|
info.detachedData = info.detachedData or info.data
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if not self.onceRegistered[parent] and type(parent) == "table" and type(parent.SetScript) == "function" and not info.dontHook then
|
|
if not Dewdrop and AceLibrary:HasInstance("Dewdrop-2.0") then
|
|
Dewdrop = AceLibrary("Dewdrop-2.0")
|
|
end
|
|
local script = parent:GetScript("OnEnter")
|
|
parent:SetScript("OnEnter", function(...)
|
|
if script then
|
|
script(...)
|
|
end
|
|
if self.registry[parent] then
|
|
if (not data or not detachedData.detached) and (Dewdrop and not Dewdrop:IsOpen(parent)) then
|
|
self:Open(parent)
|
|
end
|
|
end
|
|
end)
|
|
if parent:HasScript("OnMouseDown") then
|
|
local script = parent:GetScript("OnMouseDown")
|
|
parent:SetScript("OnMouseDown", function(...)
|
|
if script then
|
|
script(...)
|
|
end
|
|
if self.registry[parent] and self.registry[parent].tooltip and self.registry[parent].tooltip == self.tooltip then
|
|
self.tooltip:Hide()
|
|
end
|
|
end)
|
|
end
|
|
if parent:HasScript("OnMouseWheel") then
|
|
local script = parent:GetScript("OnMouseWheel")
|
|
parent:SetScript("OnMouseWheel", function(...)
|
|
if script then
|
|
script(...)
|
|
end
|
|
if self.registry[parent] and self.registry[parent].tooltip then
|
|
self.registry[parent].tooltip:Scroll(arg1 < 0)
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
self.onceRegistered[parent] = true
|
|
if GetMouseFocus() == parent then
|
|
self:Open(parent)
|
|
end
|
|
end
|
|
Tablet.Register = wrap(Tablet.Register, "Tablet:Register")
|
|
|
|
function Tablet:Unregister(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
if not self.registry[parent] then
|
|
self:error("You cannot unregister a parent frame if it has not been registered already.")
|
|
end
|
|
self.registry[parent] = nil
|
|
end
|
|
Tablet.Unregister = wrap(Tablet.Unregister, "Tablet:Unregister")
|
|
|
|
function Tablet:IsRegistered(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
return self.registry[parent] and true
|
|
end
|
|
Tablet.IsRegistered = wrap(Tablet.IsRegistered, "Tablet:IsRegistered")
|
|
|
|
local _id = 0
|
|
local addedCategory
|
|
local currentCategoryInfo
|
|
local depth = 0
|
|
local categoryPool = {}
|
|
function CleanCategoryPool(self)
|
|
for k,v in pairs(categoryPool) do
|
|
del(v)
|
|
categoryPool[k] = nil
|
|
end
|
|
_id = 0
|
|
end
|
|
|
|
function Tablet:AddCategory(...)
|
|
if not currentFrame then
|
|
self:error("You must add categories in within a registration.")
|
|
end
|
|
local info = new(...)
|
|
local cat = currentTabletData:AddCategory(info)
|
|
info = del(info)
|
|
return cat
|
|
end
|
|
Tablet.AddCategory = wrap(Tablet.AddCategory, "Tablet:AddCategory")
|
|
|
|
function Tablet:SetHint(text)
|
|
if not currentFrame then
|
|
self:error("You must set hint within a registration.")
|
|
end
|
|
if currentCategoryInfo then
|
|
self:error("You cannot set hint in a category.")
|
|
end
|
|
currentTabletData:SetHint(text)
|
|
end
|
|
Tablet.SetHint = wrap(Tablet.SetHint, "Tablet:SetHint")
|
|
|
|
function Tablet:SetTitle(text)
|
|
if not currentFrame then
|
|
self:error("You must set title within a registration.")
|
|
end
|
|
if currentCategoryInfo then
|
|
self:error("You cannot set title in a category.")
|
|
end
|
|
currentTabletData:SetTitle(text)
|
|
end
|
|
Tablet.SetTitle = wrap(Tablet.SetTitle, "Tablet:SetTitle")
|
|
|
|
function Tablet:SetTitleColor(r, g, b)
|
|
if not currentFrame then
|
|
self:error("You must set title color within a registration.")
|
|
end
|
|
if currentCategoryInfo then
|
|
self:error("You cannot set title color in a category.")
|
|
end
|
|
self:argCheck(r, 2, "number")
|
|
self:argCheck(g, 3, "number")
|
|
self:argCheck(b, 4, "number")
|
|
currentTabletData:SetTitleColor(r, g, b)
|
|
end
|
|
Tablet.SetTitleColor = wrap(Tablet.SetTitleColor, "Tablet:SetTitleColor")
|
|
|
|
function Tablet:GetNormalFontSize()
|
|
return normalSize
|
|
end
|
|
|
|
function Tablet:GetHeaderFontSize()
|
|
return headerSize
|
|
end
|
|
|
|
function Tablet:GetNormalFontObject()
|
|
return GameTooltipText
|
|
end
|
|
|
|
function Tablet:GetHeaderFontObject()
|
|
return GameTooltipHeaderText
|
|
end
|
|
|
|
function Tablet:SetFontSizePercent(parent, percent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
if info.tooltip then
|
|
info.tooltip:SetFontSizePercent(percent)
|
|
else
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
detachedData.fontSizePercent = percent
|
|
else
|
|
data.fontSizePercent = percent
|
|
end
|
|
end
|
|
elseif type(parent) == "table" then
|
|
parent.fontSizePercent = percent
|
|
else
|
|
self:error("You cannot change font size with an unregistered parent frame.")
|
|
end
|
|
end
|
|
Tablet.SetFontSizePercent = wrap(Tablet.SetFontSizePercent, "Tablet:SetFontSizePercent")
|
|
|
|
function Tablet:GetFontSizePercent(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
return detachedData.fontSizePercent or 1
|
|
else
|
|
return data.fontSizePercent or 1
|
|
end
|
|
elseif type(parent) == "table" then
|
|
return parent.fontSizePercent or 1
|
|
else
|
|
self:error("You cannot check font size with an unregistered parent frame.")
|
|
end
|
|
end
|
|
Tablet.GetFontSizePercent = wrap(Tablet.GetFontSizePercent, "Tablet:GetFontSizePercent")
|
|
|
|
function Tablet:SetTransparency(parent, percent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
if info.tooltip then
|
|
info.tooltip:SetTransparency(percent)
|
|
else
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
detachedData.transparency = percent
|
|
elseif data then
|
|
data.transparency = percent
|
|
end
|
|
end
|
|
elseif type(parent) == "table" then
|
|
parent.transparency = percent
|
|
else
|
|
self:error("You cannot change transparency with an unregistered parent frame.")
|
|
end
|
|
end
|
|
Tablet.SetTransparency = wrap(Tablet.SetTransparency, "Tablet:SetTransparency")
|
|
|
|
function Tablet:GetTransparency(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
return detachedData.transparency or 0.75
|
|
else
|
|
return data.transparency or 0.75
|
|
end
|
|
elseif type(parent) == "table" then
|
|
return parent.transparency or 0.75
|
|
else
|
|
self:error("You cannot get transparency with an unregistered parent frame.")
|
|
end
|
|
end
|
|
Tablet.GetTransparency = wrap(Tablet.GetTransparency, "Tablet:GetTransparency")
|
|
|
|
function Tablet:SetColor(parent, r, g, b)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
if info.tooltip then
|
|
info.tooltip:SetColor(r, g, b)
|
|
else
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
detachedData.r = r
|
|
detachedData.g = g
|
|
detachedData.b = b
|
|
else
|
|
data.r = r
|
|
data.g = g
|
|
data.b = b
|
|
end
|
|
end
|
|
elseif type(parent) == "table" then
|
|
parent.r = r
|
|
parent.g = g
|
|
parent.b = b
|
|
else
|
|
self:error("You cannot change color with an unregistered parent frame.")
|
|
end
|
|
end
|
|
Tablet.SetColor = wrap(Tablet.SetColor, "Tablet:SetColor")
|
|
|
|
function Tablet:GetColor(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if info then
|
|
local data = info.data
|
|
local detachedData = info.detachedData
|
|
if detachedData.detached then
|
|
return detachedData.r or 0, detachedData.g or 0, detachedData.b or 0
|
|
else
|
|
return data.r or 0, data.g or 0, data.b or 0
|
|
end
|
|
elseif type(parent) == "table" then
|
|
return parent.r or 0, parent.g or 0, parent.b or 0
|
|
else
|
|
self:error("You must provide a registered parent frame to check color")
|
|
end
|
|
end
|
|
Tablet.GetColor = wrap(Tablet.GetColor, "Tablet:GetColor")
|
|
|
|
function Tablet:Detach(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot detach tablet with an unregistered parent frame.")
|
|
end
|
|
if not info.detachedData then
|
|
self:error("You cannot detach tablet without a data field.")
|
|
end
|
|
if info.tooltip and info.tooltip == tooltip then
|
|
tooltip:Detach()
|
|
else
|
|
info.detachedData.detached = true
|
|
local detached = AcquireDetachedFrame(self, info, info.data, info.detachedData)
|
|
|
|
detached.menu = info.menu
|
|
local children = info.children
|
|
function detached:children()
|
|
if not self.preventRefresh then
|
|
currentFrame = self
|
|
currentTabletData = TabletData:new(self)
|
|
self:ClearLines()
|
|
if children then
|
|
children()
|
|
end
|
|
currentTabletData:Display(currentFrame)
|
|
self:Show(currentTabletData)
|
|
currentTabletData:del()
|
|
currentTabletData = nil
|
|
currentFrame = nil
|
|
end
|
|
end
|
|
detached:SetOwner(parent)
|
|
detached:children()
|
|
end
|
|
end
|
|
Tablet.Detach = wrap(Tablet.Detach, "Tablet:Detach")
|
|
|
|
function Tablet:Attach(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot detach tablet with an unregistered parent frame.")
|
|
end
|
|
if not info.detachedData then
|
|
self:error("You cannot attach tablet without a data field.")
|
|
end
|
|
if info.tooltip and info.tooltip ~= tooltip then
|
|
info.tooltip:Attach()
|
|
else
|
|
info.detachedData.detached = false
|
|
end
|
|
end
|
|
Tablet.Attach = wrap(Tablet.Attach, "Tablet:Attach")
|
|
|
|
function Tablet:IsAttached(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot check tablet with an unregistered parent frame.")
|
|
end
|
|
return not info.detachedData or not info.detachedData.detached
|
|
end
|
|
Tablet.IsAttached = wrap(Tablet.IsAttached, "Tablet:IsAttached")
|
|
|
|
function Tablet:Refresh(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot refresh tablet with an unregistered parent frame.")
|
|
end
|
|
local tt = info.tooltip
|
|
if tt and not tt.preventRefresh and tt:IsShown() then
|
|
tt.updating = true
|
|
tt:children()
|
|
tt.updating = false
|
|
end
|
|
end
|
|
Tablet.Refresh = wrap(Tablet.Refresh, "Tablet:Refresh")
|
|
|
|
function Tablet:IsLocked(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot check tablet with an unregistered parent frame.")
|
|
end
|
|
return info.detachedData and info.detachedData.locked
|
|
end
|
|
Tablet.IsLocked = wrap(Tablet.IsLocked, "Tablet:IsLocked")
|
|
|
|
function Tablet:ToggleLocked(parent)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot lock tablet with an unregistered parent frame.")
|
|
end
|
|
if info.tooltip and info.tooltip ~= tooltip then
|
|
info.tooltip:Lock()
|
|
elseif info.detachedData then
|
|
info.detachedData.locked = info.detachedData.locked
|
|
end
|
|
end
|
|
Tablet.ToggleLocked = wrap(Tablet.ToggleLocked, "Tablet:ToggleLocked")
|
|
|
|
function Tablet:UpdateDetachedData(parent, detachedData)
|
|
self:argCheck(parent, 2, "table", "string")
|
|
local info = self.registry[parent]
|
|
if not info then
|
|
self:error("You cannot update tablet with an unregistered parent frame.")
|
|
end
|
|
self:argCheck(detachedData, 3, "table")
|
|
if info.data == info.detachedData then
|
|
info.data = detachedData
|
|
end
|
|
info.detachedData = detachedData
|
|
if info.detachedData.detached then
|
|
self:Detach(parent)
|
|
elseif info.tooltip and info.tooltip.owner then
|
|
self:Attach(parent)
|
|
end
|
|
end
|
|
Tablet.UpdateDetachedData = wrap(Tablet.UpdateDetachedData, "Tablet:UpdateDetachedData")
|
|
|
|
if DEBUG then
|
|
function Tablet:ListProfileInfo()
|
|
local duration, times, memories = GetProfileInfo()
|
|
self:assert(duration and times and memories)
|
|
local t = new()
|
|
for method in pairs(memories) do
|
|
table.insert(t, method)
|
|
end
|
|
table.sort(t, function(alpha, bravo)
|
|
if memories[alpha] ~= memories[bravo] then
|
|
return memories[alpha] < memories[bravo]
|
|
elseif times[alpha] ~= times[bravo] then
|
|
return times[alpha] < times[bravo]
|
|
else
|
|
return alpha < bravo
|
|
end
|
|
end)
|
|
local memory = 0
|
|
local time = 0
|
|
for _,method in ipairs(t) do
|
|
DEFAULT_CHAT_FRAME:AddMessage(format("%s || %.3f s || %.3f%% || %d KiB", method, times[method], times[method] / duration * 100, memories[method]))
|
|
memory = memory + memories[method]
|
|
time = time + times[method]
|
|
end
|
|
DEFAULT_CHAT_FRAME:AddMessage(format("%s || %.3f s || %.3f%% || %d KiB", "Total", time, time / duration * 100, memory))
|
|
del(t)
|
|
end
|
|
SLASH_TABLET1 = "/tablet"
|
|
SLASH_TABLET2 = "/tabletlib"
|
|
SlashCmdList["TABLET"] = function(msg)
|
|
TabletLib:GetInstance(MAJOR_VERSION):ListProfileInfo()
|
|
end
|
|
end
|
|
|
|
local function activate(self, oldLib, oldDeactivate)
|
|
Tablet = self
|
|
if oldLib then
|
|
self.registry = oldLib.registry
|
|
self.onceRegistered = oldLib.onceRegistered
|
|
self.tooltip = oldLib.tooltip
|
|
else
|
|
self.registry = {}
|
|
self.onceRegistered = {}
|
|
end
|
|
|
|
tooltip = self.tooltip
|
|
|
|
if oldDeactivate then
|
|
oldDeactivate(oldLib)
|
|
end
|
|
end
|
|
|
|
local function deactivate(self)
|
|
StopCheckingAlt()
|
|
end
|
|
|
|
AceLibrary:Register(Tablet, MAJOR_VERSION, MINOR_VERSION, activate, deactivate)
|