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 '', 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