Mercurial > wow > buffalo2
view ObjectiveFrame.lua @ 1:b0447b382f36
sorting client events from maintenance logic
implemented all that action buttons entail for quest items
author | Nenue |
---|---|
date | Wed, 30 Mar 2016 16:30:49 -0400 |
parents | |
children | a2396b03ce63 |
line wrap: on
line source
--- ${PACKAGE_NAME} -- @file-author@ -- @project-revision@ @project-hash@ -- @file-revision@ @file-hash@ -- Created: 3/30/2016 12:49 AM local B = select(2,...).frame local ipairs, max, unpack = ipairs, max, unpack local CreateFrame = CreateFrame local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local print = B.print('Objectives') -------------------------------------------------------------------- --- Global frame layout -------------------------------------------------------------------- --- Upvalues local Wrapper = _G.VeneerObjectiveWrapper local Scroller = Wrapper.scrollArea local Scroll = _G.VeneerObjectiveScroll local orderedHandlers = mod.orderedHandlers local orderedNames = mod.orderedNames --- Temp values set during updates local wrapperWidth, wrapperHeight local scrollWidth, scrollHeight local previousBlock local currentBlock --- todo: map these into config table when its sorted out local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]] local titleSize, textSize = 15, 15 local titleOutline, textOutline = "OUTLINE", "OUTLINE" local titleSpacing, textSpacing = 4, 3 local textIndent = 5 local wrapperMaxWidth, wrapperMaxHeight = 280, 490 -- these are the hard bounds, actual *Height variables are changed local headerFont, headerSize, headerHeight = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 18, 24 local headerOutline, headerColor = 'OUTLINE', {1,1,1,1} local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0} local Scroller_OnShow = function() Wrapper.watchMoneyReasons = 0; mod.UpdateWrapper() end local Scroller_OnHide = function() local self = Wrapper Wrapper:UnregisterAllEvents() Wrapper:SetScript('OnEvent', nil) Wrapper.Background:Hide() Wrapper.BackgroundR:Hide() end local Scroller_OnMouseWheel = function(self, delta) local r = Scroll:GetHeight() - Scroller:GetHeight() local s = self:GetVerticalScroll() - delta * floor(r/5+.5) if r == 0 then return end if s >= r then s = r elseif s < 1 then s = 0 end self:SetVerticalScroll(s) print(s, r, self:GetVerticalScroll()) mod.UpdateActionButtons() end local WrapperCloseButton_OnClick = function(self) if Scroller:IsVisible() then Scroller:Hide() else Scroller:Show() end end mod.InitializeTrackers = function() for i, name in ipairs(orderedNames) do if not mod.orderedHandlers[i] then if mod.Tracker(name, i) then local handler = mod[name] local tracker = CreateFrame('Frame', 'Veneer'..name..'Tracker', Scroll, 'VeneerTrackerTemplate') tracker.header:SetText(handler.name) tracker.header:SetHeight(headerHeight) tracker.header:SetFont(headerFont, headerSize, headerOutline) tracker.header:SetTextColor(unpack(headerColor)) handler.Tracker = tracker mod.orderedTrackers[i] = tracker mod.namedTrackers[name] = tracker mod.indexedTrackers[handler] = tracker print('created new tracker frames for new handler') end end end Scroller:SetScrollChild(Scroll) Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel) Scroller:SetScript('OnShow', Scroller_OnShow) Scroller:SetScript('OnHide', Scroller_OnHide) Wrapper.close:SetScript('OnClick', WrapperCloseButton_OnClick) Wrapper:SetPoint(unpack(wrapperPosition)) Scroller_OnShow(Scroller) end mod.defaults = { ObjectiveTrackerAnchor = {'BOTTOM', 'RIGHT'}, ObjectiveTrackerParent = 'DebuffButton', ObjectiveTrackerSize = {250, 600}, ObjectiveWrapperParent = '', ObjectiveTrackerStyle = { Normal = { Title = { Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, 0}}, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, }, Text = { Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, 0}}, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, }, }, Super = { Title = { Gradient = { MinColor = {0, .7, .6, .8}, MaxColor = {0, .7, .6, 0.2}}, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, BackgroundFullWidth = true }, Text = { Gradient = { MinColor = {0, .7, .6, 0.5}, MaxColor = {0, .7, .6, 0.1} }, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, }, }, Active = { Title = { Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, BackgroundFullWidth = true }, Text = { Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, BackgroundFullWidth = true } }, Complete = { Title = { Gradient = { MinColor = {0, 1, 0, 0.34}, MaxColor = {0, 1, 0, .17}, }, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, BackgroundFullWidth = true }, Text = { Gradient = { MinColor = {0, 1, 0, .25}, MaxColor = {0, 1, 0, 0.12}, }, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, BackgroundFullWidth = true } }, } } --- Argument containers local a1, a2, a3, a4, b1, b2, b3, b4, f1, f2, f3, w1, w2 mod.SetBlockStyle = function(block, name) -- var names intended to reflect argument order local c = mod.defaults.ObjectiveTrackerStyle[name] a1, a2, a3, a4 = unpack(c.Title.Gradient.MinColor) b1, b2, b3, b4 = unpack(c.Title.Gradient.MaxColor) block.titlebg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4) a1, a2, a3, a4 = unpack(c.Text.Gradient.MinColor) b1, b2, b3, b4 = unpack(c.Text.Gradient.MaxColor) block.bg:SetGradientAlpha('HORIZONTAL', a1, a2, a3, a4, b1, b2, b3, b4) f1, f2, f3 = unpack(c.Title.Font) block.title:SetFont(f1, f2, f3) f1, f2 ,f3 = unpack(c.Text.Font) block.objectives:SetFont(f1,f2,f3) w1 = Wrapper:GetWidth() w2 = (c.Title.BackgroundFullWidth and w1 or block.title:GetStringWidth()) local titleSpacing, titleSpacing2 = c.Title.Spacing, (c.Title.Spacing * 2) local textSpacing, textSpacing2 = c.Text.Spacing, (c.Text.Spacing * 2) if block.info.isTrivial then block.title:SetTextColor(0.7, 0.7, 0.7, 1) elseif block.info.isComplete then block.title:SetTextColor(1,1,1,1) else block.title:SetTextColor(0,.7,1,1) end block.title:SetSpacing(titleSpacing) block.objectives:SetSpacing(textSpacing) block.objectives:SetWordWrap(true) local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight() local blockHeight = titleHeight + titleSpacing2 + textHeight + textSpacing2 local blockWidth = wrapperMaxWidth block.titlebg:SetSize(min(w1, w2), titleHeight + titleSpacing2) block.bg:SetSize(w1, textHeight + textSpacing2) block:SetSize(blockWidth, blockHeight) block.title:SetPoint('TOPLEFT', block.titlebg, 'TOPLEFT', 0, -titleSpacing) block.objectives:SetPoint('TOPLEFT', block.titlebg, 'BOTTOMLEFT', textIndent, -textSpacing) -- store block.titleHeight = titleHeight block.textHeight = textHeight block.width = blockWidth block.height = blockHeight print('|cFF88DDFFApplyStyle(', block:GetName(), ')|r', blockWidth, 'x', blockHeight, '(textH', textHeight,', titleH', titleHeight, ')') end --- Updates the selected block frame to display the given info batch -- If `previousBlock` is set, it will attempt to anchor to that -- @param blockNum the ordered block to be updated, not a watchIndex value -- @param info the reference returned by the GetXInfo functions -- REMEMBER: t.info and questData[questID] are the same table mod.UpdateTrackerBlock = function (handler, blockIndex, info) print('|cFF00FFFFUpdateTrackerBlock('..blockIndex..'|r') if not blockIndex or not info then return end local tracker = handler.Tracker local t = handler:GetBlock(blockIndex) if previousBlock then if blockIndex == 1 then t:SetPoint('TOPLEFT', previousBlock, 'TOPLEFT', 0, -headerHeight) else t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0) end t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) end print(t:GetName(), t:GetSize()) print(t:GetPoint(1)) t.info = info if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end info.blockIndex = blockIndex handler.BlockInfo[blockIndex] = info t.Select = handler.Select t.Open = handler.Open t.Remove = handler.Remove t.Link = handler.Link t:SetScript('OnMouseUp', handler.OnMouseUp) t:SetScript('OnMouseDown', handler.OnMouseDown) t.title:SetText(info.title) if info.isComplete then t.objectives:Show() t.objectives:SetText(info.completionText) elseif info.numObjectives >= 1 then t.objectives:Show() print('objective lines:', info.numObjectives, 'can wrap:', t.objectives:CanWordWrap()) local text = '' for o, obj in ipairs(t.info.objectives) do local line = obj.text if obj.type == 'monster' then line = '|cFFFFFF00' .. line .. '|r' elseif obj.type == 'item' then line = '|cFF44BBFF' .. line .. '|r' elseif obj.type == 'object' then line = '|cFFFFFFFF' .. line .. '|r' end text = text .. ((text == '') and "" or "\n") .. line end t.objectives:SetText(text) -- todo: set up a SecureActionButton template if info.specialItem then print('|cFF00FFFFretrieve item button') mod.SetItemButton(t, info) elseif t.itemButton then print('|cFF00FF88drop item button') mod.FreeItemButton(t, info) end elseif info.description then t.objectives:SetText(info.description) t.objectives:SetWordWrap(true) else t.objectives:SetText(nil) end local style = 'Normal' if info.isComplete then style = 'Complete' elseif info.superTracked then style = 'Super' end t:SetStyle(style) local fullheight = t:GetHeight() t:Show() print('|cFF00FFFF)|r -> ', t, t:GetHeight(), fullheight) return t end mod.UpdateTracker = function(handler) print('|cFF00FF88UpdateTracker(|r|cFFFF4400' .. type(handler) .. '|r :: |cFF88FFFF' .. tostring(handler) .. '|r') local tracker = handler.Tracker local blockIndex = 0 local trackerHeight = headerHeight local w = 300 previousBlock = handler.Tracker local numWatched = handler.GetNumWatched() local numBlocks = handler.numBlocks local actualBlocks = handler.actualBlocks for watchIndex = 1, 25 do blockIndex = blockIndex + 1 if watchIndex <= numWatched then local info = handler:GetInfo(watchIndex) if info then local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info) previousBlock = currentBlock print('adding ', currentBlock.height) trackerHeight = trackerHeight + currentBlock.height numBlocks = max(numBlocks, watchIndex) actualBlocks = actualBlocks + 1 else print('|cFFFF0000Failed to draw info for index #'..watchIndex) end elseif watchIndex <= numBlocks then local used = handler.usedBlocks local free = handler.freeBlocks print('clean up dead quest block') if used[blockIndex] then used[blockIndex]:Hide() used[blockIndex]:ClearAllPoints() free[#free+1]= used[blockIndex] used[blockIndex] = nil end else print('Stopping scan at', blockIndex) break -- done with quest stuff end end handler.numWatched = numWatched handler.numBlocks = numBlocks handler.actualBlocks = actualBlocks handler:Report() previousBlock = nil if numBlocks > 0 then tracker.height = trackerHeight else tracker.height = 0 end print('|cFF00FF88)|r ->', numBlocks, 'blocks; height', tracker.height, 'last block: ') end mod.Quest.numButtons = 0 local usedButtons = mod.Quest.itemButtons local freeButtons = mod.Quest.freeButtons mod.UpdateWrapper = function() wrapperWidth = wrapperMaxWidth scrollWidth = wrapperWidth local wrapperBlocks = 0 -- Update scroll child vertical size scrollHeight = 0 for i, handler in ipairs(orderedHandlers) do mod.UpdateTracker(handler) if handler.actualBlocks >= 1 then local tracker = handler.Tracker print('setting', handler.Tracker, 'to anchor to offset', -scrollHeight) tracker:SetParent(Scroll) -- this doesn't do anything that relativeTo doesn't tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) tracker:SetSize(wrapperWidth, tracker.height) print('adding ', tracker.height) scrollHeight = scrollHeight + tracker.height end wrapperBlocks = wrapperBlocks + handler.actualBlocks end print('final scrollHeight:', scrollHeight) -- Update frame dimensions if scrollHeight > wrapperMaxHeight then print(' is larger than', wrapperMaxHeight) --ScrollBar:Show() --scrollWidth = wrapperMaxWidth - scrollBarWidth wrapperHeight = wrapperMaxHeight -- Make ThumbTexture reflect the viewing scale (smaller for longer scroll, bigger for shorter) --ScrollBar:GetThumbTexture():SetHeight((wrapperMaxHeight/scrollHeight) * (wrapperMaxHeight)) --ScrollBar:SetWidth(scrollBarWidth) --ScrollBar:SetPoint('TOPRIGHT', Scroller, 'TOPRIGHT', 0, 0) --ScrollBar:SetPoint('BOTTOMLEFT', Scroller, 'BOTTOMRIGHT', -scrollBarWidth, 0) --ScrollBar:SetMinMaxValues(1, scrollHeight - wrapperMaxHeight) else --ScrollBar:Hide() wrapperHeight = scrollHeight end scrollWidth = floor(scrollWidth+.5) scrollHeight = floor(scrollHeight+.5) wrapperWidth = floor(wrapperWidth+.5) wrapperHeight = floor(wrapperHeight+.5) headerHeight = floor(headerHeight+.5) if wrapperBlocks >= 1 then Wrapper.Background:Show() Wrapper.BackgroundR:Show() else Wrapper.Background:Hide() Wrapper.BackgroundR:Hide() return end --wrapperHeight = scrollHeight print('|cFFFFFF00params:|r scroller:', scrollWidth, 'x', scrollHeight) print('|cFFFFFF00params:|r scroll:', scrollWidth, 'x', scrollHeight) print('|cFFFFFF00params:|r wrapper:', wrapperWidth, 'x', wrapperHeight) print('|cFFFFFF00params:|r header:', headerHeight) Scroller:SetSize(wrapperWidth, wrapperHeight) Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, -headerHeight) Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT') Scroll:SetSize(scrollWidth, scrollHeight) Scroll:SetPoint('TOPLEFT', Scroller, 'TOPLEFT', 0, 0) Scroll:SetPoint('RIGHT', Scroller, 'RIGHT') --Scroller:UpdateScrollChildRect() Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight) -- update action buttons print('scroll size:', Scroll:GetSize()) print('scroller size:',Scroller:GetSize()) print('wrapper size:', Wrapper:GetSize()) print('scroll range :', floor(Scroller:GetVerticalScrollRange()+.5)) mod.UpdateActionButtons() end --- Queue any active item buttons for update for that frame mod.UpdateActionButtons = function() local previousItem for questIndex, itemButton in pairs(usedButtons) do print('|cFF00FFFF', questIndex, itemButton:GetName()) local block = mod.Quest.LogBlock[questIndex] print(block:GetTop()) if block then if IsQuestWatched(questIndex) then -- Dispatch the probe block:SetScript('OnUpdate', function() print('|cFFFFFF00probing', block:GetName()) if block:GetBottom() then print('|cFF00FF00ding ding ding!') mod.UpdateBlockAction(block, itemButton, previousItem) block:SetScript('OnUpdate', nil) end end) return else mod.FreeItemButton(block, itemButton) end end end end mod.UpdateBlockAction = function (block, itemButton, previousItem) if block:GetBottom() < Scroller:GetBottom() then print('|cFFFFFF00bottom not fully visible') if previousItem then previousItem:ClearAllPoints() previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, 4) end itemButton:ClearAllPoints() itemButton:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', Wrapper:GetLeft(), Wrapper:GetBottom()) itemButton:Show() else print('|cFF00FF00visible positions') itemButton:ClearAllPoints() itemButton:SetPoint('TOPRIGHT', UIParent, 'BOTTOMLEFT', block:GetLeft(), block:GetTop()) itemButton:Show() end end mod.UpdateItemButtonCooldown = function(button) end