WoWInterface SVN NeedyGreedy

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

RollWatcher.lua
137,10 → 137,10
end
 
function RollWatcher:ToggleDisplay()
if report:IsShown() then
report:Hide()
if self.tooltip then
self:HideReportFrame()
else
report:Show()
self:ShowReportFrame()
end
end
 
371,6 → 371,11
report:RegisterForDrag("LeftButton")
report:SetScript("OnDragStart", function() this:StartMoving() end)
report:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
 
-- QTip Shiz
report:SetScript('OnEnter', anchor_OnEnter)
report:SetScript('OnLeave', anchor_OnLeave)
 
report:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", tile = true, tileSize = 16,
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16,
809,3 → 814,60
function RollWatcher:SetDisplayIcons(info, displayIcons)
self.db.profile.displayIcons = displayIcons
end
 
 
-- Detachable QTip Frames
local LibQTip = LibStub('LibQTip-1.0')
 
function RollWatcher:ShowReportFrame()
 
-- Acquire a tooltip with 3 columns, respectively aligned to left, center and right
self.tooltip = LibQTip:Acquire("FooBarTooltip", 3, "LEFT", "CENTER", "RIGHT")
 
-- Add an header filling only the first two columns
self.tooltip:AddHeader('Anchor', 'Tooltip')
 
-- Add an new line, using all columns
self.tooltip:AddLine('Hello', 'World', 'Bob!')
 
-- To make tooltip detached
self.tooltip:ClearAllPoints()
self.tooltip:SetFrameStrata("FULLSCREEN")
self.tooltip:EnableMouse(true)
self.tooltip:SetResizable(true)
self.tooltip:SetFrameLevel(1)
self.tooltip:SetMovable(true)
self.tooltip:SetClampedToScreen(true)
 
if not self.db.profile.reportFramePos then
self.db.profile.reportFramePos = {
anchor1 = "CENTER",
anchor2 = "CENTER",
x = 0,
y = 0
}
end
self.tooltip:SetPoint(self.db.profile.reportFramePos.anchor1, nil, self.db.profile.reportFramePos.anchor2, self.db.profile.reportFramePos.x, self.db.profile.reportFramePos.y)
 
-- Make it move !
self.tooltip:SetScript("OnMouseDown", function() self.tooltip:StartMoving() end)
self.tooltip:SetScript("OnMouseUp", function()
self.tooltip:StopMovingOrSizing()
local anchor1, _, anchor2, x, y = self.tooltip:GetPoint()
self.db.profile.reportFramePos.anchor1 = anchor1
self.db.profile.reportFramePos.anchor2 = anchor2
self.db.profile.reportFramePos.x = x
self.db.profile.reportFramePos.y = y
end)
 
-- Make it remember
 
-- Show it, et voilà !
self.tooltip:Show()
end
 
function RollWatcher:HideReportFrame()
self.tooltip:Hide()
LibQTip:Release(self.tooltip)
self.tooltip = nil
end
\ No newline at end of file
libs/LibQTip-1.0/LICENSE.txt New file
0,0 → 1,29
Copyright (c) 2008, LibQTip Development Team
 
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Redistribution of a stand alone version is strictly prohibited without
prior written authorization from the Lead of the LibQTip Development Team.
* Neither the name of the LibQTip Development Team nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
libs/LibQTip-1.0/LibQTip-1.0.lua New file
0,0 → 1,1056
local MAJOR = "LibQTip-1.0"
local MINOR = 30 -- Should be manually increased
assert(LibStub, MAJOR.." requires LibStub")
 
local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not lib then return end -- No upgrade needed
 
------------------------------------------------------------------------------
-- Upvalued globals
------------------------------------------------------------------------------
local type = type
local select = select
local error = error
local pairs, ipairs = pairs, ipairs
local tonumber, tostring = tonumber, tostring
local strfind = string.find
local math = math
local min, max = math.min, math.max
local setmetatable = setmetatable
local tinsert, tremove = tinsert, tremove
local wipe = wipe
 
local CreateFrame = CreateFrame
local UIParent = UIParent
 
------------------------------------------------------------------------------
-- Tables and locals
------------------------------------------------------------------------------
lib.frameMetatable = lib.frameMetatable or {__index = CreateFrame("Frame")}
 
lib.tipPrototype = lib.tipPrototype or setmetatable({}, lib.frameMetatable)
lib.tipMetatable = lib.tipMetatable or {__index = lib.tipPrototype}
 
lib.providerPrototype = lib.providerPrototype or {}
lib.providerMetatable = lib.providerMetatable or {__index = lib.providerPrototype}
 
lib.cellPrototype = lib.cellPrototype or setmetatable({}, lib.frameMetatable)
lib.cellMetatable = lib.cellMetatable or { __index = lib.cellPrototype }
 
lib.activeTooltips = lib.activeTooltips or {}
 
lib.tooltipHeap = lib.tooltipHeap or {}
lib.frameHeap = lib.frameHeap or {}
lib.tableHeap = lib.tableHeap or {}
 
local tipPrototype = lib.tipPrototype
local tipMetatable = lib.tipMetatable
 
local providerPrototype = lib.providerPrototype
local providerMetatable = lib.providerMetatable
 
local cellPrototype = lib.cellPrototype
local cellMetatable = lib.cellMetatable
 
local activeTooltips = lib.activeTooltips
 
------------------------------------------------------------------------------
-- Private methods for Caches and Tooltip
------------------------------------------------------------------------------
local AcquireTooltip, ReleaseTooltip
local AcquireCell, ReleaseCell
local AcquireTable, ReleaseTable
 
local InitializeTooltip, SetTooltipSize, ResetTooltipSize, LayoutColspans
local SetFrameScript, ClearFrameScripts
 
------------------------------------------------------------------------------
-- Cache debugging.
------------------------------------------------------------------------------
--[===[@debug@
local usedTables, usedFrames, usedTooltips = 0, 0, 0
--@end-debug@]===]
 
------------------------------------------------------------------------------
-- Internal constants to tweak the layout
------------------------------------------------------------------------------
local TOOLTIP_PADDING = 10
local CELL_MARGIN_H = 6
local CELL_MARGIN_V = 3
 
------------------------------------------------------------------------------
-- Public library API
------------------------------------------------------------------------------
--- Create or retrieve the tooltip with the given key.
-- If additional arguments are passed, they are passed to :SetColumnLayout for the acquired tooltip.
-- @name LibQTip:Acquire(key[, numColumns, column1Justification, column2justification, ...])
-- @param key string or table - the tooltip key. Any value that can be used as a table key is accepted though you should try to provide unique keys to avoid conflicts.
-- Numbers and booleans should be avoided and strings should be carefully chosen to avoid namespace clashes - no "MyTooltip" - you have been warned!
-- @return tooltip Frame object - the acquired tooltip.
-- @usage Acquire a tooltip with at least 5 columns, justification : left, center, left, left, left
-- <pre>local tip = LibStub('LibQTip-1.0'):Acquire('MyFooBarTooltip', 5, "LEFT", "CENTER")</pre>
function lib:Acquire(key, ...)
if key == nil then error("attempt to use a nil key", 2) end
local tooltip = activeTooltips[key]
if not tooltip then
tooltip = AcquireTooltip()
InitializeTooltip(tooltip, key)
activeTooltips[key] = tooltip
end
if select('#', ...) > 0 then
-- Here we catch any error to properly report it for the calling code
local ok, msg = pcall(tooltip.SetColumnLayout, tooltip, ...)
if not ok then error(msg, 2) end
end
return tooltip
end
 
function lib:Release(tooltip)
local key = tooltip and tooltip.key
if not key or activeTooltips[key] ~= tooltip then return end
ReleaseTooltip(tooltip)
activeTooltips[key] = nil
end
 
function lib:IsAcquired(key)
if key == nil then error("attempt to use a nil key", 2) end
return not not activeTooltips[key]
end
 
function lib:IterateTooltips()
return pairs(activeTooltips)
end
 
------------------------------------------------------------------------------
-- Frame cache
------------------------------------------------------------------------------
local frameHeap = lib.frameHeap
 
local function AcquireFrame(parent)
local frame = tremove(frameHeap) or CreateFrame("Frame")
frame:SetParent(parent)
--[===[@debug@
usedFrames = usedFrames + 1
--@end-debug@]===]
return frame
end
 
local function ReleaseFrame(frame)
frame:Hide()
frame:SetParent(nil)
frame:ClearAllPoints()
frame:SetBackdrop(nil)
ClearFrameScripts(frame)
tinsert(frameHeap, frame)
--[===[@debug@
usedFrames = usedFrames - 1
--@end-debug@]===]
end
 
------------------------------------------------------------------------------
-- Dirty layout handler
------------------------------------------------------------------------------
lib.layoutCleaner = lib.layoutCleaner or CreateFrame('Frame')
 
local layoutCleaner = lib.layoutCleaner
layoutCleaner.registry = layoutCleaner.registry or {}
 
function layoutCleaner:RegisterForCleanup(tooltip)
self.registry[tooltip] = true
self:Show()
end
 
function layoutCleaner:CleanupLayouts()
self:Hide()
for tooltip in pairs(self.registry) do
LayoutColspans(tooltip)
end
wipe(self.registry)
end
layoutCleaner:SetScript('OnUpdate', layoutCleaner.CleanupLayouts)
 
------------------------------------------------------------------------------
-- CellProvider and Cell
------------------------------------------------------------------------------
function providerPrototype:AcquireCell()
local cell = tremove(self.heap)
if not cell then
cell = setmetatable(CreateFrame("Frame", nil, UIParent), self.cellMetatable)
if type(cell.InitializeCell) == 'function' then
cell:InitializeCell()
end
end
self.cells[cell] = true
return cell
end
 
function providerPrototype:ReleaseCell(cell)
if not self.cells[cell] then return end
if type(cell.ReleaseCell) == 'function' then
cell:ReleaseCell()
end
self.cells[cell] = nil
tinsert(self.heap, cell)
end
 
function providerPrototype:GetCellPrototype()
return self.cellPrototype, self.cellMetatable
end
 
function providerPrototype:IterateCells()
return pairs(self.cells)
end
 
function lib:CreateCellProvider(baseProvider)
local cellBaseMetatable, cellBasePrototype
if baseProvider and baseProvider.GetCellPrototype then
cellBasePrototype, cellBaseMetatable = baseProvider:GetCellPrototype()
else
cellBaseMetatable = cellMetatable
end
local cellPrototype = setmetatable({}, cellBaseMetatable)
local cellProvider = setmetatable({}, providerMetatable)
cellProvider.heap = {}
cellProvider.cells = {}
cellProvider.cellPrototype = cellPrototype
cellProvider.cellMetatable = { __index = cellPrototype }
return cellProvider, cellPrototype, cellBasePrototype
end
 
------------------------------------------------------------------------------
-- Basic label provider
------------------------------------------------------------------------------
if not lib.LabelProvider then
lib.LabelProvider, lib.LabelPrototype = lib:CreateCellProvider()
end
 
local labelProvider = lib.LabelProvider
local labelPrototype = lib.LabelPrototype
 
function labelPrototype:InitializeCell()
self.fontString = self:CreateFontString()
self.fontString:SetFontObject(GameTooltipText)
end
 
function labelPrototype:SetupCell(tooltip, value, justification, font, l_pad, r_pad, max_width, min_width, ...)
local fs = self.fontString
fs:SetFontObject(font or tooltip:GetFont())
fs:SetJustifyH(justification)
fs:SetText(tostring(value))
 
l_pad = l_pad or 0
r_pad = r_pad or 0
 
local width = fs:GetStringWidth() + l_pad + r_pad
 
fs:SetPoint("TOPLEFT", self, "TOPLEFT", l_pad, 0)
fs:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -r_pad, 0)
 
if max_width and min_width and (max_width < min_width) then
error("maximum width cannot be lower than minimum width: "..tostring(max_width).." < "..tostring(min_width), 2)
end
if min_width and width < min_width then width = min_width end
if max_width and max_width < width then width = max_width end
 
fs:SetWidth(width)
fs:Show()
 
-- Use GetHeight() instead of GetStringHeight() so lines which are longer than width will wrap.
return width, fs:GetHeight()
end
 
function labelPrototype:GetPosition() return self._line, self._column end
 
------------------------------------------------------------------------------
-- Tooltip cache
------------------------------------------------------------------------------
local tooltipHeap = lib.tooltipHeap
 
-- Returns a tooltip
function AcquireTooltip()
local tooltip = tremove(tooltipHeap)
if not tooltip then
tooltip = CreateFrame("Frame", nil, UIParent)
local scrollFrame = CreateFrame("ScrollFrame", nil, tooltip)
scrollFrame:SetPoint("TOP", tooltip, "TOP", 0, -TOOLTIP_PADDING)
scrollFrame:SetPoint("BOTTOM", tooltip, "BOTTOM", 0, TOOLTIP_PADDING)
scrollFrame:SetPoint("LEFT", tooltip, "LEFT", TOOLTIP_PADDING, 0)
scrollFrame:SetPoint("RIGHT", tooltip, "RIGHT", -TOOLTIP_PADDING, 0)
tooltip.scrollFrame = scrollFrame
local scrollChild = CreateFrame("Frame", nil, tooltip.scrollframe)
scrollFrame:SetScrollChild(scrollChild)
tooltip.scrollChild = scrollChild
setmetatable(tooltip, tipMetatable)
end
--[===[@debug@
usedTooltips = usedTooltips + 1
--@end-debug@]===]
return tooltip
end
 
-- Cleans the tooltip and stores it in the cache
function ReleaseTooltip(tooltip)
tooltip:SetAutoHideDelay(nil)
tooltip:Hide()
tooltip:ClearAllPoints()
tooltip:Clear()
if tooltip.slider then
tooltip.slider:SetValue(0)
tooltip.slider:Hide()
tooltip.scrollFrame:SetPoint("RIGHT", tooltip, "RIGHT", -TOOLTIP_PADDING, 0)
tooltip:EnableMouseWheel(false)
tooltip:SetScript("OnMouseWheel", nil)
end
for i, column in ipairs(tooltip.columns) do
tooltip.columns[i] = ReleaseFrame(column)
end
tooltip.columns = ReleaseTable(tooltip.columns)
tooltip.lines = ReleaseTable(tooltip.lines)
tooltip.colspans = ReleaseTable(tooltip.colspans)
 
layoutCleaner.registry[tooltip] = nil
tinsert(tooltipHeap, tooltip)
--[===[@debug@
usedTooltips = usedTooltips - 1
--@end-debug@]===]
end
 
------------------------------------------------------------------------------
-- Cell 'cache' (just a wrapper to the provider's cache)
------------------------------------------------------------------------------
-- Returns a cell for the given tooltip from the given provider
function AcquireCell(tooltip, provider)
local cell = provider:AcquireCell(tooltip)
cell:SetParent(tooltip.scrollChild)
cell:SetFrameLevel(tooltip.scrollChild:GetFrameLevel() + 3)
cell._provider = provider
return cell
end
 
-- Cleans the cell hands it to its provider for storing
function ReleaseCell(cell)
cell:Hide()
cell:ClearAllPoints()
cell:SetParent(nil)
cell:SetBackdrop(nil)
ClearFrameScripts(cell)
cell._font, cell._justification, cell._colSpan, cell._line, cell._column = nil
 
cell._provider:ReleaseCell(cell)
cell._provider = nil
end
 
------------------------------------------------------------------------------
-- Table cache
------------------------------------------------------------------------------
local tableHeap = lib.tableHeap
 
-- Returns a table
function AcquireTable()
local tbl = tremove(tableHeap) or {}
--[===[@debug@
usedTables = usedTables + 1
--@end-debug@]===]
return tbl
end
 
-- Cleans the table and stores it in the cache
function ReleaseTable(table)
wipe(table)
tinsert(tableHeap, table)
--[===[@debug@
usedTables = usedTables - 1
--@end-debug@]===]
end
 
------------------------------------------------------------------------------
-- Tooltip prototype
------------------------------------------------------------------------------
function InitializeTooltip(tooltip, key)
----------------------------------------------------------------------
-- (Re)set frame settings
----------------------------------------------------------------------
tooltip:SetBackdrop(GameTooltip:GetBackdrop())
tooltip:SetBackdropColor(GameTooltip:GetBackdropColor())
tooltip:SetBackdropBorderColor(GameTooltip:GetBackdropBorderColor())
tooltip:SetScale(GameTooltip:GetScale())
tooltip:SetAlpha(1)
tooltip:SetFrameStrata("TOOLTIP")
tooltip:SetClampedToScreen(false)
 
----------------------------------------------------------------------
-- Internal data. Since it's possible to Acquire twice without calling
-- release, check for pre-existence.
----------------------------------------------------------------------
tooltip.key = key
tooltip.columns = tooltip.columns or AcquireTable()
tooltip.lines = tooltip.lines or AcquireTable()
tooltip.colspans = tooltip.colspans or AcquireTable()
tooltip.regularFont = GameTooltipText
tooltip.headerFont = GameTooltipHeaderText
tooltip.labelProvider = labelProvider
 
----------------------------------------------------------------------
-- Finishing procedures
----------------------------------------------------------------------
tooltip:SetAutoHideDelay(nil)
tooltip:Hide()
ResetTooltipSize(tooltip)
end
 
function tipPrototype:SetDefaultProvider(myProvider)
if not myProvider then return end
self.labelProvider = myProvider
end
 
function tipPrototype:GetDefaultProvider() return self.labelProvider end
 
local function checkJustification(justification, level, silent)
if justification ~= "LEFT" and justification ~= "CENTER" and justification ~= "RIGHT" then
if silent then return false end
error("invalid justification, must one of LEFT, CENTER or RIGHT, not: "..tostring(justification), level+1)
end
return true
end
 
function tipPrototype:SetColumnLayout(numColumns, ...)
if type(numColumns) ~= "number" or numColumns < 1 then
error("number of columns must be a positive number, not: "..tostring(numColumns), 2)
end
for i = 1, numColumns do
local justification = select(i, ...) or "LEFT"
checkJustification(justification, 2)
if self.columns[i] then
self.columns[i].justification = justification
else
self:AddColumn(justification)
end
end
end
 
function tipPrototype:AddColumn(justification)
justification = justification or "LEFT"
checkJustification(justification, 2)
 
local colNum = #self.columns + 1
local column = self.columns[colNum] or AcquireFrame(self.scrollChild)
column:SetFrameLevel(self.scrollChild:GetFrameLevel() + 1)
column.justification = justification
column.width = 0
column:SetWidth(1)
column:SetPoint("TOP", self.scrollChild)
column:SetPoint("BOTTOM", self.scrollChild)
 
if colNum > 1 then
column:SetPoint("LEFT", self.columns[colNum - 1], "RIGHT", CELL_MARGIN_H, 0)
SetTooltipSize(self, self.width + CELL_MARGIN_H, self.height)
else
column:SetPoint("LEFT", self.scrollChild)
end
column:Show()
self.columns[colNum] = column
return colNum
end
 
------------------------------------------------------------------------------
-- Scrollbar data and functions
------------------------------------------------------------------------------
local sliderBackdrop = {
["bgFile"] = [[Interface\Buttons\UI-SliderBar-Background]],
["edgeFile"] = [[Interface\Buttons\UI-SliderBar-Border]],
["tile"] = true,
["edgeSize"] = 8,
["tileSize"] = 8,
["insets"] = {
["left"] = 3,
["right"] = 3,
["top"] = 3,
["bottom"] = 3,
},
}
 
local function slider_OnValueChanged(self)
self.scrollFrame:SetVerticalScroll(self:GetValue())
end
 
local function tooltip_OnMouseWheel(self, delta)
local slider = self.slider
local currentValue = slider:GetValue()
local minValue, maxValue = slider:GetMinMaxValues()
 
if delta < 0 and currentValue < maxValue then
slider:SetValue(min(maxValue, currentValue + 10))
elseif delta > 0 and currentValue > minValue then
slider:SetValue(max(minValue, currentValue - 10))
end
end
 
-- will resize the tooltip to fit the screen and show a scrollbar if needed
function tipPrototype:UpdateScrolling(maxheight)
self:SetClampedToScreen(false)
 
-- all data is in the tooltip; fix colspan width and prevent the layout cleaner from messing up the tooltip later
LayoutColspans(self)
layoutCleaner.registry[self] = nil
 
local scale = self:GetScale()
local topside = self:GetTop()
local bottomside = self:GetBottom()
local screensize = UIParent:GetHeight() / scale
local tipsize = (topside - bottomside) / scale
 
-- if the tooltip would be too high, limit its height and show the slider
if bottomside < 0 or topside > screensize or (maxheight and tipsize > maxheight) then
local shrink = (bottomside < 0 and (5 - bottomside) or 0) + (topside > screensize and (topside - screensize + 5) or 0)
 
if maxheight and tipsize - shrink > maxheight then
shrink = tipsize - maxheight
end
self:SetHeight(2 * TOOLTIP_PADDING + self.height - shrink)
self:SetWidth(2 * TOOLTIP_PADDING + self.width + 20)
self.scrollFrame:SetPoint("RIGHT", self, "RIGHT", -(TOOLTIP_PADDING + 20), 0)
 
if not self.slider then
local slider = CreateFrame("Slider", nil, self)
self.slider = slider
slider:SetOrientation("VERTICAL")
slider:SetPoint("TOPRIGHT", self, "TOPRIGHT", -TOOLTIP_PADDING, -TOOLTIP_PADDING)
slider:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -TOOLTIP_PADDING, TOOLTIP_PADDING)
slider:SetBackdrop(sliderBackdrop)
slider:SetThumbTexture([[Interface\Buttons\UI-SliderBar-Button-Vertical]])
slider:SetMinMaxValues(0, 1)
slider:SetValueStep(1)
slider:SetWidth(12)
slider.scrollFrame = self.scrollFrame
slider:SetScript("OnValueChanged", slider_OnValueChanged)
slider:SetValue(0)
end
self.slider:SetMinMaxValues(0, shrink)
self.slider:Show()
self:EnableMouseWheel(true)
self:SetScript("OnMouseWheel", tooltip_OnMouseWheel)
else
self:SetHeight(2 * TOOLTIP_PADDING + self.height)
self:SetWidth(2 * TOOLTIP_PADDING + self.width)
self.scrollFrame:SetPoint("RIGHT", self, "RIGHT", -TOOLTIP_PADDING, 0)
 
if self.slider then
self.slider:SetValue(0)
self.slider:Hide()
self:EnableMouseWheel(false)
self:SetScript("OnMouseWheel", nil)
end
end
end
 
------------------------------------------------------------------------------
-- Tooltip methods for changing its contents.
------------------------------------------------------------------------------
function tipPrototype:Clear()
for i, line in ipairs(self.lines) do
for j, cell in pairs(line.cells) do
if cell then ReleaseCell(cell) end
end
ReleaseTable(line.cells)
line.cells = nil
ReleaseFrame(line)
self.lines[i] = nil
end
for i, column in ipairs(self.columns) do
column.width = 0
column:SetWidth(1)
end
wipe(self.colspans)
ResetTooltipSize(self)
end
 
local function checkFont(font, level, silent)
if not font or type(font) ~= 'table' or type(font.IsObjectType) ~= 'function' or not font:IsObjectType("Font") then
if silent then return false end
error("font must be Font instance, not: "..tostring(font), level+1)
end
return true
end
 
function tipPrototype:SetFont(font)
checkFont(font, 2)
self.regularFont = font
end
 
function tipPrototype:GetFont() return self.regularFont end
 
function tipPrototype:SetHeaderFont(font)
checkFont(font, 2)
self.headerFont = font
end
 
function tipPrototype:GetHeaderFont() return self.headerFont end
 
function SetTooltipSize(tooltip, width, height)
tooltip:SetHeight(2 * TOOLTIP_PADDING + height)
tooltip.scrollChild:SetHeight(height)
tooltip.height = height
 
tooltip:SetWidth(2 * TOOLTIP_PADDING + width)
tooltip.scrollChild:SetWidth(width)
tooltip.width = width
end
 
-- Add 2 pixels to height so dangling letters (g, y, p, j, etc) are not clipped.
function ResetTooltipSize(tooltip)
SetTooltipSize(tooltip, max(0, (CELL_MARGIN_H * (#tooltip.columns - 1)) + (CELL_MARGIN_H / 2)), 2)
end
 
local function EnlargeColumn(tooltip, column, width)
if width > column.width then
SetTooltipSize(tooltip, tooltip.width + width - column.width, tooltip.height)
 
column.width = width
column:SetWidth(width)
end
end
 
function LayoutColspans(tooltip)
local columns = tooltip.columns
for colRange, width in pairs(tooltip.colspans) do
local left, right = colRange:match("^(%d+)%-(%d+)$")
left, right = tonumber(left), tonumber(right)
for col = left, right-1 do
width = width - columns[col].width - CELL_MARGIN_H
end
EnlargeColumn(tooltip, columns[right], width)
end
wipe(tooltip.colspans)
end
 
local function _SetCell(tooltip, lineNum, colNum, value, font, justification, colSpan, provider, ...)
local line = tooltip.lines[lineNum]
local cells = line.cells
 
-- Unset: be quick
if value == nil then
local cell = cells[colNum]
if cell then
for i = colNum, colNum + cell._colSpan - 1 do
cells[i] = nil
end
ReleaseCell(cell)
end
return lineNum, colNum
end
 
-- Check previous cell
local cell
local prevCell = cells[colNum]
if prevCell then
-- There is a cell here
font = font or prevCell._font
justification = justification or prevCell._justification
colSpan = colSpan or prevCell._colSpan
-- Clear the currently marked colspan
for i = colNum + 1, colNum + prevCell._colSpan - 1 do
cells[i] = nil
end
if provider == nil or prevCell._provider == provider then
-- Reuse existing cell
cell = prevCell
provider = cell._provider
else
-- A new cell is required
cells[colNum] = ReleaseCell(prevCell)
end
elseif prevCell == nil then
-- Creating a new cell, using meaningful defaults.
provider = provider or tooltip.labelProvider
font = font or tooltip.regularFont
justification = justification or tooltip.columns[colNum].justification or "LEFT"
colSpan = colSpan or 1
else
error("overlapping cells at column "..colNum, 3)
end
 
local tooltipWidth = #tooltip.columns
local rightColNum
if colSpan > 0 then
rightColNum = colNum + colSpan - 1
if rightColNum > tooltipWidth then
error("ColSpan too big, cell extends beyond right-most column", 3)
end
else
-- Zero or negative: count back from right-most columns
rightColNum = max(colNum, tooltipWidth + colSpan)
-- Update colspan to its effective value
colSpan = 1 + rightColNum - colNum
end
 
-- Cleanup colspans
for i = colNum + 1, rightColNum do
local cell = cells[i]
if cell then
ReleaseCell(cell)
elseif cell == false then
error("overlapping cells at column "..i, 3)
end
cells[i] = false
end
 
-- Create the cell
if not cell then
cell = AcquireCell(tooltip, provider)
cells[colNum] = cell
end
 
-- Anchor the cell
cell:SetPoint("LEFT", tooltip.columns[colNum])
cell:SetPoint("RIGHT", tooltip.columns[rightColNum])
cell:SetPoint("TOP", line)
cell:SetPoint("BOTTOM", line)
 
-- Store the cell settings directly into the cell
-- That's a bit risky but is really cheap compared to other ways to do it
cell._font, cell._justification, cell._colSpan, cell._line, cell._column = font, justification, colSpan, lineNum, colNum
 
-- Setup the cell content
local width, height = cell:SetupCell(tooltip, value, justification, font, ...)
cell:Show()
 
if colSpan > 1 then
-- Postpone width changes until the tooltip is shown
local colRange = colNum.."-"..rightColNum
tooltip.colspans[colRange] = max(tooltip.colspans[colRange] or 0, width)
layoutCleaner:RegisterForCleanup(tooltip)
else
-- Enlarge the column and tooltip if need be
EnlargeColumn(tooltip, tooltip.columns[colNum], width)
end
 
-- Enlarge the line and tooltip if need be
if height > line.height then
SetTooltipSize(tooltip, tooltip.width, tooltip.height + height - line.height)
 
line.height = height
line:SetHeight(height)
end
 
if rightColNum < tooltipWidth then
return lineNum, rightColNum + 1
else
return lineNum, nil
end
end
 
local function CreateLine(tooltip, font, ...)
if #tooltip.columns == 0 then
error("column layout should be defined before adding line", 3)
end
local lineNum = #tooltip.lines + 1
local line = tooltip.lines[lineNum] or AcquireFrame(tooltip.scrollChild)
line:SetFrameLevel(tooltip.scrollChild:GetFrameLevel() + 2)
line:SetPoint('LEFT', tooltip.scrollChild)
line:SetPoint('RIGHT', tooltip.scrollChild)
if lineNum > 1 then
line:SetPoint('TOP', tooltip.lines[lineNum-1], 'BOTTOM', 0, -CELL_MARGIN_V)
SetTooltipSize(tooltip, tooltip.width, tooltip.height + CELL_MARGIN_V)
else
line:SetPoint('TOP', tooltip.scrollChild)
end
tooltip.lines[lineNum] = line
line.cells = line.cells or AcquireTable()
line.height = 0
line:SetHeight(1)
line:Show()
 
local colNum = 1
for i = 1, #tooltip.columns do
local value = select(i, ...)
if value ~= nil then
lineNum, colNum = _SetCell(tooltip, lineNum, i, value, font, nil, 1, tooltip.labelProvider)
end
end
return lineNum, colNum
end
 
function tipPrototype:AddLine(...)
return CreateLine(self, self.regularFont, ...)
end
 
function tipPrototype:AddHeader(...)
return CreateLine(self, self.headerFont, ...)
end
 
local GenericBackdrop = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
}
 
function tipPrototype:AddSeparator(height, r, g, b, a)
local lineNum, colNum = self:AddLine()
local line = self.lines[lineNum]
local color = NORMAL_FONT_COLOR
 
height = height or 1
SetTooltipSize(self, self.width, self.height + height)
line.height = height
line:SetHeight(height)
line:SetBackdrop(GenericBackdrop)
line:SetBackdropColor(r or color.r, g or color.g, b or color.b, a or 1)
return lineNum, colNum
end
 
function tipPrototype:SetCellColor(lineNum, colNum, r, g, b, a)
local cell = self.lines[lineNum].cells[colNum]
 
if cell then
local sr, sg, sb, sa = self:GetBackdropColor()
cell:SetBackdrop(GenericBackdrop)
cell:SetBackdropColor(r or sr, g or sg, b or sb, a or sa)
end
end
 
function tipPrototype:SetColumnColor(colNum, r, g, b, a)
local column = self.columns[colNum]
 
if column then
local sr, sg, sb, sa = self:GetBackdropColor()
column:SetBackdrop(GenericBackdrop)
column:SetBackdropColor(r or sr, g or sg, b or sb, a or sa)
end
end
 
function tipPrototype:SetLineColor(lineNum, r, g, b, a)
local line = self.lines[lineNum]
 
if line then
local sr, sg, sb, sa = self:GetBackdropColor()
line:SetBackdrop(GenericBackdrop)
line:SetBackdropColor(r or sr, g or sg, b or sb, a or sa)
end
end
 
-- TODO: fixed argument positions / remove checks for performance?
function tipPrototype:SetCell(lineNum, colNum, value, ...)
-- Mandatory argument checking
if type(lineNum) ~= "number" then
error("line number must be a number, not: "..tostring(lineNum), 2)
elseif lineNum < 1 or lineNum > #self.lines then
error("line number out of range: "..tostring(lineNum), 2)
elseif type(colNum) ~= "number" then
error("column number must be a number, not: "..tostring(colNum), 2)
elseif colNum < 1 or colNum > #self.columns then
error("column number out of range: "..tostring(colNum), 2)
end
 
-- Variable argument checking
local font, justification, colSpan, provider
local i, arg = 1, ...
if arg == nil or checkFont(arg, 2, true) then
i, font, arg = 2, ...
end
if arg == nil or checkJustification(arg, 2, true) then
i, justification, arg = i + 1, select(i, ...)
end
if arg == nil or type(arg) == 'number' then
i, colSpan, arg = i + 1, select(i, ...)
end
if arg == nil or type(arg) == 'table' and type(arg.AcquireCell) == 'function' then
i, provider = i + 1, arg
end
 
return _SetCell(self, lineNum, colNum, value, font, justification, colSpan, provider, select(i, ...))
end
 
function tipPrototype:GetLineCount() return #self.lines end
 
function tipPrototype:GetColumnCount() return #self.columns end
 
 
------------------------------------------------------------------------------
-- Frame Scripts
------------------------------------------------------------------------------
local highlight = CreateFrame("Frame", nil, UIParent)
highlight:SetFrameStrata("TOOLTIP")
highlight:Hide()
 
highlight._texture = highlight:CreateTexture(nil, "OVERLAY")
highlight._texture:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
highlight._texture:SetBlendMode("ADD")
highlight._texture:SetAllPoints(highlight)
 
local scripts = {
OnEnter = function(frame, ...)
highlight:SetParent(frame)
highlight:SetAllPoints(frame)
highlight:Show()
if frame._OnEnter_func then
frame:_OnEnter_func(frame._OnEnter_arg, ...)
end
end,
OnLeave = function(frame, ...)
highlight:Hide()
highlight:ClearAllPoints()
highlight:SetParent(nil)
if frame._OnLeave_func then
frame:_OnLeave_func(frame._OnLeave_arg, ...)
end
end,
OnMouseDown = function(frame, ...)
frame:_OnMouseDown_func(frame._OnMouseDown_arg, ...)
end,
OnMouseUp = function(frame, ...)
frame:_OnMouseUp_func(frame._OnMouseUp_arg, ...)
end,
}
 
function SetFrameScript(frame, script, func, arg)
if not scripts[script] then
return
end
frame["_"..script.."_func"] = func
frame["_"..script.."_arg"] = arg
if script == "OnMouseDown" or script == "OnMouseUp" then
if func then
frame:SetScript(script, scripts[script])
else
frame:SetScript(script, nil)
end
end
-- if at least one script is set, set the OnEnter/OnLeave scripts for the highlight
if frame._OnEnter_func or frame._OnLeave_func or frame._OnMouseDown_func or frame._OnMouseUp_func then
frame:EnableMouse(true)
frame:SetScript("OnEnter", scripts.OnEnter)
frame:SetScript("OnLeave", scripts.OnLeave)
else
frame:EnableMouse(false)
frame:SetScript("OnEnter", nil)
frame:SetScript("OnLeave", nil)
end
end
 
function ClearFrameScripts(frame)
if frame._OnEnter_func or frame._OnLeave_func or frame._OnMouseDown_func or frame._OnMouseUp_func then
frame:EnableMouse(false)
frame:SetScript("OnEnter", nil)
frame._OnEnter_func = nil
frame._OnEnter_arg = nil
frame:SetScript("OnLeave", nil)
frame._OnLeave_func = nil
frame._OnLeave_arg = nil
frame:SetScript("OnMouseDown", nil)
frame._OnMouseDown_func = nil
frame._OnMouseDown_arg = nil
frame:SetScript("OnMouseUp", nil)
frame._OnMouseUp_func = nil
frame._OnMouseUp_arg = nil
end
end
 
function tipPrototype:SetLineScript(lineNum, script, func, arg)
SetFrameScript(self.lines[lineNum], script, func, arg)
end
 
function tipPrototype:SetColumnScript(colNum, script, func, arg)
SetFrameScript(self.columns[colNum], script, func, arg)
end
 
function tipPrototype:SetCellScript(lineNum, colNum, script, func, arg)
local cell = self.lines[lineNum].cells[colNum]
if cell then
SetFrameScript(cell, script, func, arg)
end
end
 
 
------------------------------------------------------------------------------
-- Auto-hiding feature
------------------------------------------------------------------------------
 
-- Script of the auto-hiding child frame
local function AutoHideTimerFrame_OnUpdate(self, elapsed)
self.checkElapsed = self.checkElapsed + elapsed
if self.checkElapsed > 0.1 then
if self.parent:IsMouseOver() or (self.alternateFrame and self.alternateFrame:IsMouseOver()) then
self.elapsed = 0
else
self.elapsed = self.elapsed + self.checkElapsed
if self.elapsed >= self.delay then
lib:Release(self.parent)
end
end
self.checkElapsed = 0
end
end
 
-- Usage:
-- :SetAutoHideDelay(0.25) => hides after 0.25sec outside of the tooltip
-- :SetAutoHideDelay(0.25, someFrame) => hides after 0.25sec outside of both the tooltip and someFrame
-- :SetAutoHideDelay() => disable auto-hiding (default)
function tipPrototype:SetAutoHideDelay(delay, alternateFrame)
local timerFrame = self.autoHideTimerFrame
delay = tonumber(delay) or 0
 
if delay > 0 then
if not timerFrame then
timerFrame = AcquireFrame(self)
timerFrame:SetScript("OnUpdate", AutoHideTimerFrame_OnUpdate)
self.autoHideTimerFrame = timerFrame
end
timerFrame.parent = self
timerFrame.checkElapsed = 0
timerFrame.elapsed = 0
timerFrame.delay = delay
timerFrame.alternateFrame = alternateFrame
timerFrame:Show()
elseif timerFrame then
self.autoHideTimerFrame = nil
timerFrame.alternateFrame = nil
timerFrame:SetScript("OnUpdate", nil)
ReleaseFrame(timerFrame)
end
end
 
------------------------------------------------------------------------------
-- "Smart" Anchoring
------------------------------------------------------------------------------
local function GetTipAnchor(frame)
local x,y = frame:GetCenter()
if not x or not y then return "TOPLEFT", "BOTTOMLEFT" end
local hhalf = (x > UIParent:GetWidth() * 2/3) and "RIGHT" or (x < UIParent:GetWidth() / 3) and "LEFT" or ""
local vhalf = (y > UIParent:GetHeight() / 2) and "TOP" or "BOTTOM"
return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
end
 
function tipPrototype:SmartAnchorTo(frame)
if not frame then
error("Invalid frame provided.", 2)
end
self:ClearAllPoints()
self:SetClampedToScreen(true)
self:SetPoint(GetTipAnchor(frame))
end
 
------------------------------------------------------------------------------
-- Debug slashcmds
------------------------------------------------------------------------------
--[===[@debug@
local print = print
local function PrintStats()
local tipCache = tostring(#tooltipHeap)
local frameCache = tostring(#frameHeap)
local tableCache = tostring(#tableHeap)
 
print("Tooltips used: "..usedTooltips..", Cached: "..tipCache..", Total: "..tipCache + usedTooltips)
print("Frames used: "..usedFrames..", Cached: "..frameCache..", Total: "..frameCache + usedFrames)
print("Tables used: "..usedTables..", Cached: "..tableCache..", Total: "..tableCache + usedTables)
 
local header = false
for k, v in pairs(activeTooltips) do
if not header then
print("Active tooltips:")
header = true
end
print("- "..k)
end
end
 
SLASH_LibQTip1 = "/qtip"
SlashCmdList["LibQTip"] = PrintStats
--@end-debug@]===]
libs/LibQTip-1.0/LibQTip-1.0.toc New file
0,0 → 1,17
## Interface: 30300
## Title: Lib: QTip-1.0
## Notes: Library providing multi-column tooltips.
## Author: Torhal, Adirelle, Elkano, Tristanian
## Version: r126-release
## LoadOnDemand: 1
## X-Date: 2010-01-16T19:03:33Z
## X-Credits: Kaelten (input on initial design)
## X-Category: Library, Tooltip
## X-License: Ace3 BSD-like license
## X-Curse-Packaged-Version: r126-release
## X-Curse-Project-Name: LibQTip-1.0
## X-Curse-Project-ID: libqtip-1-0
## X-Curse-Repository-ID: wow/libqtip-1-0/mainline
 
LibStub\LibStub.lua
lib.xml
libs/LibQTip-1.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
libs/LibQTip-1.0/LibStub/LibStub.toc New file
0,0 → 1,13
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
## X-Curse-Packaged-Version: 1.0
## X-Curse-Project-Name: LibStub
## X-Curse-Project-ID: libstub
## X-Curse-Repository-ID: wow/libstub/mainline
 
LibStub.lua
libs/LibQTip-1.0/lib.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibQTip-1.0.lua"/>
</Ui>
\ No newline at end of file
libs/LibQTip-1.0/Changelog-LibQTip-1.0-r126-release.txt New file
0,0 → 1,22
------------------------------------------------------------------------
r126 | torhal | 2010-01-16 19:04:27 +0000 (Sat, 16 Jan 2010) | 1 line
Changed paths:
A /tags/r126-release (from /trunk:125)
 
Tagging as r126-release
------------------------------------------------------------------------
r125 | torhal | 2010-01-16 19:03:33 +0000 (Sat, 16 Jan 2010) | 1 line
Changed paths:
M /trunk/LibQTip-1.0.lua
 
In UpdateScrolling(): Changed scale modifiers to work correctly with fractional sizes less than one.
------------------------------------------------------------------------
r123 | torhal | 2010-01-01 11:05:28 +0000 (Fri, 01 Jan 2010) | 3 lines
Changed paths:
M /trunk/LibQTip-1.0.lua
M /trunk/LibQTip-1.0.toc
 
In tipPrototype:UpdateScrolling() - modified to account for the scale of the tooltip so the function will actually work if the tooltip has been scaled to gigantic proportions.
Made the library load-on-demand.
 
------------------------------------------------------------------------
embeds.xml
9,4 → 9,5
<Include file="libs\AceEvent-3.0\AceEvent-3.0.xml"/>
<Include file="libs\AceTimer-3.0\AceTimer-3.0.xml"/>
<Script file="libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
<Script file="libs\LibQTip-1.0\LibQTip-1.0.lua"/>
</Ui>