Mercurial > wow > buffalo2
diff ObjectiveTracker/ObjectiveWidgets.lua @ 23:e837384ac363
Separating objective tracker module
author | Nenue |
---|---|
date | Sun, 10 Apr 2016 04:35:32 -0400 |
parents | ObjectiveWidgets.lua@9b3fa734abff |
children | 66b927b46776 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/ObjectiveWidgets.lua Sun Apr 10 04:35:32 2016 -0400 @@ -0,0 +1,439 @@ +local B = select(2,...).frame +local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local print = B.print('WidgetFactory') +local UIParent = UIParent +local GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown +local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll +local tremove, tinsert, tContains, pairs, setmetatable = tremove, tinsert, tContains, pairs, setmetatable + +--- frame refs +local Wrapper = _G.VeneerObjectiveWrapper +local Scroller = Wrapper.scrollArea +local CloseButton = Wrapper.CloseButton +local QuestMapButton = Wrapper.QuestMapButton +local Scroll = _G.VeneerObjectiveScroll + +local panelButtons = { + CloseButton = { + closedSwatch = { + [[Interface\Buttons\UI-Panel-QuestHideButton]], + [[Interface\Buttons\UI-Panel-QuestHideButton]], + 0, 0.5, 0.5, 1, + 0.5, 1, 0.5, 1, + }, + openSwatch = { + [[Interface\Buttons\UI-Panel-QuestHideButton]], + [[Interface\Buttons\UI-Panel-QuestHideButton]], + 0.5, 1, 0.5, 1, + 0, 0.5, 0.5, 1, + }, + parent = 'VeneerObjectiveWrapper' + }, + QuestMapButton = { + closedSwatch = { + [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], + [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], + 0, 1, 0.5, 1, + 0, 1, 0, 0.5, + }, + openSwatch = { + [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], + [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]], + 0, 1, 0, 0.5, + 0, 1, 0.5, 1, + } + } +} + +local Scroller_OnShow = function() + Wrapper.watchMoneyReasons = 0; + --mod:Update() + --mod:OnInitialize() + 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() + print('|cFF00FF00OnMouseWheel', 'scroll =', s) + 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 UpdatePanelButton = function (self, state) + state = state and B.Conf.FrameState[state] or 1 + local swatch = (state == 1) and self.openSwatch or self.closedSwatch + self:SetNormalTexture(swatch[1]) + self:SetPushedTexture(swatch[2]) + if #swatch >= 6 then + self:GetNormalTexture():SetTexCoord(swatch[3], swatch[4], swatch[5], swatch[6]) + end + if #swatch == 10 then + self:GetPushedTexture():SetTexCoord(swatch[7], swatch[8], swatch[9], swatch[10]) + end + +end + +local OnClick = {} +OnClick.CloseButton = function(self) + Wrapper:Minimize() + UpdatePanelButton(self, self.parent) +end + +OnClick.QuestMapButton = function() + ToggleWorldMap() +end + + +mod.InitializeWidgets = function() + --- tracker scroll + Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel) + Scroller:SetScript('OnShow', Scroller_OnShow) + Scroller:SetScript('OnHide', Scroller_OnHide) + for name, swatch in pairs(panelButtons) do + local source = swatch and swatch or panelButtons.CloseButton + local button = Wrapper[name] + button.parent = swatch.parent + button.openSwatch = source.openSwatch + button.closedSwatch = source.closedSwatch + if OnClick[name] then + button:SetScript('OnClick', OnClick[name]) + end + UpdatePanelButton(button, button.parent) + end +end + +---------------------------------------------------------------------------------------- +--- XML and script code lifted from "QuestKing 2" by Barjack, +--- found at http://mods.curse.com/addons/wow/questking +---------------------------------------------------------------------------------------- +local usedButtons = mod.Quest.itemButtons +local freeButtons = mod.Quest.freeButtons +mod.SetItemButton = function(block, info) + local itemInfo = info.specialItem + if not itemInfo then + return + end + + --- Quest.GetInfo().specialItem :: {link = link, charges = charges, icon = icon, start = start, duration = duration, enable = enable} + + + local itemButton + if not info.itemButton then + if #freeButtons >= 1 then + print(' |cFF00FFFFfound a free button') + itemButton = freeButtons[#freeButtons] + freeButtons[#freeButtons] = nil + if itemButton.block then + itemButton.block.itemButton = nil + itemButton.block = nil + end + else + local buttonIndex = mod.Quest.numButtons + #freeButtons + 1 + itemButton = CreateFrame('Button', 'VeneerQuestItemButton' .. buttonIndex, UIParent, 'VeneerItemButtonTemplate') + itemButton.buttonIndex = buttonIndex + itemButton:SetSize(36, 36) + itemButton:GetNormalTexture():SetSize(36 * (5/3), 36 * (5/3)) + print(' |cFFFF4400starting new button', itemButton:GetName()) + end + mod.Quest.numButtons = mod.Quest.numButtons + 1 + else + itemButton = info.itemButton + print(' |cFF00FF00found assigned button', itemButton:GetName()) + + end + -- set values + + info.itemButton = itemButton + usedButtons[info.questID] = itemButton + print(' |cFF8800FFassigning|r', itemButton:GetName(), 'to quest|cFF00FF00', info.questID, '|rat|cFFFFFF00', block:GetName(),'|r') + + for k,v in pairs(usedButtons) do + print('|cFFFF44DD'..k..'|r', v:GetName()) + end + + itemButton:SetAttribute("type", "item") + itemButton:SetAttribute("item", itemInfo.link) + + itemButton.questID = info.questID + itemButton.questLogIndex = info.questLogIndex + itemButton.charges = itemInfo.charges + itemButton.rangeTimer = -1 + itemButton.block = block + + SetItemButtonTexture(itemButton, itemInfo.icon) + SetItemButtonCount(itemButton, itemInfo.charges) + Veneer_QuestObjectiveItem_UpdateCooldown(itemButton); + + return itemButton +end +--- Clear an itemButton from the given block +mod.FreeItemButtons = function(block) + + if block.itemButton then + local itemButton = block.itemButton + if itemButton.questID ~= block.info.questID then + block.itemButton = nil + itemButton.block = mod.Quest.InfoBlock[itemButton.questID] + else + itemButton.block = nil + itemButton:Hide() + + usedButtons[itemButton.questID] = nil + freeButtons[#freeButtons + 1] = itemButton + mod.Quest.numButtons = mod.Quest.numButtons - 1 + print('|cFFFF0088released', itemButton:GetName(),'and', block:GetName()) + end + end +end + +function Veneer_QuestObjectiveItem_OnUpdate (self, elapsed) + -- Handle range indicator + local rangeTimer = self.rangeTimer + if (rangeTimer) then + rangeTimer = rangeTimer - elapsed + if (rangeTimer <= 0) then + local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.questLogIndex) + if ((not charges) or (charges ~= self.charges)) then + mod:Update() + return + end + + local count = self.HotKey + local valid = IsQuestLogSpecialItemInRange(self.questLogIndex) + if (valid == 0) then + count:Show() + count:SetVertexColor(1.0, 0.1, 0.1) + elseif (valid == 1) then + count:Show() + count:SetVertexColor(0.6, 0.6, 0.6) + else + count:Hide() + end + rangeTimer = TOOLTIP_UPDATE_TIME + end + + self.rangeTimer = rangeTimer + end +end + +function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton) + local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.questLogIndex) + if (start) then + CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable) + if (duration > 0 and enable == 0) then + SetItemButtonTextureVertexColor(itemButton, 0.4, 0.4, 0.4) + else + SetItemButtonTextureVertexColor(itemButton, 1, 1, 1) + end + end +end + +----------------------------------------- +-- 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(line, data, objectiveType, objectiveKey) + local print = B.print('ObjectiveWidgets') + local widgetType = objectiveType + local widget + if wr[widgetType] and wr[widgetType].used[objectiveKey] then + widget = wr[widgetType].used[objectiveKey] + print('|cFF00FF00Updating ('..objectiveKey..')', widget) + elseif not wr[widgetType] or #wr[widgetType].free == 0 then + widget = CreateFrame('Frame', 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) + + print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) + else + widget = tremove(wr[widgetType].free) + print('|cFFFFFF00Acquiring released widget', widget:GetName()) + end + + + wr[widgetType].used[objectiveKey] = widget + widget.line = line + widget.objective = data + widget.key = objectiveKey + mod.InitializeWidget(widget) + return widget +end + +--- WidgetTemplate 'OnLoad' +mod.RegisterWidget = function(frame) + local print = B.print('ObjectiveWidgets') + local widgetType = frame.widgetType + if not wr[frame.widgetType] then + print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) + wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } + else + print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) + wr[widgetType].lastn = wr[widgetType].lastn + 1 + end +end + +--- WidgetTemplate 'OnShow' +mod.InitializeWidget = setmetatable({}, { + __call = function(t, frame) + -- todo: config pull + + frame:SetWidth(mod.Conf.Wrapper.Width - mod.Conf.Style.Format.status.Indent * 2) + frame:SetScript('OnEvent', mod.UpdateWidget[frame.widgetType]) + frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') + frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') + frame:RegisterEvent('CRITERIA_UPDATE') + frame:RegisterEvent('CRITERIA_COMPLETE') + frame:RegisterEvent('CRITERIA_EARNED') + t[frame.widgetType](frame) + mod.UpdateWidget[frame.widgetType](frame) + end, +}) + +--- WidgetTemplate 'OnEvent' +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 +}) + +--- WidgetTemplate 'OnHide' +mod.ReleaseWidget = function(frame) + --[[ + local print = B.print('ObjectiveWidgets') + local reg = wr[frame.widgetType] + if reg and reg.used[frame.key] then + reg.used[frame.key] = nil + frame.line = nil + frame.info = nil + frame:UnregisterAllEvents() + tinsert(reg.free, frame) + print('|cFFBBBBBBreleased from service', frame:GetName()) + end + ]] +end + +--- RemoveTrackedAchievement post-hook +mod.CleanWidgets = function() + local print = B.print('ObjectiveWidgets') + local tracked = {GetTrackedAchievements() } + local tasks = GetTasksTable() + for type, reg in pairs(mod.WidgetRegistry) do + print('collecting', type) + for key, frame in pairs(reg.used) do + if frame.objective.cheevID then + local id = frame.objective.cheevID + + if id and not tContains(tracked, id) then + + print(' untracked achievement', id, 'associated with', key, frame:GetName()) + frame:Hide() + end + elseif frame.objective.questID then + -- do something for quest task + end + end + end +end + + + +mod.defaults.WidgetStyle = { + +} + +local progressHeight = 16 +local progressBorder = 1 +local progressIndent = 3 +local progressFont = _G.VeneerCriteriaFontNormal + + +mod.InitializeWidget.ProgressBar = function(self) + local c = mod.Conf.Wrapper + self.height = progressHeight + c.TextSpacing + self.width = c.Width - c.TextSpacing + self.indent = progressIndent + + self:SetHeight(progressHeight) + self.bg:SetHeight(progressHeight) + self.bg:SetWidth(self.width) + self.fg:ClearAllPoints() + self.fg:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', progressBorder, progressBorder) + self.fg:SetHeight(progressHeight - progressBorder * 2) + self.status:SetFontObject(progressFont) + self.status:SetText(self.objective.quantityString) +end + +mod.UpdateWidget.ProgressBar = function (self) + local quantity, requiredQuantity = self.objective.value, self.objective.maxValue + print('update vals:') + for k,v in pairs(self.line) do + print(k, v) + end + + if self.line.format then + self.status:SetFormattedText(self.line.format, quantity, requiredQuantity) + end + + local progress = (quantity / requiredQuantity) + if progress >= 1 then + self.fg:Show() + self.fg:SetWidth(self.width - progressBorder * 2) + elseif progress > 0 then + self.fg:Show() + print('color:', 1-progress*2 , progress*2 - 1,0,1) + print('width:', (self.width -progressBorder * 2) * progress) + self.fg:SetTexture(1-progress*2 , progress*2,0,1) + self.fg:SetWidth((self.width -progressBorder * 2) * progress) + else + self.fg:Hide() + end +end + + +mod.InitializeWidget.Hidden = function (self) + self.height = 0 +end +mod.UpdateWidget.Hidden = function (self) + self.height= 0 +end \ No newline at end of file