Mercurial > wow > buffalo2
diff ObjectiveFrame.lua @ 14:ed642234f017
ObjectiveFrame
- implement proper tracker name text
- expanded tracker prototypes to cover "objective lines" formatting and accommodation of widget variables
- implement the progress bars for bonus objectives
ObjectiveStyle
- moved `UpdateWrapperStyle` over and renamed it to fit semantics
- change the formula for block.`height` to measure non-widget content only
- allows widgets to position relative to text
- size FontString `status` to match block.`height`
- full block height is acquired by adding block.`height` and block.`attachmentHeight` which is calculated during objective parsing
ObjectiveWidgets
- use string keys for generated widgets to deal with multiple objectives under the same questID, and maybe dungeon objectives
- wrapper buttons use a common code path
- specialized handlers for wheel scrolling moved over to fit semantics
author | Nenue |
---|---|
date | Mon, 04 Apr 2016 03:16:22 -0400 |
parents | 9455693fc290 |
children | f660f1c1e0aa |
line wrap: on
line diff
--- a/ObjectiveFrame.lua Sat Apr 02 17:46:52 2016 -0400 +++ b/ObjectiveFrame.lua Mon Apr 04 03:16:22 2016 -0400 @@ -5,9 +5,10 @@ -- Created: 3/30/2016 12:49 AM local B = select(2,...).frame local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local ipairs, max, min, unpack, floor, pairs, tostring, type = ipairs, max, min, unpack, floor, pairs, tostring, type +local ipairs, max, min, unpack, floor, pairs, tostring, type, band = ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent +local Quest, Bonus, Cheevs = mod.Quest, mod.Bonus, mod.Cheevs local CreateFrame = CreateFrame local print = B.print('Objectives') local unitLevel = 1 @@ -40,86 +41,32 @@ local headerOutline, headerColor, headerSpacing = 'OUTLINE', {1,1,1,1}, 2 local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0} ---- These are mostly aesthetic choices so it lives here +mod.InitializeWrapper = function() -local Scroller_OnShow = function() - Wrapper.watchMoneyReasons = 0; - mod.UpdateWrapper() - mod.SetEvents() - for i, region in ipairs(Wrapper.headerComplex) do - region:Show() - end -end - -local Scroller_OnHide = function() - local self = Wrapper - Wrapper:UnregisterAllEvents() - Wrapper:SetScript('OnEvent', nil) - for i, region in ipairs(Wrapper.headerComplex) do - region:Hide() - end -end - -local Scroller_OnMouseWheel = function(self, delta) - local r = Scroll:GetHeight() - Scroller:GetHeight() - local s = B.Conf.ObjectiveScroll - delta * floor(r/5+.5) - local from = self:GetVerticalScroll() - if s >= r then - s = r - elseif s < 1 then - s = 0 - end - self:SetVerticalScroll(s) - B.Conf.ObjectiveScroll = s - print('|cFF00FF00OnMouseWheel', 'from = ', from, 'scroll =', s, ' range =', r, 'current =', self:GetVerticalScroll()) - - mod.UpdateActionButtons('SCROLLING') -end - -local WrapperCloseButton_OnClick = function(self) - Wrapper:Minimize() - if B.Conf.FrameState[Wrapper:GetName()] == 1 then - self:GetNormalTexture():SetTexture([[Interface\PaperDollInfoFrame\UI-Character-SkillsPageDown-Up]]) - self:GetPushedTexture():SetTexture([[Interface\PaperDollInfoFrame\UI-Character-SkillsPageDown-Down]]) - else - self:GetNormalTexture():SetTexture([[Interface\PaperDollInfoFrame\UI-Character-SkillsPageUp-Up]]) - self:GetPushedTexture():SetTexture([[Interface\PaperDollInfoFrame\UI-Character-SkillsPageUp-Down]]) - end -end -local WrapperCloseButton_OnMouseWheel = function(self, delta) -end - -mod.InitializeTrackers = function() - + mod.SetBlockStyle(Scroller, 'Scroller', 'Normal') + mod.SetBlockStyle(Scroller, 'Scroll', 'Normal') + mod.SetBlockStyle(Wrapper, 'Wrapper', 'Normal') 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.title:SetText(name) + tracker.title:SetText(handler.displayName) mod.SetBlockStyle(tracker, 'Tracker', 'Normal') - 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.close:SetScript('OnMouseWheel', WrapperCloseButton_OnMouseWheel) - Wrapper:SetPoint(unpack(wrapperPosition)) + + mod.InitializeWrapperWidgets() if B.Conf.ObjectiveTrackerMinimized then Scroller_OnShow(Scroller) end @@ -208,211 +155,12 @@ -local segments = {'Left', 'Right', 'Tile'} -mod.UpdateWrapperStyle = function() - --[[for _, segment in ipairs(segments) do - local texture, a1, a2, a3, a4, width = unpack(mod.defaults.Style.Wrapper.BackgroundComplex[segment]) - Wrapper['Background'..segment]:SetAtlas(texture) - Wrapper['Background'..segment]:SetTexCoord(a1, a2, a3, a4) - if width then - Wrapper['Background'..segment]:SetWidth(width) - end - end]] -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) - local print = B.print('ObjectiveBlockParse') - print(' |cFF00FFFFUpdateTrackerBlock('..blockIndex..'|r') - if not blockIndex or not info then - return - end - - local mainStyle = 'Normal' - local subStyle +mod.UpdateTracker = function(handler) local tracker = handler.Tracker - - local t = handler:GetBlock(blockIndex) - if previousBlock then - t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0) - t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) - end - --print(t:GetName(), t:GetSize()) - --print(t:GetPoint(1)) - - t.info = info - - if info.questID then handler.QuestBlock[info.questID] = t end - 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) - - t.attachmentHeight = 0 - if info.isComplete then - t.status:Show() - t.status:SetText(info.completionText) - elseif info.numObjectives >= 1 then - t.attachmentHeight = textSpacing - t.status:Show() - print(' - objective lines:', info.numObjectives, 'can wrap:', t.status:CanWordWrap()) - - local text = '' - - --- todo: implement objective displays - -- in an accumulator loop, call upon handler for the appropriate display frame, each defining: - -- * height - height of whatever display widget is involved in conveying the task - -- * lines - number of non-wrapped text lines to account for line space; may be discarded depending on things - -- * money - boolean that determines listening for money events or not - -- * progress - number ranging 0 to 2 indicating none/partial/full completion respectively - text = mod.UpdateObjectives(t, info, text) - - t.status:SetText(text) - t.status:SetWordWrap(true) - - elseif info.description then - t.status:SetText(info.description) - t.status:SetWordWrap(true) - else - t.status:SetText(nil) - end - - if info.isComplete then - mainStyle = 'Complete' - end - if info.superTracked then - subStyle = 'Super' - elseif info.isDaily then - subStyle = 'Daily' - end - - if info.specialItem and not info.itemButton then - print(' - |cFF00FFFFgenerating item button for info set') - info.itemButton = mod.SetItemButton(t, info) - else - --info.itemButton = nil - end - - if info.level then - local levelDiff = unitLevel - info.level - if levelDiff > 9 then - t.title:SetTextColor(0.7, 0.7, 0.7, 1) - elseif levelDiff > 1 then - t.title:SetTextColor(0.5, 1, 0.5, 1) - elseif levelDiff < -1 then - t.title:SetTextColor(1, 0.4, 0.25, 1) - elseif levelDiff < -4 then - t.title:SetTextColor(1, 0, 0, 1) - else - t.title:SetTextColor(1,1,1,1) - end - end - - - if Devian and Devian.InWorkspace() then - t.debugText:Show() - t.debugText:SetText(tostring(blockIndex) .. '\n' .. tostring(info.itemButton and info.itemButton:GetName()) .. "\n" .. (info.level and info.level or '-')) - end - - --- metrics are calculated in SetStyle - t:SetStyle('TrackerBlock', handler.name, mainStyle, subStyle) - t:Show() - - print(' |cFF00FFFF)|r -> ', t, t:GetHeight()) - return t -end - -mod.UpdateObjectives = function(block, info, text) - local print = B.print('ObjectiveBlockParse') - - local attachmentHeight = block.attachmentHeight - if info.description then - print(' -- has description text:', select('#', info.description), info.description) - text = info.description - end - local completionScore, completionMax = 0, 0 - for o, obj in ipairs(info.objectives) do - --- achievement criteria - if obj.flags then - - - if bit.band(obj.flags, 0x00000001) > 0 then - obj.type = 'ProgressBar' - elseif bit.band(obj.flags, 0x00000002) then - obj.type = 'Hidden' - obj.widget = nil - else - obj.type = 'Text' - obj.widget = nil - text = text .. ((text == '') and "" or "\n") .. obj.text - end - - print('obj.type =', obj.type) - print(' ** qtyStr:', obj.quantityString, 'qty:', obj.quantity, 'assetID:', obj.assetID) - obj.widget = mod.SetWidget(obj, info) - if obj.finished then - obj.progress = 2 - elseif obj.quantity > 0 then - obj.progress = 1 - else - obj.progress = 0 - end - - - --- none of the above (most quests) - else - local line = obj.text - local color = '00FFFF' - if obj.finished then - obj.progress = 2 - color = 'FFFFFF' - elseif obj.type == 'monster' then - color = 'FFFF00' - elseif obj.type == 'item' then - color = '44DDFF' - elseif obj.type == 'object' then - color = 'FF44DD' - end - text = text .. ((text == '') and "" or "\n") .. '|cFF'..color.. line .. '|r' - end - - if obj.widget then - - obj.widget:Show() - obj.widget:SetPoint('TOPLEFT', block.objectives, 'BOTTOMLEFT', 0, -attachmentHeight) - print('have a widget, height is', obj.widget.height) - attachmentHeight = attachmentHeight + obj.widget.height - completionScore = completionScore + obj.progress - completionMax = completionMax + 2 - end - - end - - block.completionScore = completionScore / completionMax - block.attachmentHeight = attachmentHeight - - return text -end - -mod.UpdateTracker = function(handler) - print('|cFF00FF88UpdateTracker(|r|cFFFF4400' .. type(handler) .. '|r :: |cFF88FFFF' .. tostring(handler) .. '|r') - local tracker = handler.Tracker + print('|cFFFF4400'..tracker:GetName().. '|r:Update()') local blockIndex = 0 local trackerHeight = headerHeight - local w = 300 + previousBlock = tracker.title local numWatched = handler.GetNumWatched() @@ -425,12 +173,12 @@ if info then local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info) previousBlock = currentBlock - print('|cFF00FF00'..currentBlock:GetName()..'|r', currentBlock.height) + print(' |cFFFFFF00'..watchIndex..'|r', '|cFF00FF00'..currentBlock:GetName()..'|r', currentBlock.height) trackerHeight = trackerHeight + currentBlock.height numBlocks = max(numBlocks, watchIndex) actualBlocks = actualBlocks + 1 else - print('|cFFFF0000Failed to draw info for index #'..watchIndex) + print(' |cFFFF0000Failed to draw info for index #'..watchIndex) end elseif watchIndex <= numBlocks then @@ -444,7 +192,7 @@ used[blockIndex] = nil end else - print('Stopping scan at', blockIndex) + print(' |cFFFF9900END|r @', blockIndex) break -- done with quest stuff end end @@ -452,36 +200,251 @@ handler.numBlocks = numBlocks handler.actualBlocks = actualBlocks handler:Report() - previousBlock = nil - if numBlocks > 0 then + + if numBlocks >= 1 then + previousBlock = nil tracker.height = trackerHeight else tracker.height = 0 end - print('|cFF00FF88)|r ->', numBlocks, 'blocks; height', tracker.height, 'last block: ') + return tracker.numWatched, tracker.numAll 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) + local print = B.print('BlockParse') + print(' Read list item |cFF00FFFF'..blockIndex..'|r') + if not blockIndex or not info then + return + end + local tracker = handler.Tracker + local t = handler:GetBlock(blockIndex) + t.handler = handler + t.info = info + t.mainStyle = 'Normal' + t.subStyle = nil + + info.blockIndex = blockIndex + if info.questID then handler.QuestBlock[info.questID] = t end + if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end + if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end + handler.BlockInfo[blockIndex] = info + + + t.attachmentHeight = 0 + --if info.isComplete then + --t.status:Show() + --t.status:SetText(info.completionText) + --end + + if info.numObjectives >= 1 then + t.attachmentHeight = textSpacing + t.status:Show() + print(' lines to build:', info.numObjectives) + + local text = '' + + mod.UpdateObjectives(t, info, text) + elseif info.description then + t.status:SetText(info.description) + else + t.status:SetText(nil) + end + t.title:SetText(info.title) + + + if info.specialItem and not info.itemButton then + print(' - |cFF00FFFFgenerating item button for info set') + info.itemButton = mod.SetItemButton(t, info) + else + --info.itemButton = nil + end + + handler.SetBlockTags(t, info) + + if previousBlock then + t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0) + t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) + print(' anchor to|cFF0088FF', previousBlock:GetName()) + end + + --- metrics are calculated in SetStyle + t:SetStyle('TrackerBlock', handler.name, t.mainStyle, t.subStyle) + t:Show() + + print(' |cFF00FFFF)|r -> ', t, t:GetHeight()) + + + if Devian and Devian.InWorkspace() then + t.debugText:Show() + t.debugText:SetText(tostring(blockIndex) .. '\n' .. tostring(info.itemButton and info.itemButton:GetName()) .. "\n" .. (tostring(t.mainStyle) .. '/' .. tostring(t.subStyle))) + end + return t +end + +mod.UpdateObjectives = function(block, info, text) + local print = B.print('BlockLine') + print(' |cFF00FF00objective updates for', block:GetName()) + + local attachmentHeight = block.attachmentHeight + if info.description then + print(' -- has description text:', select('#', info.description), info.description) + text = info.description + end + local completionScore, completionMax = 0, 0 + + for i, line in ipairs(info.objectives) do + print(' |cFF88FF00objective', i) + block.handler.ParseObjective(line, info) + + if line.title then + info.title = line.title + line.title = nil + end + + + if line.widget then + line.widget:Show() + line.widget:SetParent(block) + line.widget:SetPoint('TOPLEFT', block.status, 'BOTTOMLEFT', 0, -attachmentHeight ) + print(' has a widget, height is', line.widget.height) + attachmentHeight = attachmentHeight + line.widget.height + completionScore = completionScore + line.progress + completionMax = completionMax + 2 + end + + if line.displayText then + print(' has text') + text = text .. ((text == '') and "" or "\n") .. '|cFF'..line.displayColor.. line.displayText .. '|r' + end + + end + + block.completionScore = completionScore / completionMax + block.attachmentHeight = attachmentHeight + + block.status:SetText(text) +end + +--- Objective parsers +-- defines the following variables +-- * height - height of whatever display widget is involved in conveying the task +-- * lines - number of non-wrapped text lines to account for line space; may be discarded depending on things +-- * money - boolean that determines listening for money events or not +-- * progress - number ranging 0 to 2 indicating none/partial/full completion respectively +mod.Tracker.ParseObjective = function(line, info) + + if line.finished then + line.progress = 2 + elseif line.quantity > 0 then + line.progress = 1 + else + line.progress = 0 + end + +end + +Bonus.ParseObjective = function(line, info) + local print = B.print('BonusLine') + for k,v in pairs(line) do + print(k, v) + end + + line.displayColor = 'FFFFFF' + if line.text and not info.title then + line.title = line.text + else + line.displayText = line.text + end + + line.progess = 0 + if line.objectiveType == 'progressbar' then + print(' |cFFFF0088==|r', line.type, line.text) + line.widgetType = 'ProgressBar' + print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) + line.value = GetQuestProgressBarPercent(info.questID) or 0 + line.maxValue = 100 + if line.value >= line.maxValue then + line.progress = 1 + elseif line.value > 0 then + line.progress = 2 + end + line.format = PERCENTAGE_STRING + line.widget = mod.SetWidget(line, info, 'ProgressBar', info.questID..'-'..line.index) + print('line.type =', line.type) + print(' ** qtyStr:', line.quantityString, 'qty:', line.value, 'assetID:', line.questID) + else + line.widget = nil + end +end + +Cheevs.ParseObjective = function(line, info) + local print = B.print('CheevsLine') + line.progress = 0 + if line.flags then + if band(line.flags, 0x00000001) > 0 then + line.format = "%d/%d" + line.widget = mod.SetWidget(line, info, 'ProgressBar', line.criteriaID) + elseif band(line.flags, 0x00000002) then + line.widget = nil + else + line.widget = nil + line.displayColor = 'FFFFFF' + line.displayText = line.text + + end + end + print('line.type =', line.type) + print(' ** qtyStr:', line.quantityString, 'qty:', line.quantity, 'assetID:', line.assetID) +end + +Quest.ParseObjective = function(line) + local print = B.print('QuestLine') + print(' |cFFFF0088', line.type) + local color = '00FFFF' + line.progress = 0 + if line.finished then + line.progress = 2 + color = 'FFFFFF' + elseif line.type == 'monster' then + color = 'FFFF00' + elseif line.type == 'item' then + color = '44DDFF' + elseif line.type == 'object' then + color = 'FF44DD' + end + line.displayColor = color + line.displayText = line.text +end + + mod.Quest.numButtons = 0 local usedButtons = mod.Quest.itemButtons local freeButtons = mod.Quest.freeButtons mod.UpdateWrapper = function() unitLevel = UnitLevel('player') - wrapperWidth = wrapperMaxWidth - scrollWidth = wrapperWidth + wrapperWidth = mod.Conf.Wrapper.WrapperWidth + scrollWidth = mod.Conf.Wrapper.WrapperWidth local wrapperBlocks = 0 -- Update scroll child vertical size scrollHeight = 0 for i, handler in ipairs(orderedHandlers) do mod.UpdateTracker(handler) + local tracker = handler.Tracker if handler.actualBlocks >= 1 then - local tracker = handler.Tracker - print('setting', handler.Tracker, 'to anchor to offset', -scrollHeight) tracker:SetParent(Scroll) tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) tracker:SetSize(wrapperWidth, tracker.height) - print('adding ', tracker.height) + print('|cFF00FFFF'..tracker:GetName()..'|r h:|cFF00FF00', tracker.height, '|r y:|cFF00FF00', -scrollHeight) scrollHeight = scrollHeight + tracker.height + tracker:Show() + else + tracker:Hide() end wrapperBlocks = wrapperBlocks + handler.actualBlocks end @@ -513,18 +476,13 @@ end return end - --wrapperHeight = scrollHeight + --[[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) + print('|cFFFFFF00params:|r scroller:', scrollWidth .. ',' .. scrollHeight, 'scroll:', scrollWidth .. ',' .. scrollHeight, + 'wrapper:', wrapperWidth .. ',' .. wrapperHeight, + 'header:', headerHeight)]] - mod.SetBlockStyle(Scroller, 'Scroller', 'Normal') - mod.SetBlockStyle(Scroller, 'Scroll', 'Normal') - mod.SetBlockStyle(Wrapper, 'Wrapper', 'Normal') - - Scroller:SetSize(wrapperWidth, wrapperHeight) + --Scroller:SetSize(wrapperWidth, wrapperHeight) Scroller:SetPoint('TOPLEFT', Wrapper, 'TOPLEFT', 0, 0) Scroller:SetPoint('BOTTOMRIGHT', Wrapper, 'BOTTOMRIGHT') @@ -536,13 +494,14 @@ --Scroller:UpdateScrollChildRect() Wrapper:SetSize(wrapperWidth, wrapperHeight) - -- update action buttons + --[[ update action buttons print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(), '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(), '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(), '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5) ) - mod.UpdateActionButtons('FULL_UPDATE') + mod.UpdateActionButtons() + --]] end