annotate ObjectiveTracker/Widgets.lua @ 46:aa693607b813

Block - use Animation:IsPlaying() to determine whether a block should be ignored during cleanup; fixes abandoned quest ghosts
author Nenue
date Tue, 26 Apr 2016 15:05:38 -0400
parents 9480bd904f4c
children
rev   line source
Nenue@28 1 local B = select(2,...).frame
Nenue@28 2 local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
Nenue@28 3 local print = B.print('WidgetFactory')
Nenue@43 4 local tprint = B.print('Tracker')
Nenue@28 5 local _G, UIParent = _G, UIParent
Nenue@28 6 local GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown
Nenue@43 7 local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame
Nenue@43 8 local pairs, ipairs, floor = pairs, ipairs, floor
Nenue@28 9 local SetItemButtonTexture, SetItemButtonCount = SetItemButtonTexture, SetItemButtonCount
Nenue@43 10 local ToggleWorldMap = ToggleWorldMap
Nenue@28 11 -- GLOBALS: Veneer_QuestObjectiveItem_UpdateCooldown, Veneer_QuestObjectiveItem_OnUpdate
Nenue@43 12
Nenue@43 13 --- Functions for generating and recycling the miscellaneous interface widgets specified by quests
Nenue@28 14 local Wrapper = _G.VeneerObjectiveWrapper
Nenue@28 15 local Scroller = Wrapper.scrollArea
Nenue@28 16 local CloseButton = Wrapper.CloseButton
Nenue@28 17 local QuestMapButton = Wrapper.QuestMapButton
Nenue@28 18 local Scroll = _G.VeneerObjectiveScroll
Nenue@28 19 local usedButtons = T.Quest.itemButtons
Nenue@28 20 local freeButtons = T.Quest.freeButtons
Nenue@28 21
Nenue@28 22 T.buttons = {
Nenue@28 23 CloseButton = {
Nenue@28 24 closedSwatch = {
Nenue@28 25 [[Interface\Buttons\UI-Panel-QuestHideButton]],
Nenue@28 26 [[Interface\Buttons\UI-Panel-QuestHideButton]],
Nenue@28 27 0, 0.5, 0.5, 1,
Nenue@28 28 0.5, 1, 0.5, 1,
Nenue@28 29 },
Nenue@28 30 openSwatch = {
Nenue@28 31 [[Interface\Buttons\UI-Panel-QuestHideButton]],
Nenue@28 32 [[Interface\Buttons\UI-Panel-QuestHideButton]],
Nenue@28 33 0.5, 1, 0.5, 1,
Nenue@28 34 0, 0.5, 0.5, 1,
Nenue@28 35 },
Nenue@28 36 parent = 'VeneerObjectiveWrapper'
Nenue@28 37 },
Nenue@28 38 QuestMapButton = {
Nenue@28 39 closedSwatch = {
Nenue@28 40 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]],
Nenue@28 41 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]],
Nenue@28 42 0, 1, 0.5, 1,
Nenue@28 43 0, 1, 0, 0.5,
Nenue@28 44 },
Nenue@28 45 openSwatch = {
Nenue@28 46 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]],
Nenue@28 47 [[Interface\QUESTFRAME\UI-QUESTMAP_BUTTON]],
Nenue@28 48 0, 1, 0, 0.5,
Nenue@28 49 0, 1, 0.5, 1,
Nenue@28 50 }
Nenue@28 51 }
Nenue@28 52 }
Nenue@28 53
Nenue@28 54 local Scroller_OnShow = function()
Nenue@28 55 Wrapper.watchMoneyReasons = 0;
Nenue@28 56 --T:Update()
Nenue@28 57 --T:OnInitialize()
Nenue@28 58 for i, region in ipairs(Wrapper.headerComplex) do
Nenue@28 59 region:Show()
Nenue@28 60 end
Nenue@28 61 end
Nenue@28 62
Nenue@28 63 local Scroller_OnHide = function()
Nenue@28 64 local self = Wrapper
Nenue@28 65 Wrapper:UnregisterAllEvents()
Nenue@28 66 Wrapper:SetScript('OnEvent', nil)
Nenue@28 67 for i, region in ipairs(Wrapper.headerComplex) do
Nenue@28 68 region:Hide()
Nenue@28 69 end
Nenue@28 70 end
Nenue@28 71
Nenue@28 72 local Scroller_OnMouseWheel = function(self, delta)
Nenue@28 73 local r = Scroll:GetHeight() - Scroller:GetHeight()
Nenue@28 74 local s = B.Conf.ObjectiveScroll - delta * floor(r/5+.5)
Nenue@28 75 local from = self:GetVerticalScroll()
Nenue@28 76 print('|cFF00FF00OnMouseWheel', 'scroll =', s)
Nenue@28 77 if s >= r then
Nenue@28 78 s = r
Nenue@28 79 elseif s < 1 then
Nenue@28 80 s = 0
Nenue@28 81 end
Nenue@28 82 self:SetVerticalScroll(s)
Nenue@28 83 B.Conf.ObjectiveScroll = s
Nenue@28 84 print('|cFF00FF00OnMouseWheel', 'from = ', from, 'scroll =', s, ' range =', r, 'current =', self:GetVerticalScroll())
Nenue@28 85
Nenue@28 86 T.UpdateActionButtons('SCROLLING')
Nenue@28 87 end
Nenue@28 88
Nenue@28 89 local UpdatePanelButton = function (self, state)
Nenue@28 90 state = state or true
Nenue@28 91 local swatch = (state == true) and self.openSwatch or self.closedSwatch
Nenue@28 92 print((state ~= true) and 'closedSwatch' or 'openSwatch')
Nenue@28 93 self:SetNormalTexture(swatch[1])
Nenue@28 94 self:SetPushedTexture(swatch[2])
Nenue@28 95 if #swatch >= 6 then
Nenue@28 96 self:GetNormalTexture():SetTexCoord(swatch[3], swatch[4], swatch[5], swatch[6])
Nenue@28 97 end
Nenue@28 98 if #swatch == 10 then
Nenue@28 99 self:GetPushedTexture():SetTexCoord(swatch[7], swatch[8], swatch[9], swatch[10])
Nenue@28 100 end
Nenue@28 101
Nenue@28 102 end
Nenue@28 103
Nenue@28 104 local OnClick = {}
Nenue@28 105 OnClick.CloseButton = function(self)
Nenue@38 106 T:Enable()
Nenue@34 107 if T.Conf.enabled then
Nenue@34 108 T:Update()
Nenue@34 109 end
Nenue@34 110
Nenue@28 111 UpdatePanelButton(self, T.Conf.enabled)
Nenue@28 112 end
Nenue@28 113
Nenue@28 114 OnClick.QuestMapButton = function()
Nenue@28 115 ToggleWorldMap()
Nenue@28 116 end
Nenue@28 117
Nenue@43 118 --- Get a usable widget for the given achievement criteria set.
Nenue@43 119 -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block
Nenue@43 120 local wr = T.WidgetRegistry
Nenue@43 121 T.GetWidget = function(data, objectiveType, objectiveKey)
Nenue@43 122 local print = B.print('ObjectiveWidgets')
Nenue@43 123 local widgetType = objectiveType
Nenue@43 124 local widget
Nenue@43 125 local isNew
Nenue@43 126 if wr[widgetType] and wr[widgetType].used[objectiveKey] then
Nenue@43 127 widget = wr[widgetType].used[objectiveKey]
Nenue@43 128 print('|cFF00FF00Updating ('..objectiveKey..')', widget)
Nenue@43 129 elseif not wr[widgetType] or #wr[widgetType].free == 0 then
Nenue@43 130 -- creating a new frame
Nenue@43 131 isNew = true
Nenue@43 132 widget = CreateFrame(widgetType, 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType)
Nenue@43 133 print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn)
Nenue@43 134 T.UpdateSchema(widgetType, data.schema or 'default')
Nenue@43 135 else
Nenue@43 136 -- recycling for a different criteria set
Nenue@43 137 isNew = true
Nenue@43 138 widget = tremove(wr[widgetType].free)
Nenue@43 139 print('|cFFFFFF00Acquiring released widget', widget:GetName())
Nenue@43 140 end
Nenue@43 141
Nenue@43 142 for k,v in pairs(data) do
Nenue@43 143 if not widget[k] then
Nenue@43 144 widget[k] = v
Nenue@43 145 tprint('widget', widget:GetName(), k, v)
Nenue@43 146 end
Nenue@43 147 end
Nenue@43 148
Nenue@43 149 wr[widgetType].used[objectiveKey] = widget
Nenue@43 150 widget.objective = data
Nenue@43 151 widget.key = objectiveKey
Nenue@43 152 T.InitializeWidget(widget, isNew)
Nenue@43 153 return widget
Nenue@43 154 end
Nenue@43 155
Nenue@43 156 local wr = T.WidgetRegistry
Nenue@43 157 --- WidgetTemplate 'OnLoad'
Nenue@43 158 T.RegisterWidget = function(frame)
Nenue@43 159 local print = B.print('ObjectiveWidgets')
Nenue@43 160 local widgetType = frame.widgetType
Nenue@43 161 if not wr[frame.widgetType] then
Nenue@43 162 print('|cFFFF4400[[WidgetTemplate]]|r', widgetType)
Nenue@43 163 wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} }
Nenue@43 164 else
Nenue@43 165 print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn)
Nenue@43 166 wr[widgetType].lastn = wr[widgetType].lastn + 1
Nenue@43 167 end
Nenue@43 168 end
Nenue@28 169
Nenue@28 170 T.InitializeWidgets = function()
Nenue@28 171 local panelButtons = T.buttons
Nenue@28 172 --- tracker scroll
Nenue@28 173 Scroller:SetScript('OnMouseWheel', Scroller_OnMouseWheel)
Nenue@28 174 Scroller:SetScript('OnShow', Scroller_OnShow)
Nenue@28 175 Scroller:SetScript('OnHide', Scroller_OnHide)
Nenue@28 176 for name, swatch in pairs(panelButtons) do
Nenue@28 177 local source = swatch and swatch or panelButtons.CloseButton
Nenue@28 178 local button = Wrapper[name]
Nenue@28 179 button.parent = swatch.parent
Nenue@28 180 button.openSwatch = source.openSwatch
Nenue@28 181 button.closedSwatch = source.closedSwatch
Nenue@28 182 if OnClick[name] then
Nenue@28 183 button:SetScript('OnClick', OnClick[name])
Nenue@28 184 end
Nenue@28 185 UpdatePanelButton(button, T.Conf.enabled)
Nenue@28 186 end
Nenue@28 187 end
Nenue@28 188
Nenue@28 189 ----------------------------------------------------------------------------------------
Nenue@28 190 --- modified version of the itemButton initializer used by Barjack's 'QuestKing 2' addon,
Nenue@28 191 --- url: http://mods.curse.com/addons/wow/questking
Nenue@28 192 ----------------------------------------------------------------------------------------
Nenue@28 193 T.SetItemButton = function(block, info)
Nenue@28 194 local itemInfo = info.specialItem
Nenue@28 195 if not itemInfo then
Nenue@28 196 return
Nenue@28 197 end
Nenue@28 198
Nenue@28 199 local itemButton
Nenue@28 200 if not info.itemButton then
Nenue@28 201 if #freeButtons >= 1 then
Nenue@28 202 print(' |cFF00FFFFfound a free button')
Nenue@28 203 itemButton = freeButtons[#freeButtons]
Nenue@28 204 freeButtons[#freeButtons] = nil
Nenue@28 205 if itemButton.block then
Nenue@28 206 itemButton.block.itemButton = nil
Nenue@28 207 itemButton.block = nil
Nenue@28 208 end
Nenue@28 209 else
Nenue@28 210 local buttonIndex = T.Quest.numButtons + #freeButtons + 1
Nenue@28 211 itemButton = CreateFrame('Button', 'VeneerQuestItemButton' .. buttonIndex, UIParent, 'VeneerItemButtonTemplate')
Nenue@28 212 itemButton.buttonIndex = buttonIndex
Nenue@28 213 itemButton:SetSize(36, 36)
Nenue@28 214 itemButton:GetNormalTexture():SetSize(36 * (5/3), 36 * (5/3))
Nenue@28 215 print(' |cFFFF4400starting new button', itemButton:GetName())
Nenue@28 216 end
Nenue@28 217 T.Quest.numButtons = T.Quest.numButtons + 1
Nenue@28 218 else
Nenue@28 219 itemButton = info.itemButton
Nenue@28 220 print(' |cFF00FF00found assigned button', itemButton:GetName())
Nenue@28 221
Nenue@28 222 end
Nenue@28 223 -- set values
Nenue@28 224
Nenue@28 225 info.itemButton = itemButton
Nenue@28 226 usedButtons[info.questID] = itemButton
Nenue@28 227 print(' |cFF8800FFassigning|r', itemButton:GetName(), 'to quest|cFF00FF00', info.questID, '|rat|cFFFFFF00', block:GetName(),'|r')
Nenue@28 228
Nenue@28 229 for k,v in pairs(usedButtons) do
Nenue@28 230 print('|cFFFF44DD'..k..'|r', v:GetName())
Nenue@28 231 end
Nenue@28 232
Nenue@28 233 itemButton:SetAttribute("type", "item")
Nenue@28 234 itemButton:SetAttribute("item", itemInfo.link)
Nenue@28 235
Nenue@28 236 itemButton.questID = info.questID
Nenue@34 237 itemButton.logIndex = info.logIndex
Nenue@28 238 itemButton.charges = itemInfo.charges
Nenue@28 239 itemButton.rangeTimer = -1
Nenue@28 240 itemButton.block = block
Nenue@28 241
Nenue@28 242 SetItemButtonTexture(itemButton, itemInfo.icon)
Nenue@28 243 SetItemButtonCount(itemButton, itemInfo.charges)
Nenue@28 244 Veneer_QuestObjectiveItem_UpdateCooldown(itemButton);
Nenue@28 245
Nenue@28 246 return itemButton
Nenue@28 247 end
Nenue@28 248 --- Clear an itemButton from the given block
Nenue@28 249 T.FreeItemButtons = function(block)
Nenue@28 250
Nenue@28 251 if block.itemButton then
Nenue@28 252 local itemButton = block.itemButton
Nenue@28 253 if itemButton.questID ~= block.info.questID then
Nenue@28 254 block.itemButton = nil
Nenue@28 255 itemButton.block = T.Quest.InfoBlock[itemButton.questID]
Nenue@28 256 else
Nenue@28 257 itemButton.block = nil
Nenue@28 258 itemButton:Hide()
Nenue@28 259
Nenue@28 260 usedButtons[itemButton.questID] = nil
Nenue@28 261 freeButtons[#freeButtons + 1] = itemButton
Nenue@28 262 T.Quest.numButtons = T.Quest.numButtons - 1
Nenue@28 263 print('|cFFFF0088released', itemButton:GetName(),'and', block:GetName())
Nenue@28 264 end
Nenue@28 265 end
Nenue@28 266 end
Nenue@28 267
Nenue@28 268 function Veneer_QuestObjectiveItem_OnUpdate (self, elapsed)
Nenue@28 269 -- Handle range indicator
Nenue@28 270 local rangeTimer = self.rangeTimer
Nenue@28 271 if (rangeTimer) then
Nenue@28 272 rangeTimer = rangeTimer - elapsed
Nenue@28 273 if (rangeTimer <= 0) then
Nenue@34 274 local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.logIndex)
Nenue@28 275 if ((not charges) or (charges ~= self.charges)) then
Nenue@28 276 T:Update()
Nenue@28 277 return
Nenue@28 278 end
Nenue@28 279
Nenue@28 280 local count = self.HotKey
Nenue@34 281 local valid = IsQuestLogSpecialItemInRange(self.logIndex)
Nenue@28 282 if (valid == 0) then
Nenue@28 283 count:Show()
Nenue@28 284 count:SetVertexColor(1.0, 0.1, 0.1)
Nenue@28 285 elseif (valid == 1) then
Nenue@28 286 count:Show()
Nenue@28 287 count:SetVertexColor(0.6, 0.6, 0.6)
Nenue@28 288 else
Nenue@28 289 count:Hide()
Nenue@28 290 end
Nenue@28 291 rangeTimer = TOOLTIP_UPDATE_TIME
Nenue@28 292 end
Nenue@28 293
Nenue@28 294 self.rangeTimer = rangeTimer
Nenue@28 295 end
Nenue@28 296 end
Nenue@28 297
Nenue@28 298 function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton)
Nenue@34 299 local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.logIndex)
Nenue@28 300 if (start) then
Nenue@28 301 CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable)
Nenue@28 302 if (duration > 0 and enable == 0) then
Nenue@28 303 SetItemButtonTextureVertexColor(itemButton, 0.4, 0.4, 0.4)
Nenue@28 304 else
Nenue@28 305 SetItemButtonTextureVertexColor(itemButton, 1, 1, 1)
Nenue@28 306 end
Nenue@28 307 end
Nenue@28 308 end
Nenue@28 309