Mercurial > wow > buffalo2
changeset 7:5301c68f28d8
TrackerBlock
- use IsModifiedClick function to determine appropriate OnClick actions
- handle 'CHATLINK' modifier
- handle 'TOGGLEQUESTWATCH' modifier
TrackerBlockObjectives
- use a generic framework to manage frame creation for various criteria tracker types:
- ProgressBar when Blizzard flag data indicates so
- skip when Blizzard flag data indicates so
- DynamicText otherwise
- events related to the criteria are registered in the criteria frame, and unregistered when the frame is hidden, either by destruction of its parent or completion
author | Nenue |
---|---|
date | Fri, 01 Apr 2016 12:27:05 -0400 |
parents | 589de8ea05b9 |
children | 7923243ae972 |
files | BuffButton.lua ObjectiveFrame.lua ObjectiveUI.lua ObjectiveWidgets.xml |
diffstat | 4 files changed, 228 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/BuffButton.lua Fri Apr 01 01:30:42 2016 -0400 +++ b/BuffButton.lua Fri Apr 01 12:27:05 2016 -0400 @@ -159,7 +159,8 @@ -- Background decorations layer if not d[i] then d[i] = CreateFrame('Frame', buffName..i..'Decor', _G.UIParent, 'VeneerDecorTemplate') - --RegisterStateDriver(d[i], "visibility", "[petbattle] [vehicleui] hide") + -- todo: sort out a way to fix this without creating taint issues + RegisterStateDriver(d[i], "visibility", "[petbattle] [vehicleui] hide") end d[i]:SetPoint('BOTTOMLEFT', guide.icon, 'BOTTOMLEFT', -buffBorder, -buffBorder)
--- a/ObjectiveFrame.lua Fri Apr 01 01:30:42 2016 -0400 +++ b/ObjectiveFrame.lua Fri Apr 01 12:27:05 2016 -0400 @@ -83,13 +83,13 @@ }, Active = { Title = { - Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, + Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, .4}, }, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, BackgroundFullWidth = true }, Text = { - Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1}, }, + Gradient = { MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, .2}, }, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, BackgroundFullWidth = true @@ -107,6 +107,28 @@ BackgroundFullWidth = true } }, + CheevNormal = { + + Title = { + Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, .19}}, + Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, + }, + Text = { + Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, .12}}, + Font = {textFont, textSize, textOutline}, Spacing = textSpacing, + }, + }, + CheevComplete = { + + Title = { + Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, .19}}, + Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, + }, + Text = { + Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, .12}}, + Font = {textFont, textSize, textOutline}, Spacing = textSpacing, + }, + } } } @@ -137,7 +159,8 @@ local Scroller_OnMouseWheel = function(self, delta) local r = Scroll:GetHeight() - Scroller:GetHeight() - local s = self:GetVerticalScroll() - delta * floor(r/5+.5) + local s = B.Conf.ObjectiveScroll - delta * floor(r/5+.5) + local from = self:GetVerticalScroll() if r == 0 then return end if s >= r then s = r @@ -145,7 +168,8 @@ s = 0 end self:SetVerticalScroll(s) - print(s, r, self:GetVerticalScroll()) + B.Conf.ObjectiveScroll = s + print('|cFF00FF00OnMouseWheel', 'from = ', from, 'scroll =', s, ' range =', r, 'current =', self:GetVerticalScroll()) mod.UpdateActionButtons('SCROLLING') end @@ -322,7 +346,7 @@ block.objectives:SetSpacing(textSpacing) block.objectives:SetWordWrap(true) - local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight() + local titleHeight, textHeight = block.title:GetStringHeight(), block.objectives:GetStringHeight() + block.attachmentHeight local blockHeight = titleHeight + titleSpacing2 + textHeight + textSpacing2 local blockWidth = wrapperMaxWidth @@ -387,6 +411,7 @@ info.blockIndex = blockIndex handler.BlockInfo[blockIndex] = info + t.Select = handler.Select t.Open = handler.Open t.Remove = handler.Remove @@ -395,18 +420,16 @@ t:SetScript('OnMouseDown', handler.OnMouseDown) t.title:SetText(info.title) + t.attachmentHeight = 0 if info.isComplete then t.objectives:Show() t.objectives:SetText(info.completionText) elseif info.numObjectives >= 1 then + t.attachmentHeight = textSpacing t.objectives:Show() print(' - objective lines:', info.numObjectives, 'can wrap:', t.objectives:CanWordWrap()) local text = '' - if info.description then - print(' -- has description text:', select('#', info.description), info.description) - text = info.description - end --- todo: implement objective displays -- in an accumulator loop, call upon handler for the appropriate display frame, each defining: @@ -454,7 +477,11 @@ end mod.UpdateObjectives = function(block, info, text) - local attachmentHeight = 0 + local attachmentHeight = block.attachmentHeight + if info.description then + print(' -- has description text:', select('#', info.description), info.description) + text = info.description + end for o, obj in ipairs(info.objectives) do --- achievement criteria if obj.flags then @@ -462,7 +489,6 @@ if bit.band(obj.flags, 0x00000001) > 0 then obj.type = 'ProgressBar' - obj.widget = mod.SetWidget(obj, info) elseif bit.band(obj.flags, 0x00000002) then obj.type = 'Hidden' obj.widget = nil @@ -472,7 +498,9 @@ text = text .. ((text == '') and "" or "\n") .. obj.text end - print(obj.type, obj.text, obj.quantityString) + print('obj.type =', obj.type) + print(' ** qtyStr:', obj.quantityString, 'qty:', obj.quantity, 'assetID:', obj.assetID) + obj.widget = mod.SetWidget(obj, info) --- none of the above (most quests) else local line = obj.text @@ -490,6 +518,10 @@ 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 end @@ -620,8 +652,9 @@ 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('TOPLEFT', Scroller, 'TOPLEFT', 0, B.Conf.ObjectiveScroll or 0) Scroll:SetPoint('RIGHT', Scroller, 'RIGHT') --Scroller:UpdateScrollChildRect()
--- a/ObjectiveUI.lua Fri Apr 01 01:30:42 2016 -0400 +++ b/ObjectiveUI.lua Fri Apr 01 12:27:05 2016 -0400 @@ -8,6 +8,7 @@ local print = B.print('Objectives') local Tracker, AutoQuest, Quest, Cheevs = mod.Tracker, mod.AutoQuest, mod.Quest, mod.Cheevs local itemButtonSize, itemButtonSpacing = 36, 1 +local tremove, tremovebyval = table.remove, table.removebyval -------------------------------------------------------------------- --- Tracker-specific widgets and their handlers @@ -21,27 +22,28 @@ end Tracker.OnMouseUp = function(self, button) - if self.initialButton == 'LeftButton' then - self:Select() - mod.UpdateWrapper() - if self.modShift then + if self.modChatLink and ChatEdit_GetActiveWindow() then + self:Link() + elseif self.modQuestWatch then self:Remove() + else + self:Select() end elseif button == 'RightButton' then self:Open() end self.initialButton = nil - self.modShift = nil + self.modChatLink = nil + self.modQuestWatch = nil print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r ->',self.info.trackingID) end Tracker.OnMouseDown = function(self, button) self.initialButton = button - self.modShift = IsShiftKeyDown() - if button == 'LeftButton' then - self:SetStyle('Active') - end + self.modChatLink = IsModifiedClick("CHATLINK") + self.modQuestWatch = IsModifiedClick("QUESTWATCHTOGGLE") + self:SetStyle('Active') print(self.info.title) end @@ -55,6 +57,13 @@ Quest.name = "Quests" Quest.Select = function(self) SetSuperTrackedQuestID(self.info.questID) + mod.UpdateWrapper() +end +Quest.Link = function(self) + local questLink = GetQuestLink(block.questLogIndex); + if ( questLink ) then + ChatEdit_InsertLink(questLink); + end end Quest.Open = function(self) QuestMapFrame_OpenToQuestDetails(self.info.questID) @@ -75,6 +84,13 @@ --- CHEEVS Cheevs.Select = function(self) end +Cheevs.Link = function(self) + local achievementLink = GetAchievementLink(self.info.cheevID); + if ( achievementLink ) then + ChatEdit_InsertLink(achievementLink); + end + self:SetStyle('CheevNormal') +end Cheevs.Open = function(self) if ( not AchievementFrame ) then @@ -212,33 +228,129 @@ end ----------------------------------------- --- Progress slider for achievements, and area objecitves --- Stored by criteria ID to account for multiple bars in one cheev -Tracker.SetProgress = function(criteria, info) +-- Criteria frames + +--[[ + text = description, + type = type, + finished = completed, + quantity = quantity, + requiredQuantity = requiredQuantity, + characterName = characterName, + flags = flags, + assetID = assetID, + quantityString = quantityString, + criteriaID = criteriaID, +]] +local newWidgetID = 0 +mod.WidgetRegistry = {} +local wr = mod.WidgetRegistry + +--- Get a usable widget for the given achievement criteria set. + -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block +mod.SetWidget = function(obj, info) + local widgetType = obj.type + local widget + + if not wr[widgetType] or #wr[widgetType].free == 0 then + print('VeneerObjectiveCriteria' .. widgetType) + widget = CreateFrame('Frame', nil, VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) + end + local free = wr[widgetType].free + local used = wr[widgetType].used + + widget = tremove(free) + local index = #used+1 + used[index] = widget + wr[widgetType].usedIndex[widget] = index + widget.info = obj + widget.parentInfo = info + mod.InitializeWidget(widget) + + return widget end -mod.WidgetRegistry = {} -local wr = mod.WidgetRegistry -mod.SetWidget = function(criteria, info) - local widget - if not wr[criteria.type] then - print('|cFFFF4400[[WidgetTemplate]]|r', criteria.type) - wr[criteria.type] = { free = {}, used = {}, } +--- Fired by OnLoad() when a new frame is spawned +mod.RegisterWidget = function(frame) + local widgetType = frame.widgetType + local obj = frame.info + if not wr[frame.widgetType] then + print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) + wr[widgetType] = { lastn = 0, free = {}, used = {}, usedIndex = {}, freeIndex = {} } end - if #wr[criteria.type].free == 0 then + tinsert(wr[frame.widgetType].free, frame) +end +mod.InitializeWidget = setmetatable({}, { + __call = function(t, frame) + -- todo: config pull + local maxWidth = 250 - local frameID = #wr[criteria.type].free + #wr[criteria.type].used - widget = CreateFrame('Frame', 'VeneerCriteria' .. criteria.type .. frameID, VeneerObjectiveWrapper, 'VeneerObjectiveCriteria' .. criteria.type) + frame:SetWidth(maxWidth) + mod.UpdateWidget[frame.widgetType](frame) + frame:SetScript('OnEvent', mod.UpdateWidget[frame.widgetType]) + if frame.info.isCurrency then + frame:RegisterEvent('CHAT_MSG_CURRENCY') + frame:RegisterEvent('CURRENCY_LIST_UPDATE') + end + frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') + frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') + frame:RegisterEvent('CRITERIA_UPDATE') + frame:RegisterEvent('CRITERIA_COMPLETE') + frame:RegisterEvent('CRITERIA_EARNED') + + return t[frame.widgetType](frame) + end, +}) +mod.UpdateWidget = setmetatable({}, { + __call = function(t, frame) + if not frame.widgetType then + error('Invalid widget template, needs .widgetType') + return + end + + return t[frame.widgetType](frame) + end +}) + +mod.ReleaseWidget = function(frame) + local reg = wr[frame.widgetType] + if reg and reg.usedIndex[frame] then + tremove(reg.used, reg.usedIndex[frame]) + reg.usedIndex[frame] = nil + frame:UnregisterAllEvents() + tinsert(reg.free, frame) end end -mod.RegisterWidget = function(frame) - tinsert(wr[frame.widgetType].free, frame) + +mod.WidgetParams = { + ['ProgressBar'] = { + height = 20, + caption = {}, + quantityString = {SetFontObject = _G.VeneerFontNormal} + } +} + +mod.InitializeWidget.ProgressBar = function(self) + local params = mod.WidgetParams[self.widgetType] + self.height = params.height + self:SetHeight(20) + self.bg:SetHeight(20) + self.fg:SetHeight(18) + self.fg:SetPoint('BOTTOMLEFT', self.bg, 'BOTTOMLEFT', 1, 1) + self.quantityString:SetFontObject(params.quantityString.SetFontObject) + self.quantityString:SetText(self.info.quantityString) end -mod.InitializeWidget = function(frame) + +mod.UpdateWidget.ProgressBar = function (self) + local quantity, requiredQuantity = self.info.quantity, self.info.requiredQuantity + self.fg:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) + if self.info.finished then + self.fg:SetWidth(self.bg:GetWidth() - 2) + elseif quantity == 0 then + self.fg:Hide() + else + self.fg:Show() + self.fg:SetWidth(self:GetWidth() * (quantity / requiredQuantity)) + end end -mod.ReleaseWidget = function(frame) - - if tContains(wr[frame.widgetType], frame) then - end -end \ No newline at end of file
--- a/ObjectiveWidgets.xml Fri Apr 01 01:30:42 2016 -0400 +++ b/ObjectiveWidgets.xml Fri Apr 01 12:27:05 2016 -0400 @@ -1,7 +1,7 @@ <Ui> <!-- houses objective widget templates --> - <Frame name="VeneerObjectiveCriteriaProgressBar" virtual="true"> + <Frame name="VeneerObjectiveCriteriaProgressBar" virtual="true" hidden="true"> <Size x="250" y="30" /> <Scripts> <OnLoad> @@ -20,15 +20,51 @@ </Scripts> <Layers> <Layer level="BACKGROUND"> - <Texture SetAllPoints="true" name="$parentBackground" parentKey="bg" setAllPoints="true"> + <Texture SetAllPoints="true" name="$parentBackground" parentKey="bg"> <Color r="0" g="0" b="0" a="0.25" /> + <Anchors> + <Anchor point="BOTTOMLEFT" /> + <Anchor point="TOPRIGHT" /> + </Anchors> </Texture> </Layer> <Layer level="ARTWORK"> + <Texture SetAllPoints="true" name="$parentForeground" parentKey="fg"> + <Color r="1" g="1" b="1" a="1" /> + <Anchors> + <Anchor point="TOPLEFT" x="1" y="-1" /> + </Anchors> + </Texture> </Layer> <Layer level="OVERLAY"> <FontString name="$parentQuantityString" parentKey="quantityString" inherits="VeneerCriteriaFont"> + <Anchors> + <Anchor point="CENTER" /> + </Anchors> + </FontString> + </Layer> + </Layers> + </Frame> + + <Frame name="VeneerObjectiveCriteriaEvent" virtual="true" hidden="true"> + <Size x="250" y="24" /> + <Scripts> + <OnLoad> + self.widgetType = 'Event' + self.lines = 1 + Veneer.ObjectiveTracker.RegisterWidget(self) + </OnLoad> + <OnShow> + Veneer.ObjectiveTracker.InitializeWidget(self) + </OnShow> + <OnHide> + Veneer.ObjectiveTracker.ReleaseWidget(self) + </OnHide> + </Scripts> + <Layers> + <Layer level="OVERLAY"> + <FontString name="$parentQuantityString" parentKey="quantityString" inherits="VeneerCriteriaFont"> </FontString> </Layer>