annotate SkeletonUnit/UnitFrame.lua @ 4:a30285f8191e

Units: make sure unit frames are SecureUnitButton derivatives remove of unnecessary target/focus events Stats: resolve GUID after event handlers have fired keep frame manipulation in uf.ui, get needed values from wrapper functions
author Nenue
date Tue, 21 Jun 2016 11:56:14 -0400
parents 07293831dd7b
children
rev   line source
Nenue@0 1 --------------------------------------------
Nenue@0 2 -- KrakTool
Nenue@0 3 -- Nick
Nenue@0 4 -- @project - r e v i s i o n @ @project-hash@
Nenue@0 5 -- @file - r e v i s i o n @ @file-hash@
Nenue@0 6 -- Created: 6/16/2016 3:46 AM
Nenue@0 7 --------------------------------------------
Nenue@0 8
Nenue@1 9 local KT = LibKT.register(SkeletonUnits)
Nenue@3 10 local db
Nenue@0 11 local PLAYER_NAMEPLATE
Nenue@0 12 local PLAYER_WIDTH = 220
Nenue@0 13 local BUFF_SIZE = 24
Nenue@3 14 local uf = SkeletonUnits
Nenue@3 15 local prototypes = {}
Nenue@1 16 local units = {}
Nenue@1 17 local buttons = {}
Nenue@3 18
Nenue@3 19 local params = setmetatable({}, {
Nenue@3 20 __index = function(t, k)
Nenue@3 21 print('get', k)
Nenue@4 22 return t.player
Nenue@3 23 end,
Nenue@3 24 __newindex = function(t, k, v)
Nenue@3 25 if type(v) == 'table' then
Nenue@4 26 print('branch', k)
Nenue@3 27 v = setmetatable(v, {
Nenue@3 28 __index = function(tt, kk)
Nenue@3 29 print('get', k, kk)
Nenue@3 30 return rawget(t.player, kk)
Nenue@3 31 end,
Nenue@3 32 __newindex = function(tt, kk, vv)
Nenue@3 33 if type(vv) == 'table' then
Nenue@4 34 print('_branch', k, kk)
Nenue@3 35 vv = setmetatable(vv, {
Nenue@3 36 __index = function(_tt, _kk)
Nenue@3 37 print('_get', k, kk, _kk)
Nenue@3 38 return rawget(t.player[kk], _kk)
Nenue@3 39 end
Nenue@3 40 })
Nenue@3 41 end
Nenue@3 42 rawset(tt, kk ,vv)
Nenue@3 43 end
Nenue@3 44 })
Nenue@3 45 end
Nenue@3 46 rawset(t,k,v)
Nenue@3 47 end
Nenue@3 48 })
Nenue@3 49
Nenue@3 50 params.player = {
Nenue@3 51 width = 220,
Nenue@3 52 height = 30,
Nenue@3 53 health = { height = 24 },
Nenue@3 54 power = { height = 6},
Nenue@4 55 position = {'CENTER', nil, 'CENTER',0,-120 }
Nenue@4 56 }
Nenue@3 57 params.pet = {
Nenue@3 58 width = 180,
Nenue@4 59 height = 25,
Nenue@4 60
Nenue@4 61 position = {'TOPLEFT', 'player', 'BOTTOMLEFT',0,-4}
Nenue@1 62 }
Nenue@4 63 params.target = {
Nenue@4 64
Nenue@4 65 position = {'TOPLEFT', 'player', 'TOPRIGHT',4,0}
Nenue@4 66 }
Nenue@4 67 params.focus = {
Nenue@4 68 width = 180,
Nenue@4 69 height = 25,
Nenue@4 70 position = {'BOTTOMRIGHT', 'target', 'TOPRIGHT',0,4}
Nenue@4 71 }
Nenue@3 72
Nenue@3 73 uf.handler = uf -- so uf.event can work
Nenue@0 74
Nenue@0 75
Nenue@1 76 local UpdateUnitAnchor = function(self)
Nenue@1 77 self.nameplate = C_NamePlate.GetNamePlateForUnit(self.unit)
Nenue@1 78 if self.nameplate and self.nameplate.namePlateUnitToken then
Nenue@1 79 self:ClearAllPoints()
Nenue@1 80 self:SetPoint('TOP', self.nameplate, 'BOTTOM', 0, 0)
Nenue@1 81 print('snapping', self.unit, 'to', self.nameplate.namePlateUnitToken)
Nenue@1 82 else
Nenue@1 83 self:ClearAllPoints()
Nenue@1 84 self:SetPoint(unpack(self.anchorPoint))
Nenue@1 85 end
Nenue@0 86 end
Nenue@0 87
Nenue@0 88 local SetupButton = function(self, unit, index)
Nenue@1 89 if not buttons[unit][index] then
Nenue@1 90 buttons[unit][index] = CreateFrame('Frame', 'KT'..unit..'Buff'..index, self, 'KTAuraButton')
Nenue@1 91 buttons[unit][index]:SetSize(BUFF_SIZE, BUFF_SIZE)
Nenue@1 92 buttons[unit][index].cooldown:SetHideCountdownNumbers(true)
Nenue@0 93 end
Nenue@1 94 return buttons[unit][index]
Nenue@0 95 end
Nenue@0 96
Nenue@3 97 uf.unit = function(unit)
Nenue@3 98 if not prototypes[unit] then
Nenue@3 99 return
Nenue@3 100 end
Nenue@3 101 print('|cFFFFFF00unit|r:', unit)
Nenue@3 102
Nenue@4 103 local c = params[unit]
Nenue@4 104
Nenue@3 105 if not _G['KT'..unit..'Frame'] then
Nenue@4 106 local new = CreateFrame('Button', 'KT'.. unit .. 'Frame', uf, 'KTUnitFrameTemplate')
Nenue@4 107 new.unit = unit
Nenue@4 108 new.anchorPoint = {new:GetPoint(1)}
Nenue@4 109 new.handler = prototypes[unit]
Nenue@4 110 new.params = c
Nenue@4 111
Nenue@4 112 --if not db.position[unit] then
Nenue@4 113 db.position[unit] = c.position
Nenue@4 114 --end
Nenue@4 115 new.position = db.position[unit]
Nenue@4 116
Nenue@4 117
Nenue@4 118 buttons[unit] = {}
Nenue@4 119 new.buttons = buttons[unit]
Nenue@4 120 new.refresh = prototypes[unit].refresh
Nenue@4 121 new.init = prototypes[unit].init
Nenue@4 122
Nenue@4 123 new:EnableMouse(true)
Nenue@4 124 new:SetScript('OnMouseUp', prototypes[unit].OnMouseUp)
Nenue@4 125
Nenue@4 126 new:SetAttribute("type", "target")
Nenue@4 127 new:SetAttribute("unit", unit)
Nenue@4 128 RegisterUnitWatch(new)
Nenue@4 129 units[unit] = new
Nenue@1 130 end
Nenue@1 131
Nenue@4 132 return _G['KT'..unit..'Frame']
Nenue@1 133 end
Nenue@3 134
Nenue@3 135 uf.ui = function ()
Nenue@1 136 for unit, frame in pairs(units) do
Nenue@3 137 frame.handler.refresh(frame)
Nenue@1 138 end
Nenue@1 139 end
Nenue@1 140
Nenue@3 141 uf.init = function()
Nenue@3 142 uf:RegisterEvent('PLAYER_TARGET_CHANGED')
Nenue@4 143 uf:RegisterEvent('PLAYER_FOCUS_CHANGED')
Nenue@3 144 uf:RegisterUnitEvent("UNIT_AURA")
Nenue@3 145 end
Nenue@3 146
Nenue@3 147 uf.variables = function()
Nenue@3 148 if not FossilDB then
Nenue@3 149 FossilDB = {
Nenue@3 150 units = {'player', 'target', 'focus', 'pet', 'targettarget' },
Nenue@3 151 position = {}
Nenue@3 152 }
Nenue@3 153 end
Nenue@3 154 db = FossilDB
Nenue@3 155
Nenue@3 156 for i, unit in pairs(db.units) do
Nenue@3 157 print(unit)
Nenue@3 158 local frame = uf.unit(unit)
Nenue@3 159 if frame then
Nenue@3 160 frame.handler.init(frame)
Nenue@3 161 end
Nenue@3 162 end
Nenue@3 163 uf.ui()
Nenue@3 164 end
Nenue@3 165
Nenue@3 166 uf.event = function(self, event, ...)
Nenue@1 167 if self.handler[event] then
Nenue@1 168 self.handler[event](self, event, ...)
Nenue@1 169 end
Nenue@3 170 return true
Nenue@1 171 end
Nenue@1 172
Nenue@3 173 uf.PLAYER_TARGET_CHANGED = function()
Nenue@4 174 print('caught target change')
Nenue@4 175 units.target:refresh()
Nenue@4 176 end
Nenue@4 177
Nenue@4 178 uf.PLAYER_FOCUS_CHANGED = function()
Nenue@4 179 units.focus:refresh()
Nenue@1 180 end
Nenue@1 181
Nenue@3 182 prototypes.player = {}
Nenue@3 183 local player = prototypes.player
Nenue@3 184 player.init = function(self)
Nenue@1 185 self:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", self.unit)
Nenue@1 186 self:RegisterUnitEvent("UNIT_POWER_FREQUENT", self.unit)
Nenue@1 187 self:RegisterEvent("NAME_PLATE_UNIT_ADDED")
Nenue@1 188 self:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
Nenue@1 189 self:RegisterEvent("UNIT_TARGET")
Nenue@3 190 self:SetScript('OnEvent', uf.event)
Nenue@4 191
Nenue@4 192 local anchor, parent, relative, x, y = unpack(self.position)
Nenue@4 193 if parent and units[parent] then
Nenue@4 194 parent = units[parent]
Nenue@4 195 else
Nenue@4 196 parent = UIParent
Nenue@4 197 end
Nenue@4 198
Nenue@4 199 self:SetPoint(anchor, parent, relative, x, y)
Nenue@4 200 self:SetSize(self.params.width, self.params.height)
Nenue@4 201
Nenue@1 202 end
Nenue@1 203
Nenue@1 204
Nenue@1 205 --- Runs when event handler decides so
Nenue@3 206 player.refresh = function(self)
Nenue@4 207 print(self.unit, UnitExists(self.unit))
Nenue@1 208 if not UnitExists(self.unit) then
Nenue@4 209 print('hiding unit')
Nenue@1 210 self:Hide()
Nenue@1 211 return
Nenue@1 212 end
Nenue@1 213
Nenue@4 214 self:Show()
Nenue@3 215 if UnitIsPlayer(self.unit) then
Nenue@3 216 local class, classFile = UnitClass(self.unit)
Nenue@3 217 if classFile then
Nenue@3 218 self.healthbar:SetColorTexture(RAID_CLASS_COLORS[classFile].r, RAID_CLASS_COLORS[classFile].g, RAID_CLASS_COLORS[classFile].b)
Nenue@3 219 end
Nenue@3 220 elseif UnitIsFriend('player', self.unit) then
Nenue@3 221 self.healthbar:SetColorTexture(0,.75,0,1)
Nenue@3 222 elseif UnitIsEnemy('player', self.unit) then
Nenue@3 223 self.healthbar:SetColorTexture(1,0,0,1)
Nenue@3 224 else
Nenue@3 225 self.healthbar:SetColorTexture(1,1,0,1)
Nenue@3 226 end
Nenue@3 227 self.powertype = UnitPowerType(self.unit)
Nenue@3 228 if self.powertype then
Nenue@3 229 self.powerbar:SetColorTexture(0,.3,1, 1)
Nenue@3 230
Nenue@3 231 self.handler.UNIT_POWER_FREQUENT(self)
Nenue@3 232 else
Nenue@3 233 self.healthbar:SetHeight(params[self.unit].health.height + params[self.unit].power.height)
Nenue@1 234 end
Nenue@4 235 uf.UNIT_AURA(self, 'UNIT_AURA', self.unit)
Nenue@3 236
Nenue@1 237 self.handler.UNIT_HEALTH_FREQUENT(self)
Nenue@1 238 end
Nenue@1 239
Nenue@4 240
Nenue@3 241 uf.UNIT_AURA = function(self, event, unit)
Nenue@3 242 if not units[unit] then return true end
Nenue@1 243
Nenue@0 244 local buffOffset = 0
Nenue@1 245 local buttons = buttons[unit]
Nenue@0 246 for i = 1, 16 do
Nenue@1 247
Nenue@1 248 local aura, _, texture, count, dispelType, duration, expires, caster = UnitAura(unit, i, 'HARMFUL')
Nenue@0 249 if aura then
Nenue@1 250 local button = SetupButton(units[unit], unit, i)
Nenue@0 251
Nenue@0 252 button.icon:SetTexture(texture)
Nenue@0 253 button.cooldown:SetCooldown(expires - duration, duration)
Nenue@0 254 button.cooldown:Show()
Nenue@0 255 button.count:SetText(count > 0 and count or nil)
Nenue@1 256 button:SetPoint('BOTTOMLEFT', units[unit], 'TOPLEFT', buffOffset* BUFF_SIZE, 2)
Nenue@0 257 button:Show()
Nenue@0 258 buffOffset = buffOffset + 1
Nenue@0 259 else
Nenue@0 260 if buttons[i] then
Nenue@0 261 buttons[i]:Hide()
Nenue@0 262 end
Nenue@0 263 end
Nenue@0 264 end
Nenue@3 265 return true
Nenue@0 266 end
Nenue@0 267
Nenue@3 268 player.NAME_PLATE_UNIT_ADDED = function(self, event, nameplate)
Nenue@3 269 --UpdateUnitAnchor(self)
Nenue@1 270 end
Nenue@3 271 player.NAME_PLATE_UNIT_REMOVED = function(self, event, nameplate)
Nenue@3 272 --UpdateUnitAnchor(self)
Nenue@1 273 end
Nenue@1 274
Nenue@3 275 player.UNIT_HEALTH_FREQUENT = function(self, ...)
Nenue@1 276 if UnitHealthMax(self.unit) > 0 then
Nenue@4 277 self.healthbar:SetWidth(self.params.width * UnitHealth(self.unit) / UnitHealthMax(self.unit))
Nenue@1 278 self.healthtext:SetText(UnitHealth(self.unit))
Nenue@1 279 else
Nenue@1 280 self.healthbar:SetWidth(PLAYER_WIDTH)
Nenue@1 281 self.healthtext:SetText(nil)
Nenue@0 282 end
Nenue@1 283 return true
Nenue@0 284 end
Nenue@1 285
Nenue@3 286 player.UNIT_POWER_FREQUENT = function(self)
Nenue@1 287 if UnitPowerMax(self.unit) > 0 then
Nenue@4 288 self.powerbar:SetWidth(self.params.width * UnitPower(self.unit) / UnitPowerMax(self.unit))
Nenue@1 289 self.powertext:SetText(UnitPower(self.unit))
Nenue@1 290 else
Nenue@1 291 self.powerbar:Hide()
Nenue@1 292 self.powertext:SetText(nil)
Nenue@1 293 end
Nenue@1 294 return true
Nenue@1 295 end
Nenue@1 296
Nenue@1 297
Nenue@3 298 player.UNIT_TARGET = function(self, ...)
Nenue@1 299 if not UnitExists(self.unit) then
Nenue@1 300 self:Hide()
Nenue@1 301 else
Nenue@1 302 self:Show()
Nenue@1 303 self.handler.refresh(self)
Nenue@0 304 end
Nenue@0 305 end
Nenue@0 306
Nenue@3 307 prototypes.pet = player
Nenue@4 308 prototypes.target = player
Nenue@4 309 prototypes.focus = player