Quicklog/Window.lua

411 lines
11 KiB
Lua

local name, addon = ...
local f = CreateFrame("Frame", nil, UIParent)
local window_methods = {}
local displays = { 'DAMAGE', 'HEAL', 'ABSORBED' }
local display_methods = {}
local defaultWindow = {
['active'] = true,
['show'] = true,
['bars'] = {},
['display'] = 'DAMAGE',
}
local windows = {}
local function sort_total(a, b)
return a['total'] > b['total']
end
local function sort_totalHeal(a, b)
return a['totalHeal'] > b['totalHeal']
end
local function sort_totalAbsorbed(a, b)
return a['totalAbsorbed'] > b['totalAbsorbed']
end
local sorts = {
['total'] = sort_total,
['totalHeal'] = sort_totalHeal,
['totalAbsorbed'] = sort_totalAbsorbed,
}
local function releaseBars(bars, num)
while(num < #bars) do
local bar = bars[num + 1]
tremove(bars, num + 1)
bar['lastPos'] = nil
bar['class'] = nil
bar:Release()
end
return bars
end
local function GetSegmentId(seg)
for i = 1, #QuicklogDB['segments'] do
if(QuicklogDB['segments'][i] == seg) then
return i
end
end
return #QuicklogDB['segments']
end
local function defaultDisplay(win, total)
local seg = win['seg']
if(seg) then
local store = addon:GetStore(seg)
-- print('s',seg)
local src = {}
local maxtotal = 0
for c, d in pairs(seg['source']) do
local gis = addon:GetGuidInfo2(d)
if(gis and d[total] > 0 and gis:IsParty()) then
if(d[total]>maxtotal) then
maxtotal = d[total]
end
src[#src + 1] = d
end
end
-- print('src', #src)
sort(src, sorts[total])
local last = win
local h1 = win:GetHeight()
local maxBars = win:GetMaxBars()
-- print("bars",#src, maxBars)
for i = 1, #src do
local d = src[i]
local bar = win:GetBar(i)
local guid = d[1]
bar['guid'] = guid
local gib = addon:GetGuidInfo2(d)
if(bar['class'] ~= gib['class']) then
bar:SetColorByClass(gib['class'])
end
if(bar['lastPos'] ~= i) then
bar['lastPos'] = i
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", win, "TOPLEFT", 14, (bar:GetHeight() * i * - 1) + 2)
end
bar:SetMinMaxValues(0, maxtotal)
bar:SetValue(d[total])
bar:SetText(gib['shortName'] and gib['shortName'] or gib[2], d[total])
last = bar
if(i >= maxBars) then
break
end
end
win['settings']['bars'] = releaseBars(win['settings']['bars'], #src)
end
end
function display_methods:DAMAGE(win)
defaultDisplay(win, 'total')
end
function display_methods:HEAL(win)
defaultDisplay(win, 'totalHeal')
end
function display_methods:ABSORBED(win)
defaultDisplay(win, 'totalAbsorbed')
end
function window_methods:GetMaxBars()
local h1 = self:GetHeight()
local bar = self:GetBar(1)
local h2 = bar:GetHeight()
local e = h1 - 16 - (h2/2)
local n = (e) / (h2)
local m = floor(n) -- 8 = Insets, 2 y-offset
-- print('heights',h1, h2, 'e', e, 'h', h2*m, 'max',m , n, m*16)
return m
end
function window_methods:GetBar(bid)
if(self['settings']['bars'][bid]) then
return self['settings']['bars'][bid]
else
self['settings']['bars'][#self['settings']['bars'] + 1] = addon:GetStatusBar()
self['settings']['bars'][#self['settings']['bars']]:SetParent(self)
return self['settings']['bars'][#self['settings']['bars']]
end
end
local function defaultTooltip(tooltip, src, total, spells)
local dip = {}
tooltip:AddDoubleLine("Total", src[total], 1, 1, 1, 1, 1, 1)
for guid, dest in pairs(src['dest']) do
if(dest[total]>0) then
dip[#dip + 1] = dest
end
end
if(#dip > 0) then
sort(dip, sorts[total])
for i = 1, #dip do
local dest = dip[i]
local gib = addon:GetGuidInfo2(dest)
if(gib) then
local r, g, b = unpack(gib['classColor'] or addon:GetClassColors(gib['class']))
tooltip:AddDoubleLine(gib[2] and gib[2] or '<Unbekannt>', dest[total], r, g, b, 1, 1, 1)
if(dest[spells]) then
local tip = {}
for _, spell in pairs(dest[spells]) do
if(spell[total]>0) then
tip[#tip + 1] = spell
end
end
if(#tip > 0) then
sort(tip, sorts[total])
for i = 1, #tip do
local spell = tip[i]
tooltip:AddDoubleLine(format(" %s",spell['spellName']), spell[total])
if(i >= QuicklogDB:Get('maxTooltipSpells')) then
break
end
end
end
tip = nil
end
end
if(i >= QuicklogDB:Get('maxTooltipUnits')) then
break
end
end
end
dip = nil
end
function window_methods:StatusBarOnEnter(bar)
local seg = self['seg']
local store = addon:GetStore(seg)
local src = store:GetSource(bar['guid'], nil, nil, true)
if(not src or not src[2]) then bar:Release() return end
local display = self['settings']['display']
bar['tooltip']:AddLine(format("%s - %s", display, src[2]),1,1,1)
if(display == 'DAMAGE') then
defaultTooltip(bar['tooltip'], src, 'total', 'spells')
elseif(display == 'HEAL') then
defaultTooltip(bar['tooltip'], src, 'totalHeal', 'spellsHeal')
elseif(display == 'ABSORBED') then
defaultTooltip(bar['tooltip'], src, 'totalAbsorbed', 'spellsAbsorbed')
end
end
local function OnResize(self)
local maxBars = self:GetMaxBars()
for i = 1, #self['settings']['bars'] do
local bar = self['settings']['bars'][i]
if(i>maxBars) then
bar:Hide()
else
bar:Show()
end
end
end
function window_methods:StatusBarOnLeave(bar)
--
end
function window_methods:Refresh()
local display = self['settings']['display']
self['title']['text']:SetText(display)
self['footer']['text']:SetText(format("# %i/%i",GetSegmentId(self['seg']),#QuicklogDB['segments']))
if(type(display_methods[display]) == 'function') then
self['seg'] = self['seg'] or addon:GetSegment()
display_methods[display](nil, self)
end
OnResize(self)
-- print(self:GetName(), 'refresh', display)
end
function window_methods:SetSegment(seg)
self['seg'] = seg
self:Refresh()
end
function window_methods:UpdateWindow()
if(not self['seg']) then
self:SetSegment(addon:GetSegment())
else
self:Refresh()
end
-- print("update",self:GetName())
end
function window_methods:Clear()
for i = 1, #self['settings']['bars'] do
local bar = self['settings']['bars'][i]
if(bar) then
bar['src'] = nil
bar:Release()
end
tremove(self['settings']['bars'], i)
end
end
local function StartResize(self, button)
local p = self:GetParent()
p:StartSizing()
self['isMoving'] = true
self['hasMoved'] = false
end
local function StopResize(self)
if(self['isMoving']) then
local p = self:GetParent()
p:StopMovingOrSizing()
self['isMoving'] = false
self['hasMoved'] = true
end
end
local function GetDisplayId(display)
for i=1, #displays do
if(displays[i] == display) then
return i
end
end
return 1
end
local function TitleNavClick(self, button)
local win = self:GetParent():GetParent()
local display = win['settings']['display']
local cur = GetDisplayId(display)
win:Clear()
if(self['nav'] == "LEFT") then
cur = cur - 1
if(cur < 1) then
cur = #displays
end
else
cur = cur + 1
if(cur > #displays) then
cur = 1
end
end
win['settings']['display'] = displays[cur]
win:Refresh()
end
local function FooterNavClick(self, button)
local win = self:GetParent():GetParent()
local cur = GetSegmentId(win['seg'])
win:Clear()
if(self['nav'] == "LEFT") then
cur = cur - 1
if(cur < 1) then
cur = #QuicklogDB['segments']
end
else
cur = cur + 1
if(cur > #QuicklogDB['segments']) then
cur = 1
end
end
win:SetSegment(QuicklogDB['segments'][cur])
win:Refresh()
end
local function titleDragStart(self)
self:GetParent():StartMoving()
end
local function titleDragStop(self)
self:GetParent():StopMovingOrSizing()
end
local function GetWinBar(self, barName, drag, clickFunc)
local title = CreateFrame("Frame", "$parent_"..barName, self, "BackdropTemplate")
self:EnableMouse(true)
title:SetSize(200, 20)
title:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
-- edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true,
tileSize = 32,
edgeSize = 32,
insets = { left = 2, right = 2, top = 2, bottom = 2 }
})
title:EnableMouse(true)
if(drag) then
title:RegisterForDrag("LeftButton")
title:SetScript("OnDragStart", titleDragStart)
title:SetScript("OnDragStop", titleDragStop)
end
title:SetBackdropBorderColor(1, 1, 1, 1)
local b = CreateFrame("BUTTON", "$parent_Left", title, "BackdropTemplate")
b:SetSize(20,20)
b:SetPoint("TOPLEFT", title, "TOPLEFT")
b:SetNormalTexture("Interface\\BUTTONS\\UI-SpellbookIcon-PrevPage-Up")
b:SetPushedTexture("Interface\\BUTTONS\\UI-SpellbookIcon-PrevPage-Down")
b:SetDisabledTexture("Interface\\BUTTONS\\UI-SpellbookIcon-PrevPage-Disabled")
b:SetScript("OnClick", clickFunc)
b['nav'] = "LEFT"
local d = CreateFrame("BUTTON", "$parent_Right", title, "BackdropTemplate")
d:SetSize(20,20)
d:SetPoint("TOPLEFT", b, "TOPRIGHT",-8)
d:SetNormalTexture("Interface\\BUTTONS\\UI-SpellbookIcon-NextPage-Up")
d:SetPushedTexture("Interface\\BUTTONS\\UI-SpellbookIcon-NextPage-Down")
d:SetDisabledTexture("Interface\\BUTTONS\\UI-SpellbookIcon-NextPage-Disabled")
d:SetScript("OnClick", clickFunc)
d['nav'] = "RIGHT"
local c = title:CreateFontString(nil,"OVERLAY","CombatLogFont")
c:ClearAllPoints()
c:SetAllPoints(title)
c:SetPoint("TOPLEFT", d, "TOPRIGHT")
c:SetJustifyH("LEFT")
c:SetText(name)
title['text'] = c
return title
end
function window_methods:AddFooterBar()
self['footer'] = GetWinBar(self, 'Footer', false, FooterNavClick)
self['footer']:SetPoint("TOPLEFT", self, "BOTTOMLEFT")
end
function window_methods:AddTitleBar()
self['title'] = GetWinBar(self, 'Title', true, TitleNavClick)
self['title']:SetPoint("BOTTOMLEFT", self, "TOPLEFT")
end
function addon:GetWindow(windowname)
for i = 1, #windows do
if(windows[i] and windows[i]:GetName() == windowname) then
-- print("Window", windowname)
return windows[i]
end
end
windows[#windows + 1] = CreateFrame("Frame", format("%s_Window_%i", name, #windows + 1),f,"BackdropTemplate")
local win = windows[#windows]
for fname, func in pairs(window_methods) do
win[fname] = func
end
win:AddTitleBar()
win:AddFooterBar()
self['resize'] = CreateFrame("Frame", nil, win)
local btn = self['resize']
btn:SetSize(20,20)
btn:SetPoint("BOTTOMRIGHT",win,"BOTTOMRIGHT")
btn:SetScript("OnMouseDown", StartResize)
btn:SetScript("OnMouseUp", StopResize)
win:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
-- edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true,
tileSize = 32,
edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
})
win:SetBackdropColor(0, 0, 0, 1)
win['settings'] = CopyTable(defaultWindow)
win:HookScript("OnSizeChanged", OnResize)
win:SetPoint("CENTER",UIParent,"CENTER")
win:SetSize(200, 400)
win:SetMovable(true)
win:SetResizable(true)
win:SetMinResize(200,200)
win:SetMaxResize(200,800)
win:SetClampedToScreen(true)
win:Show()
win:UpdateWindow()
return win
end
function addon:CreateWindow(windowname)
return self:GetWindow(windowname)
end
function addon:UpdateWindows(seg)
if(#windows == 0) then
self:CreateWindow('DAMAGE')
-- self:CreateWindow('HEAL')
end
for i = 1, #windows do
local win = windows[i]
if(win['settings']['active'] and win:IsVisible()) then
if(seg) then
win:SetSegment(seg)
else
win:SetSegment(addon:GetSegment())
end
win:UpdateWindow()
end
end
end