1. -- Start config
  2. local font = [=[Interface\AddOns\oUF_Test\media\Simple.TTF]=]
  3. local texture = [=[Interface\AddOns\oUF_Test\media\Statusbar]=]
  4. local font_size = 11
  5. local font_style = 'THINOUTLINE'
  6. local sfix = CreateFrame("Frame")
  7. sfix:RegisterEvent("PLAYER_LOGIN")
  8. sfix:SetScript("OnEvent", function()
  9. SetCVar("useUiScale", 1)
  10. SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
  11. end)
  12. _G["BuffFrame"]:Hide()
  13. _G["BuffFrame"]:UnregisterAllEvents()
  14. _G["BuffFrame"]:SetScript("OnUpdate", nil)
  15. local backdrop = {
  16. bgFile = [=[Interface\Buttons\WHITE8x8]=],
  17. edgeFile = [=[Interface\Buttons\WHITE8x8]=], edgeSize = 1,
  18. insets = {top = 0, bottom = 0, right = 0, left = 0}
  19. }
  20. local CreateBackdrop = function(parent)
  21. local bg = CreateFrame("Frame", nil, parent)
  22. bg:SetPoint('TOPLEFT', parent, 'TOPLEFT', -1, 1)
  23. bg:SetPoint('BOTTOMRIGHT', parent, 'BOTTOMRIGHT', 1, -1)
  24. bg:SetFrameLevel(parent:GetFrameLevel() - 1)
  25. bg:SetBackdrop(backdrop)
  26. bg:SetBackdropColor(0, 0, 0, 0.6)
  27. bg:SetBackdropBorderColor(0, 0, 0, 1)
  28. return bg
  29. end
  30. local CreateFontString = function(frame, fsize, fstyle, sfont)
  31. local fstring = frame:CreateFontString(nil, 'OVERLAY')
  32. fstring:SetFont(font, font_size, font_style)
  33. fstring:SetShadowColor(0, 0, 0, 0)
  34. return fstring
  35. end
  36. local menu = function(self)
  37. local unit = self.unit:gsub("(.)", string.upper, 1)
  38. if _G[unit.."FrameDropDown"] then
  39. ToggleDropDownMenu(1, nil, _G[unit.."FrameDropDown"], "cursor")
  40. elseif self.unit:match("party") then
  41. ToggleDropDownMenu(1, nil, _G["PartyMemberFrame"..self.id.."DropDown"], "cursor")
  42. else
  43. FriendsDropDown.unit = self.unit
  44. FriendsDropDown.id = self.id
  45. FriendsDropDown.initialize = RaidFrameDropDown_Initialize
  46. ToggleDropDownMenu(1, nil, FriendsDropDown, "cursor")
  47. end
  48. end
  49. local SetColors = setmetatable({
  50. power = setmetatable({
  51. ["MANA"] = {0.31, 0.45, 0.63},
  52. ["RAGE"] = {0.69, 0.31, 0.31},
  53. ["FOCUS"] = {0.71, 0.43, 0.27},
  54. ["ENERGY"] = {0.65, 0.63, 0.35},
  55. ["HAPPINESS"] = {0.19, 0.58, 0.58},
  56. ["RUNES"] = {0.55, 0.57, 0.61},
  57. ["RUNIC_POWER"] = {0, 0.82, 1},
  58. }, {__index = oUF.colors.power}),
  59. reaction = setmetatable({
  60. [1] = {0.85, 0.27, 0.27}, -- Hated
  61. [2] = {0.85, 0.27, 0.27}, -- Hostile
  62. [3] = {0.85, 0.27, 0.27}, -- Unfriendly
  63. [4] = {0.85, 0.77, 0.36}, -- Neutral
  64. [5] = {0.33, 0.59, 0.33}, -- Friendly
  65. [6] = {0.33, 0.59, 0.33}, -- Honored
  66. [7] = {0.33, 0.59, 0.33}, -- Revered
  67. [8] = {0.33, 0.59, 0.33}, -- Exalted
  68. }, {__index = oUF.colors.reaction}),
  69. }, {__index = oUF.colors})
  70. local FormatTime = function(s)
  71. local DAY, HOUR, MINUTE = 86400, 3600, 60
  72. if s >= DAY then
  73. return format('%dd', floor(s/DAY + 0.5)), s % DAY
  74. elseif s >= HOUR then
  75. return format('%dh', floor(s/HOUR + 0.5)), s % HOUR
  76. elseif s >= MINUTE then
  77. return format('%dm', floor(s/MINUTE + 0.5)), s % MINUTE
  78. end
  79. return floor(s + 0.5), s - floor(s)
  80. end
  81. UpdateAuraTimer = function(self, elapsed)
  82. if self.timeLeft then
  83. self.elapsed = (self.elapsed or 0) + elapsed
  84. if self.elapsed >= 0.1 then
  85. if not self.first then
  86. self.timeLeft = self.timeLeft - self.elapsed
  87. else
  88. self.timeLeft = self.timeLeft - GetTime()
  89. self.first = false
  90. end
  91. if self.timeLeft > 0 then
  92. local time = FormatTime(self.timeLeft)
  93. self.remaining:SetText(time)
  94. if self.timeLeft < 5 then
  95. self.remaining:SetTextColor(1, 0.2, 0.2)
  96. else
  97. self.remaining:SetTextColor(1, 1, 1)
  98. end
  99. else
  100. self.remaining:Hide()
  101. self:SetScript("OnUpdate", nil)
  102. end
  103. self.elapsed = 0
  104. end
  105. end
  106. end
  107. CreateAuraTimer = function(icon, duration, expTime)
  108. icon.first = true
  109. if duration and duration > 0 then
  110. icon.remaining:Show()
  111. icon.timeLeft = expTime
  112. icon:SetScript("OnUpdate", UpdateAuraTimer)
  113. else
  114. icon.remaining:Hide()
  115. icon.timeLeft = 0
  116. icon:SetScript("OnUpdate", nil)
  117. end
  118. end
  119. PostUpdateDebuff = function(self, unit, icon, index)
  120. local name, _, _, _, dtype, duration, expTime = UnitAura(unit, index, icon.filter)
  121. local c = DebuffTypeColor[dtype] or DebuffTypeColor.none
  122. icon.bg:SetBackdropBorderColor(c.r, c.g, c.b)
  123. icon.icon:SetDesaturated(true)
  124. CreateAuraTimer(icon, duration, expTime)
  125. end
  126. PostUpdateBuff = function(self, unit, icon, index)
  127. local name, _, _, _, dtype, duration, expTime = UnitAura(unit, index, icon.filter)
  128. CreateAuraTimer(icon, duration, expTime)
  129. end
  130. local CancelAura = function(self, button)
  131. if button == "RightButton" and not self.debuff then
  132. CancelUnitBuff("player", self:GetID())
  133. end
  134. end
  135. PostCreateAuraIcon = function(self, button)
  136. button.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
  137. button.icon:SetDrawLayer('ARTWORK')
  138. button.overlay:SetTexture(nil)
  139. button.remaining = CreateFontString(button)
  140. button.remaining:SetPoint('CENTER', 1, 1)
  141. button.count:SetFont(font, font_size, font_style)
  142. button.count:SetPoint('TOPRIGHT', button, 3, 19)
  143. button.bg = CreateBackdrop(button)
  144. if unit == "player" then
  145. button:SetScript("OnMouseUp", CancelAura)
  146. end
  147. end
  148. local ShortValue = function(value)
  149. if value >= 10000000 then
  150. return string.format('%.1fm', value / 1000000)
  151. elseif value >= 1000000 then
  152. return string.format('%.2fm', value / 1000000)
  153. elseif value >= 100000 then
  154. return string.format('%.0fk', value / 1000)
  155. elseif value >= 10000 then
  156. return string.format('%.1fk', value / 1000)
  157. else
  158. return value
  159. end
  160. end
  161. local PostUpdateHealthBar = function(health, unit, min, max)
  162. if not UnitIsConnected(unit) or UnitIsGhost(unit) or UnitIsDead(unit) then
  163. if not UnitIsConnected(unit) then
  164. health.value:SetText("|cffD7BEA5".."Offline".."|r")
  165. elseif UnitIsDead(unit) then
  166. health.value:SetText("|cffD7BEA5".."Dead".."|r")
  167. elseif UnitIsGhost(unit) then
  168. health.value:SetText("|cffD7BEA5".."Ghost".."|r")
  169. end
  170. else
  171. local r, g, b
  172. if min ~= max then
  173. r, g, b = oUF.ColorGradient(min/max, 0.69, 0.31, 0.31, 0.65, 0.63, 0.35, 0.33, 0.59, 0.33)
  174. if unit == "player" and health:GetAttribute("normalUnit") ~= "pet" then
  175. health.value:SetFormattedText("|cffAF5050%d|r |cffD7BEA5-|r |cff%02x%02x%02x%s%%|r", min, r * 255, g * 255, b * 255, math.floor(min /max*100+.5))
  176. elseif unit == "pet" then
  177. health.value:SetFormattedText("|cff%02x%02x%02x%s|r", r * 255, g * 255, b * 255, ShortValue(min))
  178. else
  179. health.value:SetFormattedText("|cffAF5050%s|r |cffD7BEA5-|r |cff%02x%02x%02x%s%%|r", ShortValue(min), r * 255, g * 255, b * 255, math.floor(min /max*100+.5))
  180. end
  181. else
  182. if unit ~= "player" and unit ~= "pet" then
  183. health.value:SetText("|cff559655"..ShortValue(max).."|r")
  184. else
  185. health.value:SetText("|cff559655"..max.."|r")
  186. end
  187. end
  188. end
  189. end
  190. PreUpdatePower = function(power, unit)
  191. local _, pType = UnitPowerType(unit)
  192. local color = SetColors.power[pType]
  193. if color then
  194. power:SetStatusBarColor(color[1], color[2], color[3])
  195. end
  196. end
  197. PostUpdatePower = function(power, unit, min, max)
  198. local self = power:GetParent()
  199. local pType, pToken = UnitPowerType(unit)
  200. local color = SetColors.power[pToken]
  201. if color then
  202. power.value:SetTextColor(color[1], color[2], color[3])
  203. end
  204. if not UnitIsPlayer(unit) and not UnitPlayerControlled(unit) or not UnitIsConnected(unit) then
  205. power.value:SetText()
  206. elseif UnitIsDead(unit) or UnitIsGhost(unit) then
  207. power.value:SetText()
  208. else
  209. if min ~= max then
  210. if pType == 0 then
  211. if unit == "target" then
  212. power.value:SetText(ShortValue(min))
  213. elseif unit == "player" and power:GetAttribute("normalUnit") == "pet" then
  214. power.value:SetFormattedText("%%s%%", math.floor(min /max*100+.5))
  215. elseif unit == "player" then
  216. power.value:SetFormattedText("%s%% |cffD7BEA5-|r %d", math.floor(min /max*100+.5), min)
  217. else
  218. power.value:SetText(min)
  219. end
  220. else
  221. power.value:SetText(min)
  222. end
  223. else
  224. if unit == "player" or unit == 'arena' then
  225. power.value:SetText(min)
  226. else
  227. power.value:SetText(ShortValue(min))
  228. end
  229. end end
  230. end
  231. local CreateStyle = function(self, unit)
  232. self:RegisterForClicks('AnyUp')
  233. self:SetScript('OnEnter', UnitFrame_OnEnter)
  234. self:SetScript('OnLeave', UnitFrame_OnLeave)
  235. self.colors = SetColors
  236. self:SetAttribute('type2', 'menu')
  237. self.menu = menu
  238. self.Health = CreateFrame('StatusBar', nil, self)
  239. self.Health:SetStatusBarTexture(texture)
  240. self.Health:SetHeight(25)
  241. self.Health:SetPoint('TOPLEFT')
  242. self.Health:SetPoint('TOPRIGHT')
  243. self.Health.PostUpdate = PostUpdateHealthBar
  244. self.Health.frequentUpdates = true
  245. self.Health.colorTapping = true
  246. self.Health.colorClass = true
  247. self.Health.colorReaction = true
  248. self.Health.bg = self.Health:CreateTexture(nil, 'BORDER')
  249. self.Health.bg:SetAllPoints()
  250. self.Health.bg:SetTexture(texture)
  251. self.Health.bg.multiplier = 0.25
  252. self.Health.background = CreateBackdrop(self.Health)
  253. self.Health.value = CreateFontString(self.Health)
  254. if unit == 'player' or unit == 'target' then
  255. self.Health.value:SetPoint('RIGHT', 0, 4)
  256. elseif unit == 'pet' or unit == 'focus' or unit == 'targettarget' then
  257. self.Health.value:SetPoint('LEFT', 0, 1)
  258. end
  259. self.Power = CreateFrame('StatusBar', nil, self)
  260. self.Power:SetStatusBarTexture(texture)
  261. self.Power:SetHeight(4)
  262. self.Power:SetFrameLevel(10)
  263. self.Power:SetPoint('TOPRIGHT', self.Health, 'BOTTOMRIGHT', 0, 0)
  264. self.Power:SetPoint('TOPLEFT', self.Health, 'BOTTOMLEFT', 0, 0)
  265. self.Power.PreUpdate = PreUpdatePower
  266. self.Power.PostUpdate = PostUpdatePower
  267. self.Power.bg = self.Power:CreateTexture(nil, 'BORDER')
  268. self.Power.bg:SetAllPoints()
  269. self.Power.bg:SetTexture(texture)
  270. self.Power.bg.multiplier = 0.3
  271. self.Power.background = CreateBackdrop(self.Power)
  272. self.Power.frequentUpdates = true
  273. self.Power.colorDisconnected = true
  274. self.Power.colorTapping = true
  275. self.Power.colorPower = true
  276. self.Power.value = CreateFontString(self.Power)
  277. if unit == 'player' or unit == 'target' then
  278. self.Power.value:SetPoint('RIGHT', 0, 3)
  279. end
  280. self.Info = CreateFontString(self.Health)
  281. if unit == 'target' then
  282. self.Info:SetPoint('LEFT', 0, 4)
  283. self:Tag(self.Info, '[difficulty][level][shortclassification] [raidcolor][name]')
  284. elseif (not unit == 'player') or unit == 'pet' or unit == 'focus' or unit == 'targettarget' then
  285. self.Info:SetPoint('RIGHT', 0, 1)
  286. self:Tag(self.Info, '[raidcolor][name]')
  287. end
  288. if unit == 'player' or unit == 'target' then
  289. self:SetAttribute('initial-height', 25)
  290. self:SetAttribute('initial-width', 205)
  291. elseif unit == 'pet' or unit == 'focus' or unit == 'targettarget' then
  292. self:SetAttribute('initial-height', 15)
  293. self:SetAttribute('initial-width', 130)
  294. self.Health:SetHeight(15)
  295. self.Power:SetHeight(2)
  296. end
  297. self.Resting = self.Health:CreateTexture(nil, "OVERLAY")
  298. self.Resting:SetHeight(20)
  299. self.Resting:SetWidth(20)
  300. self.Resting:SetPoint('RIGHT', self, 0, 4)
  301. self.Combat = self.Health:CreateTexture(nil, "OVERLAY")
  302. self.Combat:SetHeight(20)
  303. self.Combat:SetWidth(20)
  304. self.Combat:SetPoint('LEFT', self, 0, 4)
  305. self.Leader = self.Health:CreateTexture(nil, 'OVERLAY')
  306. self.Leader:SetPoint('TOPLEFT', self, 0, 5)
  307. self.Leader:SetHeight(12)
  308. self.Leader:SetWidth(12)
  309. self.RaidIcon = self.Health:CreateTexture(nil, 'OVERLAY')
  310. self.RaidIcon:SetPoint('TOPRIGHT', self, 0, 5)
  311. self.RaidIcon:SetHeight(12)
  312. self.RaidIcon:SetWidth(12)
  313. self.Assistant = self.Health:CreateTexture(nil, "OVERLAY")
  314. self.Assistant:SetPoint('TOPLEFT', 0, 5)
  315. self.Assistant:SetHeight(12)
  316. self.Assistant:SetWidth(12)
  317. self.MasterLooter = self.Health:CreateTexture(nil, "OVERLAY")
  318. self.MasterLooter:SetPoint('TOP', 0, 5)
  319. self.MasterLooter:SetHeight(12)
  320. self.MasterLooter:SetWidth(12)
  321. self.Portrait = CreateFrame("PlayerModel", nil, self)
  322. self.Portrait:SetWidth(29)
  323. self.Portrait:SetHeight(29)
  324. if unit == 'player' then
  325. self.Portrait:SetPoint('LEFT', self.Health, 'LEFT', -32, -2)
  326. elseif unit == 'target' then
  327. self.Portrait:SetPoint('RIGHT', self.Health, 'RIGHT', 32, -2)
  328. end
  329. self.Portrait.bg = CreateBackdrop(self.Portrait)
  330. if unit == 'player' then
  331. self.Buffs = CreateFrame("Frame", nil, self)
  332. self.Buffs:SetPoint('TOPRIGHT', UIParent, 'TOPRIGHT', -150, -9)
  333. self.Buffs.initialAnchor = 'TOPRIGHT'
  334. self.Buffs["growth-y"] = 'DOWN'
  335. self.Buffs["growth-x"] = 'LEFT'
  336. self.Buffs:SetHeight(55)
  337. self.Buffs:SetWidth(450)
  338. self.Buffs.spacing = 3
  339. self.Buffs.size = 26
  340. self.Buffs.num = 32
  341. self.Buffs.disableCooldown = true
  342. self.Buffs.PostCreateIcon = PostCreateAuraIcon
  343. self.Buffs.PostUpdateIcon = PostUpdateBuff
  344. self.Debuffs = CreateFrame("Frame", nil, self)
  345. self.Debuffs:SetPoint('TOPRIGHT', UIParent, 'TOPRIGHT', -150, -116)
  346. self.Debuffs.initialAnchor = 'TOPRIGHT'
  347. self.Debuffs["growth-x"] = 'LEFT'
  348. self.Debuffs["growth-y"] = 'DOWN'
  349. self.Debuffs:SetHeight(55)
  350. self.Debuffs:SetWidth(450)
  351. self.Debuffs.spacing = 3
  352. self.Debuffs.size = 26
  353. self.Debuffs.num = 32
  354. self.Debuffs.disableCooldown = true
  355. self.Debuffs.PostCreateIcon = PostCreateAuraIcon
  356. self.Debuffs.PostUpdateIcon = PostUpdateDebuff
  357. elseif unit == 'target' then
  358. self.Auras = CreateFrame("Frame", nil, self)
  359. self.Auras:SetPoint('BOTTOMLEFT', self, 'TOPLEFT', 0, 3)
  360. self.Auras.initialAnchor = 'BOTTOMLEFT'
  361. self.Auras["growth-x"] = 'RIGHT'
  362. self.Auras["growth-y"] = 'UP'
  363. self.Auras.numDebuffs = 16
  364. self.Auras.numBuffs = 32
  365. self.Auras:SetHeight(165)
  366. self.Auras:SetWidth(221)
  367. self.Auras.spacing = 3
  368. self.Auras.size = 23
  369. self.Auras.gap = true
  370. self.Auras.disableCooldown = true
  371. self.Auras.PostCreateIcon = PostCreateAuraIcon
  372. self.Auras.PostUpdateIcon = PostUpdateBuff
  373. end
  374. self.Castbar = CreateFrame("StatusBar", nil, self)
  375. self.Castbar:SetStatusBarTexture(texture)
  376. self.Castbar:SetStatusBarColor(0.31, 0.45, 0.63)
  377. self.Castbar.bg = CreateBackdrop(self.Castbar)
  378. self.Castbar.Text = CreateFontString(self.Castbar)
  379. self.Castbar.Text:SetPoint('LEFT', 0, 1)
  380. self.Castbar.Time = CreateFontString(self.Castbar)
  381. self.Castbar.Time:SetPoint('RIGHT', 0, 1)
  382. self.Castbar.Button = CreateFrame('Frame', nil, self.Castbar)
  383. self.Castbar.Button:SetHeight(18)
  384. self.Castbar.Button:SetWidth(18)
  385. if unit == 'player' then
  386. self.Castbar.Button:SetPoint('BOTTOMRIGHT', self.Castbar, 'BOTTOMLEFT', -3, 0)
  387. elseif unit == 'target' then
  388. self.Castbar.Button:SetPoint('BOTTOMLEFT', self.Castbar, 'BOTTOMRIGHT', 3, 0)
  389. end
  390. self.Castbar.Button.bg = CreateBackdrop(self.Castbar.Button)
  391. self.Castbar.Icon = self.Castbar.Button:CreateTexture(nil, 'ARTWORK')
  392. self.Castbar.Icon:SetAllPoints(self.Castbar.Button)
  393. self.Castbar.Icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
  394. if unit == 'player' or unit == 'target' then
  395. self.Castbar:SetWidth(205)
  396. self.Castbar:SetHeight(15)
  397. self.Castbar:SetPoint('BOTTOM', self.Health, 0, -22)
  398. end
  399. end
  400. oUF:Factory(function(self)
  401. oUF:RegisterStyle('Alt', CreateStyle)
  402. self:SetActiveStyle('Alt')
  403. local player = self:Spawn('player')
  404. player:SetPoint('BOTTOM', UIParent, -150, 300)
  405. local target = self:Spawn('target')
  406. target:SetPoint('BOTTOM', UIParent, 150, 300)
  407. local focus = self:Spawn('focus')
  408. focus:SetPoint('BOTTOM', UIParent, 321, 310)
  409. local pet = self:Spawn('pet')
  410. pet:SetPoint('BOTTOM', UIParent, -187, 260)
  411. local targettarget = self:Spawn('targettarget')
  412. targettarget:SetPoint('BOTTOM', UIParent, 188, 260)
  413. end)

oUF Layout