Mercurial > wow > buffalo2
comparison Modules/BuffFrame.lua @ 68:be5cea6e1e8f
- button size metrics
- anchor adjustment for temp enchant
- clean up call order
- use secure hooks to directly catch Show/Hide for individual buttons
| author | Nenue |
|---|---|
| date | Sun, 21 Aug 2016 07:09:10 -0400 |
| parents | f80ee484ac8a |
| children | ebc18a7412a1 |
comparison
equal
deleted
inserted
replaced
| 67:f80ee484ac8a | 68:be5cea6e1e8f |
|---|---|
| 12 --]] | 12 --]] |
| 13 | 13 |
| 14 local BUFF_BUTTON_SIZE = 48 | 14 local BUFF_BUTTON_SIZE = 48 |
| 15 local BUFF_PROGRESS_SIZE = 4 | 15 local BUFF_PROGRESS_SIZE = 4 |
| 16 local BUFF_PROGRESS_INSET = 1 | 16 local BUFF_PROGRESS_INSET = 1 |
| 17 local BUFF_BUTTON_ZOOM = 0 | 17 local BUFF_BUTTON_ZOOM = .15 |
| 18 local BORDER_SIZE_L = 0 | |
| 19 local BORDER_SIZE_R = 0 | |
| 20 local BORDER_SIZE_U = 1 | |
| 21 local BORDER_SIZE_D = 7 | |
| 18 | 22 |
| 19 | 23 |
| 20 local plugin = CreateFrame('Frame', 'VeneerBuffFrame', UIParent) | 24 local plugin = CreateFrame('Frame', 'VeneerBuffFrame', UIParent) |
| 21 local vn, print = LibStub("LibKraken").register(VeneerController, plugin) | 25 local vn, print = LibStub("LibKraken").register(VeneerController, plugin) |
| 22 | 26 local tprint = DEVIAN_WORKSPACE and function(...) _G.print('Timer', ...) end or function() end |
| 27 | |
| 28 local _G, UIParent = _G, UIParent | |
| 29 local tinsert, tremove, unpack, select, tconcat = table.insert, table.remove, unpack, select, table.concat | |
| 30 local floor, tonumber, format = math.floor, tonumber, string.format | |
| 31 local UnitAura, GetTime, CreateFrame = UnitAura, GetTime, CreateFrame | |
| 32 local hooksecurefunc = hooksecurefunc | |
| 23 | 33 |
| 24 local buttons = {} | 34 local buttons = {} |
| 25 local buffTypes = { | 35 local buffTypes = { |
| 26 { | 36 { |
| 27 name = 'buff', | 37 name = 'buff', |
| 50 local aurasCache = {} | 60 local aurasCache = {} |
| 51 local skinnedFrames = {} | 61 local skinnedFrames = {} |
| 52 local pendingFrames = {} | 62 local pendingFrames = {} |
| 53 local anchors = {} | 63 local anchors = {} |
| 54 local expirationCache = {} | 64 local expirationCache = {} |
| 65 local visibility = {} | |
| 55 | 66 |
| 56 local VeneerButton_OnHide = function(self) | 67 local VeneerButton_OnHide = function(self) |
| 57 self:SetScript('OnDragStart', self.StartMoving) | 68 self:SetScript('OnDragStart', self.StartMoving) |
| 58 self:SetScript('OnDragStop', self.StopMovingOrSizing) | 69 self:SetScript('OnDragStop', self.StopMovingOrSizing) |
| 59 self:SetMovable(false) | 70 self:SetMovable(false) |
| 69 end | 80 end |
| 70 | 81 |
| 71 | 82 |
| 72 local GetVeneer = function(frame) | 83 local GetVeneer = function(frame) |
| 73 local name = frame:GetName() | 84 local name = frame:GetName() |
| 74 if not _G[name..'Veneer'] then | 85 if not (_G[name..'Veneer'] and _G[name..'Underlay']) then |
| 75 | 86 print('|cFF88FF00Creating', name,'Veneer') |
| 76 local veneer = CreateFrame('Frame', name..'Veneer', UIParent) | 87 local veneer = CreateFrame('Frame', name..'Veneer', UIParent) |
| 77 local id = frame:GetID() | 88 local id = frame:GetID() |
| 78 veneer:SetAllPoints(frame) | 89 veneer:SetAllPoints(frame) |
| 79 veneer:SetParent(frame) | 90 veneer:SetParent(frame) |
| 80 veneer.bg = veneer:CreateTexture() | 91 veneer.bg = veneer:CreateTexture() |
| 94 | 105 |
| 95 veneer.progress = CreateFrame('Frame', name .. 'VeneerProgress', veneer) | 106 veneer.progress = CreateFrame('Frame', name .. 'VeneerProgress', veneer) |
| 96 veneer.progress:Hide() | 107 veneer.progress:Hide() |
| 97 veneer.progress:SetPoint('BOTTOMLEFT', veneer, 'BOTTOMLEFT', 3, -6) | 108 veneer.progress:SetPoint('BOTTOMLEFT', veneer, 'BOTTOMLEFT', 3, -6) |
| 98 veneer.progress:SetPoint('TOPRIGHT', veneer, 'BOTTOMRIGHT', -3, -1) | 109 veneer.progress:SetPoint('TOPRIGHT', veneer, 'BOTTOMRIGHT', -3, -1) |
| 110 veneer.progress:SetHeight(BUFF_PROGRESS_SIZE + (BUFF_PROGRESS_INSET * 2)) | |
| 99 | 111 |
| 100 veneer.progress.bg = veneer.progress:CreateTexture(nil, 'BACKGROUND') | 112 veneer.progress.bg = veneer.progress:CreateTexture(nil, 'BACKGROUND') |
| 101 veneer.progress.bg:SetColorTexture(0,0,0,1) | 113 veneer.progress.bg:SetColorTexture(0,0,0,1) |
| 102 veneer.progress.bg:SetAllPoints(veneer.progress) | 114 veneer.progress.bg:SetAllPoints(veneer.progress) |
| 103 | 115 |
| 104 veneer.progress.fg = veneer.progress:CreateTexture(nil, 'ARTWORK') | 116 veneer.progress.fg = veneer.progress:CreateTexture(nil, 'ARTWORK') |
| 105 veneer.progress.fg:SetColorTexture(0,1,0,1) | 117 veneer.progress.fg:SetColorTexture(0,1,0,1) |
| 106 veneer.progress.fg:SetPoint('BOTTOMLEFT', 1,1) | 118 veneer.progress.fg:SetPoint('BOTTOMLEFT', BUFF_PROGRESS_INSET,BUFF_PROGRESS_INSET) |
| 107 veneer.progress.fg:SetPoint('TOP', 0, -1) | 119 veneer.progress.fg:SetPoint('TOP', 0, -BUFF_PROGRESS_INSET) |
| 108 | 120 |
| 109 veneer.progress.status = veneer.progress:CreateFontString() | 121 veneer.progress.status = veneer.progress:CreateFontString() |
| 110 veneer.progress.status:SetFontObject(VeneerNumberFont) | 122 veneer.progress.status:SetFontObject(VeneerNumberFont) |
| 111 veneer.progress.status:SetPoint('TOP') | 123 veneer.progress.status:SetPoint('TOP') |
| 112 | 124 |
| 113 | 125 |
| 114 veneer.cooldown = CreateFrame('Cooldown', name ..'VeneerCooldown', veneer, 'CooldownFrameTemplate') | 126 veneer.cooldown = CreateFrame('Cooldown', name ..'VeneerCooldown', veneer, 'CooldownFrameTemplate') |
| 115 veneer.cooldown:SetAllPoints(frame) | 127 veneer.cooldown:SetAllPoints(frame) |
| 116 veneer.cooldown:SetReverse(true) | 128 veneer.cooldown:SetReverse(true) |
| 117 | 129 |
| 118 end | 130 |
| 119 | 131 |
| 120 | 132 |
| 121 return _G[name..'Veneer'] | 133 local underlay = CreateFrame('Frame', name..'Underlay', UIParent) |
| 122 end | 134 underlay:Show() |
| 135 underlay:SetFrameStrata('BACKGROUND') | |
| 136 local n = frame:GetNumPoints() | |
| 137 for i = 1, n do | |
| 138 underlay:SetPoint(frame:GetPoint(n)) | |
| 139 end | |
| 140 | |
| 141 | |
| 142 | |
| 143 | |
| 144 veneer.border = underlay:CreateTexture(name..'VeneerBorder', 'BACKGROUND') | |
| 145 veneer.border:SetPoint('TOPLEFT', veneer, 'TOPLEFT', -BORDER_SIZE_L, BORDER_SIZE_U) | |
| 146 veneer.border:SetPoint('BOTTOMRIGHT', veneer, 'BOTTOMRIGHT', BORDER_SIZE_R, -BORDER_SIZE_D) | |
| 147 --veneer.border:SetColorTexture(0,1,0,1) | |
| 148 veneer.border:Show() | |
| 149 | |
| 150 end | |
| 151 | |
| 152 | |
| 153 return _G[name..'Veneer'], _G[name..'Underlay'] | |
| 154 end | |
| 155 | |
| 156 | |
| 157 -- Associates skinning elements with said button | |
| 158 local SkinFrame = function(name) | |
| 159 local frame = _G[name ] | |
| 160 if skinnedFrames[frame] then | |
| 161 print('|cFFFF4400Attempting to skin a frame that already went through.|r') | |
| 162 return | |
| 163 end | |
| 164 print('|cFFFFFF00Adopting', name) | |
| 165 | |
| 166 local icon = _G[name .. 'Icon'] | |
| 167 local border = _G[name .. 'Border'] | |
| 168 local count = _G[name .. 'Count'] | |
| 169 local duration = _G[name .. 'Duration'] | |
| 170 local slot = frame:GetID() or 0 | |
| 171 local veneer, underlay = GetVeneer(frame) | |
| 172 | |
| 173 skinnedFrames[frame] = frame | |
| 174 frame:SetSize(BUFF_BUTTON_SIZE,BUFF_BUTTON_SIZE) | |
| 175 | |
| 176 local offset = BUFF_BUTTON_ZOOM/2 | |
| 177 icon:SetTexCoord(offset, 1 - offset, offset, 1 - offset) | |
| 178 if border then | |
| 179 border:Hide() | |
| 180 hooksecurefunc(border, 'SetVertexColor', function(frame, r, g, b, a) | |
| 181 frame:Hide() | |
| 182 print('|cFF0088FFborder:SetVertexColor|r', r,g,b,a) | |
| 183 veneer.border:SetColorTexture(r,g,b,a) | |
| 184 end) | |
| 185 | |
| 186 local color = DebuffTypeColor["none"] | |
| 187 if aurasCache[frame] and aurasCache[frame][5] then | |
| 188 color = DebuffTypeColor[aurasCache[frame][5]] | |
| 189 end | |
| 190 | |
| 191 veneer.border:SetColorTexture(color.r,color.g,color.b) | |
| 192 end | |
| 193 if duration then | |
| 194 duration:ClearAllPoints() | |
| 195 duration:SetPoint('TOP', frame, 'BOTTOM', 0, -8) | |
| 196 duration:SetFontObject(VeneerNumberFont) | |
| 197 duration:SetDrawLayer('OVERLAY') | |
| 198 | |
| 199 end | |
| 200 | |
| 201 | |
| 202 hooksecurefunc(frame, "Hide", function(self) | |
| 203 local isVisible = self:IsVisible() | |
| 204 if isVisible ~= visibility[self] then | |
| 205 visibility[self] = isVisible | |
| 206 end | |
| 207 veneer:Hide() | |
| 208 underlay:Hide() | |
| 209 end) | |
| 210 | |
| 211 hooksecurefunc(frame, 'Show', function(self) | |
| 212 veneer:Show() | |
| 213 veneer.border:Show() | |
| 214 underlay:Show() | |
| 215 local isVisible = self:IsVisible() | |
| 216 if isVisible ~= visibility[self] then | |
| 217 print('|cFFFFFF00SHOW|r', self:GetName()) | |
| 218 visibility[self] = isVisible | |
| 219 end | |
| 220 end) | |
| 221 | |
| 222 anchors[frame] = veneer | |
| 223 end | |
| 224 | |
| 225 local Aura_SetBorderColor = function(self, r,g,b,a) end | |
| 226 local Aura_OnShow = function(self) end | |
| 227 local Aura_OnHide = function(self) end | |
| 123 | 228 |
| 124 --- Set widgets to reflect the passed parameters | 229 --- Set widgets to reflect the passed parameters |
| 125 local UpdateVeneer = function (frame, duration, expires) | 230 local UpdateVeneer = function (frame, duration, expires) |
| 126 local veneer = GetVeneer(frame) | 231 local veneer = GetVeneer(frame) |
| 232 -- is it a new button? | |
| 233 if not skinnedFrames[frame] then | |
| 234 SkinFrame(frame:GetName()) | |
| 235 end | |
| 236 | |
| 237 if frame.filter == 'HARMFUL' then | |
| 238 | |
| 239 veneer.border:Show() | |
| 240 end | |
| 241 | |
| 127 | 242 |
| 128 if expires and duration then | 243 if expires and duration then |
| 129 | |
| 130 if duration ~= 0 then | 244 if duration ~= 0 then |
| 131 local startTime = (expires - duration) | 245 local startTime = (expires - duration) |
| 132 local endTime = expires or 0 | 246 local endTime = expires or 0 |
| 133 print('|cFF0088FF'..frame:GetName()..'|r', duration, expires) | 247 print('|cFF0088FF'..frame:GetName()..'|r', duration, expires) |
| 134 veneer.progress:Show() | 248 veneer.progress:Show() |
| 141 local progress = (t - startTime) / duration | 255 local progress = (t - startTime) / duration |
| 142 | 256 |
| 143 local nw = (w - (w * progress)) | 257 local nw = (w - (w * progress)) |
| 144 if veneer.elapsed >= 0.25 then | 258 if veneer.elapsed >= 0.25 then |
| 145 | 259 |
| 146 print(t, startTime, floor(progress*100), w * progress, nw, w) | 260 tprint(t, startTime, floor(progress*100), w * progress, nw, w) |
| 147 veneer.elapsed = 0.25 - veneer.elapsed | 261 veneer.elapsed = 0.25 - veneer.elapsed |
| 148 end | 262 end |
| 149 if (progress >= 1) or not frame:IsVisible() then | 263 if (progress >= 1) or not frame:IsVisible() then |
| 150 veneer.startTime = nil | 264 veneer.startTime = nil |
| 151 self:Hide() | 265 self:Hide() |
| 171 end | 285 end |
| 172 veneer:Show() | 286 veneer:Show() |
| 173 end | 287 end |
| 174 | 288 |
| 175 | 289 |
| 176 -- Associates skinning elements with said button | |
| 177 local SkinFrame = function(name) | |
| 178 local frame = _G[name ] | |
| 179 if skinnedFrames[frame] then | |
| 180 print('|cFFFF4400Attempting to skin a frame that already went through.|r') | |
| 181 return | |
| 182 end | |
| 183 | |
| 184 local icon = _G[name .. 'Icon'] | |
| 185 local border = _G[name .. 'Border'] | |
| 186 local duration = _G[name .. 'Duration'] | |
| 187 local slot = frame:GetID() or 0 | |
| 188 | |
| 189 tickCounter[frame] = (tickCounter[frame] or 0) + 1 | |
| 190 | |
| 191 | |
| 192 print(tickCounter[frame], frame:GetName(), '|cFFFFFF00'..slot..'|r') | |
| 193 skinnedFrames[frame] = frame | |
| 194 frame:SetSize(BUFF_BUTTON_SIZE,BUFF_BUTTON_SIZE) | |
| 195 | |
| 196 local offset = BUFF_BUTTON_ZOOM/2 | |
| 197 icon:SetTexCoord(offset, 1 - offset, offset, 1 - offset) | |
| 198 if border then | |
| 199 border:SetSize(50,50) | |
| 200 end | |
| 201 if duration then | |
| 202 duration:ClearAllPoints() | |
| 203 duration:SetPoint('TOP', frame, 'BOTTOM', 0, -8) | |
| 204 duration:SetFontObject(VeneerNumberFont) | |
| 205 duration:SetDrawLayer('OVERLAY') | |
| 206 | |
| 207 end | |
| 208 | |
| 209 GetVeneer(frame) | |
| 210 | |
| 211 anchors[frame] = veneer | |
| 212 print('Initializing', name) | |
| 213 end | |
| 214 | |
| 215 | |
| 216 --- Provides the number of changed indices for use in deciding between partial and full veneer updates | 290 --- Provides the number of changed indices for use in deciding between partial and full veneer updates |
| 217 local CacheCheck = function(frame, ...) | 291 local CacheCheck = function(frame, ...) |
| 218 aurasCache[frame] = aurasCache[frame] or {} | 292 aurasCache[frame] = aurasCache[frame] or {} |
| 219 local hasChange = 0 | 293 local hasChange = 0 |
| 220 local numVals = select('#',...) | 294 local numVals = select('#',...) |
| 231 local AuraButton_Update = function(name, index, filter) | 305 local AuraButton_Update = function(name, index, filter) |
| 232 local bName = name..index | 306 local bName = name..index |
| 233 local frame = _G[bName] | 307 local frame = _G[bName] |
| 234 if frame and frame:IsVisible() then | 308 if frame and frame:IsVisible() then |
| 235 tickCounter[frame] = (tickCounter[frame] or 0) + 1 | 309 tickCounter[frame] = (tickCounter[frame] or 0) + 1 |
| 310 | |
| 311 | |
| 312 | |
| 236 local cacheDiff = CacheCheck(frame, UnitAura(frame.unit, frame:GetID(), frame.filter)) | 313 local cacheDiff = CacheCheck(frame, UnitAura(frame.unit, frame:GetID(), frame.filter)) |
| 314 | |
| 237 -- if the name or expirationTime changed | 315 -- if the name or expirationTime changed |
| 238 if (cacheDiff >= 1) then | 316 if (cacheDiff >= 1) then |
| 239 print(frame:GetName(), 'diff:', cacheDiff) | 317 print('|cFFFF4400', frame:GetName(), 'diff:', cacheDiff) |
| 240 if not skinnedFrames[frame] then | 318 if not skinnedFrames[frame] then |
| 241 tinsert(pendingFrames, frame) | 319 tinsert(pendingFrames, frame) |
| 242 end | 320 end |
| 243 expirationCache[name] = frame.expirationTime | 321 expirationCache[name] = frame.expirationTime |
| 244 print(unpack(aurasCache[frame])) | 322 print(unpack(aurasCache[frame])) |
| 323 | |
| 324 | |
| 325 | |
| 245 UpdateVeneer(frame, aurasCache[frame][6], aurasCache[frame][7]) | 326 UpdateVeneer(frame, aurasCache[frame][6], aurasCache[frame][7]) |
| 246 end | 327 end |
| 247 | 328 |
| 248 -- is it a new button? | |
| 249 if not skinnedFrames[frame] then | |
| 250 SkinFrame(bName) | |
| 251 end | |
| 252 end | 329 end |
| 253 end | 330 end |
| 254 | 331 |
| 255 local BuffFrame_UpdateAllBuffAnchors = function() | 332 local BuffFrame_UpdateAllBuffAnchors = function() |
| 256 local todo = {} | 333 local todo = {} |
| 261 local frame = tremove(pendingFrames) | 338 local frame = tremove(pendingFrames) |
| 262 tinsert(todo, frame:GetName()) | 339 tinsert(todo, frame:GetName()) |
| 263 | 340 |
| 264 -- re-apply custom anchors | 341 -- re-apply custom anchors |
| 265 end | 342 end |
| 266 print(table.concat(todo, ', ')) | 343 print(tconcat(todo, ', ')) |
| 267 end | 344 end |
| 268 --BuffButton1 | 345 --BuffButton1 |
| 269 --DebuffButton1 | 346 --DebuffButton1 |
| 270 --todo: separate frame groups and iterate over them at appropriate times | 347 --todo: separate frame groups and iterate over them at appropriate times |
| 271 if BuffButton1 then | 348 if BuffButton1 then |
| 272 --TempEnchant1:SetPoint('TOPRIGHT', BuffButton1, 'TOPRIGHT', BuffButton1:GetWidth()+4, 0) | 349 TempEnchant1:SetPoint('TOPRIGHT', BuffButton1, 'TOPRIGHT', BuffButton1:GetWidth()+4, 0) |
| 273 end | 350 end |
| 274 | 351 |
| 275 end | 352 end |
| 276 | 353 |
| 277 local AuraButton_UpdateDuration = function(frame, timeLeft) | 354 local AuraButton_UpdateDuration = function(frame, timeLeft) |
| 290 | 367 |
| 291 frame.duration:SetText(timeString) | 368 frame.duration:SetText(timeString) |
| 292 frame.duration:SetVertexColor(1,1,1) | 369 frame.duration:SetVertexColor(1,1,1) |
| 293 end | 370 end |
| 294 | 371 |
| 295 local visibility = {} | |
| 296 local TempEnchantButton_OnHide = function(self) | |
| 297 local isVisible = self:IsVisible() | |
| 298 if isVisible ~= visibility[self] then | |
| 299 print('|cFFFFFF00HIDE|r', self:GetName()) | |
| 300 visibility[self] = isVisible | |
| 301 end | |
| 302 end | |
| 303 | 372 |
| 304 -- Obtains the first instance of Tenchant use | 373 -- Obtains the first instance of Tenchant use |
| 305 | 374 |
| 306 local TemporaryEnchantFrame_Update = function(...) | 375 local TemporaryEnchantFrame_Update = function(...) |
| 307 local numVals = select('#', ...) | 376 local numVals = select('#', ...) |
| 348 | 417 |
| 349 -- The TempEnchant frames are hardcoded in the base FrameXML, so get them now | 418 -- The TempEnchant frames are hardcoded in the base FrameXML, so get them now |
| 350 for i = 1, 3 do | 419 for i = 1, 3 do |
| 351 | 420 |
| 352 SkinFrame('TempEnchant'..i) | 421 SkinFrame('TempEnchant'..i) |
| 353 hooksecurefunc(_G['TempEnchant'..i], "Hide", TempEnchantButton_OnHide) | 422 _G['TempEnchant'..i..'Border']:SetVertexColor(0.5,0,1,1) |
| 354 | |
| 355 | 423 |
| 356 end | 424 end |
| 357 | 425 |
| 358 plugin.init = function () | 426 plugin.init = function () |
| 359 | 427 |
