annotate KBF.lua @ 64:e5c07fdfb70b

remove the old hacked weapon enchant stuff since SAH properly supports it now, but turn it off because due to bugs either in KBF or SAH (both?), you get overlapping messed up displays whenever you have extra, non-buff frames
author Chris Mellon <arkanes@gmail.com>
date Fri, 02 Dec 2011 06:15:35 -0600
parents 31eac67dd283
children e19d0380b9f3
rev   line source
arkanes@0 1 local _, kbf = ...
arkanes@0 2
arkanes@0 3 KBF = kbf -- make global for debugging
arkanes@0 4
arkanes@0 5 local kbf = LibStub("AceAddon-3.0"):NewAddon(kbf, "KBF", "AceEvent-3.0", "AceConsole-3.0")
arkanes@0 6
arkanes@0 7
arkanes@0 8 function kbf:OnInitialize()
arkanes@54 9 -- config settings - account wide shared profile by default
arkanes@54 10 self.db = LibStub("AceDB-3.0"):New("KBFSavedVars", self.defaultConfig, true)
arkanes@45 11 -- create frames here so that they will be correctly stored in location cache by
arkanes@45 12 -- the UI.
arkanes@45 13 self.anchor, self.secureHeader, self.consolidateHeader, self.consolidateProxy = self:CreateCoreFrames()
arkanes@10 14 self.debuffFrames = {}
arkanes@0 15 self:RegisterEvent("UNIT_AURA")
arkanes@27 16 self:RegisterEvent("UNIT_ENTERING_VEHICLE", "PollForVehicleChange")
arkanes@27 17 self:RegisterEvent("UNIT_EXITING_VEHICLE", "PollForVehicleChange")
arkanes@57 18 LibStub("AceConfig-3.0"):RegisterOptionsTable("KBF", self.options);
arkanes@57 19 self.profilesFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("KBF", "KBF");
arkanes@38 20 self:RegisterChatCommand("kbf", "ToggleAnchor")
arkanes@45 21
arkanes@45 22 self.oocQueue = {}
arkanes@38 23 end
arkanes@38 24
arkanes@38 25 function kbf:OnEnable()
arkanes@38 26 -- set up the countdown timer
arkanes@4 27 -- TODO: Fancy enable/disable based on whether you have any timed buffs.
arkanes@4 28 -- Not a big deal, how often do you care about that
arkanes@8 29 -- also TODO: Maybe should bucket OnUpdates somehow
arkanes@18 30 -- AceTimer repeating events can only happen at 0.1 seconds, which is probably
arkanes@18 31 -- fast enough for updating, but makes the animation look jerky
arkanes@27 32 -- need to experiment with using animation groups
arkanes@18 33 self.update = CreateFrame("FRAME")
arkanes@18 34 self.update:SetScript("OnUpdate", function() self:OnUpdate() end)
arkanes@7 35 self.dirty = true -- force an immediate scan on login
arkanes@14 36 self:HideBlizzardBuffFrames()
arkanes@0 37 end
arkanes@1 38 -- naming convention
arkanes@17 39 -- a "frame" is the top-level button (secure button from the header, or one I make myself)
arkanes@17 40 -- that will contain the UI information about the buff
arkanes@17 41 -- a "bar" is a frame that has the icon, status bar, ect associated with it
arkanes@0 42
arkanes@20 43 -- Secure aura header doesn't self-bind to vehicle,
arkanes@27 44 -- so this only works out of combat. But thats better than nothing...
arkanes@27 45 function kbf:PollForVehicleChange(event, unit)
arkanes@20 46 if unit ~= "player" then return end
arkanes@20 47 self.dirty = true
arkanes@51 48 local function performSwap()
arkanes@51 49 if UnitHasVehicleUI("player") then
arkanes@51 50 -- only swap if we're in a "real" vehicle with its own actions
arkanes@51 51 -- There is possibly a timing issue here where
arkanes@51 52 -- we have set the poll flag but the unit is not
arkanes@51 53 -- actually "in" the vehicle yet. I'm hoping thats
arkanes@51 54 -- handled by using exited/entered events instead of exiting/entering
arkanes@51 55 self.secureHeader:SetAttribute("unit", "vehicle")
arkanes@51 56 else
arkanes@51 57 self.secureHeader:SetAttribute("unit", "player")
arkanes@51 58 end
arkanes@51 59 end
arkanes@51 60 self:QueueForOOC(performSwap)
arkanes@20 61 end
arkanes@20 62
arkanes@8 63 function kbf:HideBlizzardBuffFrames()
arkanes@8 64 local function HideBlizFrame(frame)
arkanes@8 65 if not frame then return end
arkanes@8 66 frame:UnregisterAllEvents()
arkanes@8 67 frame:SetScript("OnUpdate", nil)
arkanes@8 68 frame:Hide()
arkanes@8 69 frame.Show = function() end
arkanes@8 70 end
arkanes@8 71 HideBlizFrame(BuffFrame)
arkanes@8 72 HideBlizFrame(ConsolidatedBuffs)
arkanes@18 73 HideBlizFrame(TemporaryEnchantFrame)
arkanes@8 74
arkanes@8 75 end
arkanes@8 76
arkanes@45 77 -- enqueues a callable that will be run once in-combat lockdown is past
arkanes@45 78 -- all callables will be executed in a single run, in the order they were enqueued
arkanes@45 79 -- if called when OOC, the function will be called immediately, unless the alwaysQueue parameter is true,
arkanes@45 80 -- in which case it will be appended normally
arkanes@45 81 function kbf:QueueForOOC(func, alwaysQueue)
arkanes@46 82 if InCombatLockdown() or alwaysQueue then
arkanes@45 83 tinsert(self.oocQueue, func)
arkanes@45 84 else
arkanes@45 85 func()
arkanes@45 86 end
arkanes@45 87 end
arkanes@45 88
arkanes@51 89 function kbf:OnUpdate()
arkanes@49 90 -- TODO: only start this polling when we leave combat?
arkanes@49 91 while #self.oocQueue > 0 and not InCombatLockdown() do
arkanes@51 92 local func = table.remove(self.oocQueue)
arkanes@45 93 func()
arkanes@45 94 end
arkanes@45 95
arkanes@38 96 local unit = self.secureHeader:GetAttribute("unit")
arkanes@10 97 local buffCount = 0
arkanes@4 98 for idx=1,99 do
arkanes@38 99 local frame = self.secureHeader:GetAttribute("child"..idx)
arkanes@10 100 if not (frame and frame:IsShown()) then break end
arkanes@64 101 local hasbuff = UnitAura(unit, frame:GetAttribute("index"))
arkanes@10 102 buffCount = buffCount + 1
arkanes@6 103 if self.dirty then
arkanes@10 104 if self:BindBarToBuff(frame, unit) then break end
arkanes@9 105 end
arkanes@10 106 self:UpdateBarExpirationTime(frame)
arkanes@12 107 -- Don't forget to refresh shown tooltips
arkanes@45 108 if (GameTooltip:IsOwned(frame)) then
arkanes@15 109 self:OnEnter(frame)
arkanes@12 110 end
arkanes@10 111 end
arkanes@37 112 -- consolidated buffs
arkanes@37 113 if self.consolidateProxy:IsShown() then
arkanes@37 114 for idx=1,99 do
arkanes@37 115 local frame = self.consolidateHeader:GetAttribute("child"..idx)
arkanes@37 116 if not (frame and frame:IsShown()) then break end
arkanes@37 117 if self.dirty then
arkanes@37 118 if self:BindBarToBuff(frame, unit) then break end
arkanes@37 119 end
arkanes@37 120 self:UpdateBarExpirationTime(frame)
arkanes@37 121 -- Don't forget to refresh shown tooltips
arkanes@37 122 if ( GameTooltip:IsOwned(frame) ) then
arkanes@37 123 self:OnEnter(frame)
arkanes@37 124 end
arkanes@37 125 end
arkanes@41 126 buffCount = buffCount+1
arkanes@37 127 end
arkanes@64 128 -- SAH correctly binds the weapon enchant templates now, but when temp enchants
arkanes@64 129 -- are present and used, it seems that it doesn't correctly hide un-bound
arkanes@64 130 -- buff frames, which breaks all the layout and so forth.
arkanes@64 131 for weapon=3,1,-1 do
arkanes@64 132 local tempEnchant = self.secureHeader:GetAttribute("tempEnchant"..weapon)
arkanes@64 133 if tempEnchant and tempEnchant:IsShown() then
arkanes@64 134 self:BindBarToWeaponEnchant(tempEnchant)
arkanes@64 135 self:UpdateBarExpirationTime(tempEnchant)
arkanes@64 136 buffCount = buffCount + 1
arkanes@64 137 end
arkanes@64 138 end
arkanes@37 139
arkanes@64 140 -- debuffs
arkanes@64 141 -- Since debuffs aren't cancellable, don't need to use the secure header
arkanes@64 142 -- for them. This could be rewritten to support useful features like
arkanes@64 143 -- sorting & scaling and stuff. Honestly, should at least be alphabetical.
arkanes@10 144 for idx=1,99 do
arkanes@10 145 local frame = self.debuffFrames[idx]
arkanes@10 146 if self.dirty then
arkanes@10 147 local name, rank, icon, stacks, debuffType, duration, expirationTime = UnitAura(unit, idx, "HARMFUL")
arkanes@10 148 if not name then
arkanes@10 149 -- out of debuffs, hide all the rest of them
arkanes@10 150 for jdx = idx, 99 do
arkanes@10 151 local bar = self.debuffFrames[jdx]
arkanes@10 152 if bar then bar:Hide() else break end
arkanes@10 153 end
arkanes@10 154 break
arkanes@10 155 end
arkanes@10 156 if not frame then
arkanes@10 157 frame = self:ConstructBar(nil, 1, 0, 0)
arkanes@10 158 self.debuffFrames[idx] = frame
arkanes@10 159 end
arkanes@10 160 self:SetBarAppearance(frame, name, icon, stacks, duration, expirationTime)
arkanes@10 161 frame:ClearAllPoints()
arkanes@10 162 -- position it under all the buffs, with a half-bar spacing
arkanes@41 163 frame:SetPoint("TOP", self.secureHeader, "TOP", 0, (buffCount * -16) - 8)
arkanes@10 164 frame:Show()
arkanes@13 165 frame.filter = "HARMFUL"
arkanes@13 166 frame.unit = unit
arkanes@16 167 frame.index = idx
arkanes@13 168 frame:SetScript("OnEnter", function() kbf:OnEnter(frame) end)
arkanes@13 169 frame:SetScript("OnLeave", function() GameTooltip:Hide() end)
arkanes@23 170 frame:EnableMouse(true)
arkanes@10 171 buffCount = buffCount + 1
arkanes@10 172 else
arkanes@10 173 -- not dirty, so no frame means we're done
arkanes@10 174 if not frame then break end
arkanes@6 175 end
arkanes@10 176 self:UpdateBarExpirationTime(frame)
arkanes@13 177 if ( GameTooltip:IsOwned(frame) ) then
arkanes@15 178 self:OnEnter(frame)
arkanes@13 179 end
arkanes@4 180 end
arkanes@6 181 self.dirty = nil
arkanes@4 182 end
arkanes@4 183
arkanes@0 184 function kbf:UNIT_AURA(event, unit)
arkanes@38 185 if unit ~= self.secureHeader:GetAttribute("unit") then return end
arkanes@6 186 self.dirty = true
arkanes@0 187 end
arkanes@0 188
arkanes@10 189 function kbf:UpdateBarExpirationTime(frame)
arkanes@10 190 if frame.expirationTime then
arkanes@10 191 local remaining = frame.expirationTime - GetTime()
arkanes@10 192 remaining = math.max(0, remaining)
arkanes@10 193 local perc = remaining / frame.duration
arkanes@10 194 frame.timertext:SetText(self:FormatTimeText(remaining))
arkanes@10 195 frame.statusbar:SetValue(remaining)
arkanes@10 196 end
arkanes@10 197 end
arkanes@10 198
arkanes@42 199 local gratt = LibStub:GetLibrary("LibGratuity-3.0")
arkanes@42 200
arkanes@17 201 function kbf:BindBarToWeaponEnchant(parentFrame, slotOverride)
arkanes@17 202 -- allow passing of explicit slot in order to work around aura header bug
arkanes@17 203 local slot = slotOverride or parentFrame:GetAttribute("target-slot")
arkanes@17 204 local itemIndex = slot - 15 -- 1MH, 2OF
arkanes@17 205 local RETURNS_PER_ITEM = 3
arkanes@17 206 local hasEnchant, remaining, enchantCharges = select(RETURNS_PER_ITEM * (itemIndex - 1) + 1, GetWeaponEnchantInfo())
arkanes@17 207 -- remaining time is in milliseconds
arkanes@26 208 if not hasEnchant then return end -- this should never happen
arkanes@17 209 local remaining = remaining / 1000
arkanes@42 210
arkanes@17 211 local icon = GetInventoryItemTexture("player", slot)
arkanes@42 212 local maxDuration
arkanes@42 213 if select(2, UnitClass("player")) == "ROGUE" then
arkanes@42 214 -- Rogues are probably using poisons, which are an hour
arkanes@42 215 maxDuration = 60 * 60
arkanes@42 216 else
arkanes@42 217 -- everyone else is probably using something thats a half hour
arkanes@42 218 maxDuration = 30 * 60
arkanes@42 219 end
arkanes@42 220 local duration = max(maxDuration, remaining)
arkanes@17 221 local expirationTime = GetTime() + remaining
arkanes@17 222 local name = GetItemInfo(GetInventoryItemID("player", slot))
arkanes@42 223 -- try to figure out what the weapon enchant is
arkanes@42 224 -- tooltip string -> {spellid, duration}
arkanes@42 225 local knownEnchants = {
arkanes@42 226 ["Flametongue"] = {8024, 30*60},
arkanes@42 227 ["Frostbrand"] = {8033, 30*60},
arkanes@51 228 ["Earthliving"] = {51730, 30*60},
arkanes@61 229 ["Windfury"] = {8232, 30*60},
arkanes@44 230 ["Instant Poison"] = {8680, 60*60},
arkanes@44 231 ["Wound Poison"] = {13218, 60*60},
arkanes@44 232 ["Deadly Poison"] = {2823, 60*60},
arkanes@42 233
arkanes@42 234 }
arkanes@42 235 local spellId = nil
arkanes@42 236 if gratt then
arkanes@42 237 gratt:SetInventoryItem("player", slot)
arkanes@42 238 for tag, info in pairs(knownEnchants) do
arkanes@42 239 if gratt:Find(tag) then
arkanes@42 240 spellId, duration = unpack(info)
arkanes@42 241 name, _, _ = GetSpellInfo(spellId)
arkanes@47 242 local slots = {[16] = "Main Hand", [17] = "Off Hand", [18] = "Thrown"}
arkanes@62 243 name = tag .. " (" .. slots[slot] .. ")"
arkanes@42 244 break
arkanes@42 245 end
arkanes@42 246 end
arkanes@42 247 end
arkanes@42 248 parentFrame.spellId = spellId
arkanes@17 249 if not parentFrame.icon then
arkanes@17 250 self:ConstructBar(parentFrame, 1, 0, 1)
arkanes@17 251 end
arkanes@17 252 self:SetBarAppearance(parentFrame, name, icon, enchantCharges, duration, expirationTime)
arkanes@17 253 end
arkanes@17 254
arkanes@3 255 function kbf:BindBarToBuff(parentFrame, unit)
arkanes@3 256 local index = parentFrame:GetAttribute("index")
arkanes@3 257 local filter = parentFrame:GetAttribute("filter")
arkanes@10 258 local name, rank, icon, stacks, debuffType, duration, expirationTime,
arkanes@3 259 unitCaster, isStealable, shouldConsolidate, spellId = UnitAura(unit, index, filter)
arkanes@10 260 if not name then return end
arkanes@2 261 if not parentFrame.icon then
arkanes@2 262 self:ConstructBar(parentFrame)
arkanes@0 263 end
arkanes@10 264 self:SetBarAppearance(parentFrame, name, icon, stacks, duration, expirationTime)
arkanes@10 265 end
arkanes@10 266
arkanes@10 267 function kbf:SetBarAppearance(parentFrame, name, icon, stacks, duration, expirationTime)
arkanes@2 268 parentFrame.icon:SetNormalTexture(icon)
arkanes@0 269 if stacks and stacks > 0 then
arkanes@2 270 parentFrame.text:SetText(string.format("%s(%d)", name, stacks))
arkanes@0 271 else
arkanes@2 272 parentFrame.text:SetText(name)
arkanes@0 273 end
arkanes@4 274 parentFrame.timertext:SetText(self:FormatTimeText(duration))
arkanes@4 275 -- store duration information
arkanes@6 276 if duration and duration > 0 then
arkanes@4 277 parentFrame.expirationTime = expirationTime
arkanes@4 278 parentFrame.duration = duration
arkanes@4 279 parentFrame.statusbar:SetMinMaxValues(0, duration)
arkanes@4 280 else
arkanes@4 281 parentFrame.expirationTime = nil
arkanes@4 282 parentFrame.duration = 0
arkanes@4 283 parentFrame.statusbar:SetMinMaxValues(0,1)
arkanes@4 284 parentFrame.statusbar:SetValue(1)
arkanes@4 285 end
arkanes@4 286 end
arkanes@4 287
arkanes@17 288 -- expects time seconds
arkanes@4 289 function kbf:FormatTimeText(time)
arkanes@4 290 if not time or time == 0 then return "" end
arkanes@4 291 local timetext
arkanes@4 292 local h = floor(time/3600)
arkanes@4 293 local m = time - (h*3600)
arkanes@4 294 m = floor(m/60)
arkanes@4 295 local s = time - ((h*3600) + (m*60))
arkanes@4 296 if h > 0 then
arkanes@4 297 timetext = ("%d:%02d"):format(h, m)
arkanes@4 298 elseif m > 0 then
arkanes@4 299 timetext = string.format("%d:%02d", m, floor(s))
arkanes@4 300 elseif s < 10 then
arkanes@4 301 timetext = string.format("%1.1f", s)
arkanes@4 302 else
arkanes@4 303 timetext = string.format("%.0f", floor(s))
arkanes@4 304 end
arkanes@4 305 return timetext
arkanes@0 306 end
arkanes@0 307
arkanes@12 308 function KBF:OnEnter(button, motion)
arkanes@12 309 -- this is for the secure buttons, so use the attributes
arkanes@26 310 local unit = SecureButton_GetModifiedUnit(button) or button.unit -- will perform vehicle toggle
arkanes@21 311 local filter = button:GetAttribute("filter") or button.filter
arkanes@15 312 local index = button:GetAttribute("index") or button.index
arkanes@17 313 if unit and filter and index then
arkanes@21 314 -- I'd like a better place to position this but it's funky for right now, handle it later
arkanes@17 315 GameTooltip:SetOwner(button, "ANCHOR_BOTTOMLEFT");
arkanes@17 316 GameTooltip:SetFrameLevel(button:GetFrameLevel() + 2);
arkanes@17 317 GameTooltip:SetUnitAura(unit, index, filter);
arkanes@17 318 return
arkanes@17 319 end
arkanes@17 320 local slot = button:GetAttribute("target-slot") -- temp enchant
arkanes@42 321 if slot then
arkanes@42 322 GameTooltip:SetOwner(button, "ANCHOR_BOTTOMLEFT");
arkanes@42 323 GameTooltip:SetFrameLevel(button:GetFrameLevel() + 2);
arkanes@42 324 if button.spellId then
arkanes@42 325 -- TODO: This might be too big of a tooltip to care about that much.
arkanes@42 326 -- Maybe I should just have a single line with the weapon name
arkanes@42 327 --GameTooltip:SetInventoryItem(unit, slot)
arkanes@42 328 local name = GetItemInfo(GetInventoryItemID("player", slot))
arkanes@42 329 local r, g, b = GetItemQualityColor(GetInventoryItemQuality("player", slot))
arkanes@42 330 GameTooltip:SetText(name, r, g, b)
arkanes@62 331 local slots = {[16] = "Main Hand", [17] = "Off Hand", [18] = "Thrown"}
arkanes@62 332 GameTooltip:AddLine(slots[slot])
arkanes@42 333 GameTooltip:AddLine(" ")
arkanes@42 334 GameTooltip:AddSpellByID(button.spellId)
arkanes@42 335 else
arkanes@42 336 GameTooltip:SetInventoryItem(unit, slot)
arkanes@42 337 end
arkanes@42 338 end
arkanes@12 339 end
arkanes@12 340
arkanes@1 341 -- creates a icon + statusbar bar
arkanes@10 342 function kbf:ConstructBar(frame, r, g, b)
arkanes@0 343 local texture = "Interface\\TargetingFrame\\UI-StatusBar"
arkanes@1 344 -- Because of secureframe suckiness, these height & width numbers
arkanes@1 345 -- have to be consistent with the stuff in KBF.xml
arkanes@54 346 local height = self.staticConfig.BAR_HEIGHT
arkanes@54 347 local width = self.staticConfig.BAR_WIDTH -- this is the width *without* the icon
arkanes@22 348 local font, _, style = GameFontHighlight:GetFont()
arkanes@10 349 local r = r or 0
arkanes@10 350 local g = g or 1
arkanes@10 351 local b = b or 0
arkanes@10 352 local bgcolor = {r, g, b, 0.5}
arkanes@10 353 local color = {r, g, b, 1}
arkanes@0 354 local fontsize = 11
arkanes@0 355 local timertextwidth = fontsize * 3.6
arkanes@0 356 local textcolor = {1, 1, 1, 1}
arkanes@0 357 local timertextcolor = {1, 1, 1, 1}
arkanes@10 358 if not frame then
arkanes@10 359 frame = CreateFrame("Button", nil, UIParent) -- the "top level" frame that represents the bar as a whole
arkanes@54 360 frame:SetHeight(height)
arkanes@54 361 frame:SetWidth(width + height)
arkanes@10 362 end
arkanes@1 363 local bar = frame
arkanes@0 364 bar.icon = CreateFrame("Button", nil, bar) -- the icon
arkanes@0 365 bar.statusbarbg = CreateFrame("StatusBar", nil, bar) -- the bars background
arkanes@0 366 bar.statusbar = CreateFrame("StatusBar", nil, bar) -- and the bars foreground
arkanes@0 367 bar.text = bar.statusbar:CreateFontString(nil, "OVERLAY") -- the label text
arkanes@0 368 bar.timertext = bar.statusbar:CreateFontString(nil, "OVERLAY") -- and the timer text
arkanes@0 369
arkanes@0 370 -- the icon
arkanes@0 371 bar.icon:ClearAllPoints()
arkanes@0 372 bar.icon:SetPoint("LEFT", bar, "LEFT", 0, 0)
arkanes@0 373 -- icons are square
arkanes@0 374 bar.icon:SetWidth(height)
arkanes@0 375 bar.icon:SetHeight(height)
arkanes@2 376 --bar.icon:EnableMouse(false)
arkanes@0 377 -- the status bar background & foreground
arkanes@0 378 local function setupStatusBar(sb, color)
arkanes@0 379 sb:ClearAllPoints()
arkanes@0 380 sb:SetHeight(height)
arkanes@0 381 sb:SetWidth(width)
arkanes@0 382 -- offset the height of the frame on the x-axis for the icon.
arkanes@0 383 sb:SetPoint("TOPLEFT", bar, "TOPLEFT", height, 0)
arkanes@0 384 sb:SetStatusBarTexture(texture)
arkanes@0 385 sb:GetStatusBarTexture():SetVertTile(false)
arkanes@0 386 sb:GetStatusBarTexture():SetHorizTile(false)
arkanes@0 387 sb:SetStatusBarColor(unpack(color))
arkanes@0 388 sb:SetMinMaxValues(0,1)
arkanes@0 389 sb:SetValue(1)
arkanes@0 390 end
arkanes@0 391 setupStatusBar(bar.statusbarbg, bgcolor)
arkanes@0 392 setupStatusBar(bar.statusbar, color)
arkanes@0 393 bar.statusbarbg:SetFrameLevel(bar.statusbarbg:GetFrameLevel()-1) -- make sure the bg frame stays in the back
arkanes@0 394 -- timer text
arkanes@0 395 bar.timertext:SetFontObject(GameFontHighlight)
arkanes@0 396 bar.timertext:SetFont(GameFontHighlight:GetFont())
arkanes@0 397 bar.timertext:SetHeight(height)
arkanes@0 398 bar.timertext:SetWidth(timertextwidth)
arkanes@24 399 bar.timertext:SetPoint("LEFT", bar.statusbar, "LEFT", 2, 0)
arkanes@24 400 bar.timertext:SetJustifyH("LEFT")
arkanes@0 401 bar.timertext:SetText("time")
arkanes@0 402 bar.timertext:SetTextColor(timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolor[4])
arkanes@0 403
arkanes@0 404 -- and the label text
arkanes@0 405 bar.text:SetFontObject(GameFontHighlight)
arkanes@0 406 bar.text:SetFont(GameFontHighlight:GetFont())
arkanes@0 407 bar.text:SetHeight(height)
arkanes@24 408 bar.text:SetPoint("LEFT", bar.timertext, "RIGHT", 0, 0)
arkanes@0 409 bar.text:SetPoint("RIGHT", bar.statusbar, "RIGHT", 0, 0)
arkanes@0 410 bar.text:SetJustifyH("LEFT")
arkanes@0 411 bar.text:SetText("text")
arkanes@0 412 bar.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolor[4])
arkanes@0 413 return bar
arkanes@0 414 end
arkanes@0 415
arkanes@38 416 function kbf:CreateCoreFrames()
arkanes@38 417 -- this is the visible anchor frame that the user interacts with
arkanes@38 418 -- to move the buffs around
arkanes@54 419 local height = self.staticConfig.BAR_HEIGHT
arkanes@54 420 local width = self.staticConfig.BAR_WIDTH -- this is the width *without* the icon
arkanes@0 421 local anchor = CreateFrame("FRAME", "KBFAnchorFrame", UIParent)
arkanes@0 422 anchor:SetClampedToScreen(true)
arkanes@0 423 anchor:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background",
arkanes@0 424 edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
arkanes@54 425 tile = true, tileSize = height, edgeSize = 12,
arkanes@0 426 insets = { left = 4, right = 4, top = 4, bottom = 4 },
arkanes@0 427 })
arkanes@0 428 local text = anchor:CreateFontString(nil, "OVERLAY") -- the label text
arkanes@0 429 text:SetFontObject(GameFontHighlight)
arkanes@0 430 text:SetFont(GameFontHighlight:GetFont())
arkanes@0 431 text:SetPoint("TOPLEFT", anchor, "TOPLEFT", 0, 0)
arkanes@0 432 text:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", 0, 0)
arkanes@0 433 text:SetText("KBF ANCHOR")
arkanes@54 434 anchor:SetWidth(height + width)
arkanes@54 435 anchor:SetHeight(height)
arkanes@0 436 -- movability
arkanes@0 437 anchor:EnableMouse(true)
arkanes@0 438 anchor:SetMovable(true)
arkanes@0 439 anchor:RegisterForDrag("LeftButton")
arkanes@0 440 anchor:SetScript("OnDragStart", anchor.StartMoving)
arkanes@0 441 anchor:SetScript("OnDragStop", anchor.StopMovingOrSizing)
arkanes@0 442 anchor:ClearAllPoints()
arkanes@22 443 anchor:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", 0, 0)
arkanes@0 444 anchor:Hide()
arkanes@38 445 -- this is the parent & host for the secure aura buttons.
arkanes@0 446
arkanes@38 447 local secureHeader = CreateFrame("FRAME", "KBFBuffFrame", UIParent, "SecureAuraHeaderTemplate")
arkanes@38 448 self:SetCommonSecureHeaderAttributes(secureHeader)
arkanes@54 449 if self.db.profile.consolidateBuffs then
arkanes@54 450 secureHeader:SetAttribute("consolidateTo", 99)
arkanes@54 451 end
arkanes@38 452 secureHeader:SetPoint("TOP", anchor, "TOP", 0, 0)
arkanes@38 453
arkanes@38 454 -- this is the "button" in the aura flow that represents the consolidated buffs.
arkanes@38 455 -- pre-creating it here in order to perform customization
arkanes@40 456 local consolidateProxy = CreateFrame("BUTTON", nil, UIParent, "SecureHandlerClickTemplate")
arkanes@39 457 consolidateProxy:SetNormalTexture("Interface\\TargetingFrame\\UI-StatusBar")
arkanes@39 458 consolidateProxy:SetWidth(200 +16)
arkanes@39 459 consolidateProxy:SetHeight(16)
arkanes@38 460 secureHeader:SetAttribute("consolidateProxy", consolidateProxy)
arkanes@40 461 --secureHeader:SetFrameRef("proxy", consolidateProxy)
arkanes@40 462
arkanes@40 463
arkanes@38 464 -- this is the equivilent of the secureHeader for the consolidated buffs
arkanes@38 465 -- pre-creating again, so we can customize/size/position it
arkanes@38 466 local consolidateHeader = CreateFrame("FRAME", "KBFConsolidatedAnchorFrame", consolidateProxy)
arkanes@38 467 self:SetCommonSecureHeaderAttributes(consolidateHeader)
arkanes@38 468 secureHeader:SetAttribute("consolidateHeader", consolidateHeader)
arkanes@39 469 consolidateProxy:SetAttribute("header", consolidateHeader);
arkanes@40 470 consolidateProxy:SetFrameRef("header", consolidateHeader)
arkanes@40 471
arkanes@40 472 consolidateProxy:SetAttribute("_onclick", [[
arkanes@40 473 local frame = self:GetFrameRef("header")
arkanes@40 474 if frame:IsShown() then frame:Hide() else frame:Show() end
arkanes@40 475 ]])
arkanes@40 476 consolidateProxy:EnableMouse(true)
arkanes@40 477 consolidateProxy:RegisterForClicks("AnyUp")
arkanes@39 478
arkanes@39 479 -- position it relative to the proxy, so it can appear where we want it
arkanes@40 480 consolidateHeader:SetPoint("TOPRIGHT", anchor, "TOPLEFT", 0, 0)
arkanes@54 481 consolidateHeader:SetWidth(height + width)
arkanes@54 482 consolidateHeader:SetHeight(height)
arkanes@38 483 consolidateHeader:Show()
arkanes@39 484
arkanes@38 485 return anchor, secureHeader, consolidateHeader, consolidateProxy
arkanes@37 486 end
arkanes@37 487
arkanes@38 488 --- sets the attributes needed by all the headers
arkanes@38 489 function kbf:SetCommonSecureHeaderAttributes(frame)
arkanes@0 490 frame:SetAttribute("filter", "HELPFUL")
arkanes@20 491 frame:SetAttribute("toggleForVehicle", true) -- this doesn't actually work right now, but maybe it eventually will
arkanes@0 492 frame:SetAttribute("template", "KBFSecureUnitAuraTemplate")
arkanes@3 493 frame:SetAttribute("point", "TOP")
arkanes@0 494 frame:SetAttribute("wrapAfter", 100) -- required due to bugs in secure header
arkanes@2 495 frame:SetAttribute("xOffset", 0)
arkanes@3 496 frame:SetAttribute("yOffset", -16)
arkanes@3 497 frame:SetAttribute("minWidth", 216)
arkanes@3 498 frame:SetAttribute("minHeight", 16)
arkanes@25 499 frame:SetAttribute("unit", "player")
arkanes@3 500 frame:SetAttribute("sortMethod", "NAME")
arkanes@3 501 frame:SetAttribute("sortOrder", "-")
arkanes@64 502
arkanes@17 503 frame:SetAttribute("weaponTemplate", "KBFSecureUnitAuraTemplate")
arkanes@64 504 -- TODO: Enabling temp enchant support breaks layout for regular buffs
arkanes@64 505 frame:SetAttribute("includeWeapons", nil)
arkanes@5 506 frame:Show() -- has to be shown, otherwise the child frames don't show
arkanes@37 507 return frame
arkanes@0 508 end
arkanes@18 509
arkanes@18 510 function kbf:ShowAnchor()
arkanes@38 511 self.secureHeader:ClearAllPoints()
arkanes@38 512 self.secureHeader:SetPoint("TOP", self.anchor, "BOTTOM", 0, 0)
arkanes@18 513 self.anchor:Show()
arkanes@18 514 end
arkanes@18 515
arkanes@18 516 function kbf:HideAnchor()
arkanes@38 517 self.secureHeader:ClearAllPoints()
arkanes@38 518 self.secureHeader:SetPoint("TOP", self.anchor, "TOP", 0, 0)
arkanes@18 519 self.anchor:Hide()
arkanes@18 520 end
arkanes@18 521
arkanes@18 522 function kbf:ToggleAnchor()
arkanes@18 523 if self.anchor:IsShown() then
arkanes@18 524 self:HideAnchor()
arkanes@18 525 else
arkanes@18 526 self:ShowAnchor()
arkanes@18 527 end
arkanes@18 528 end