956383a - Update all libraries
[wowui.git] / Indicators.lua
1 local media = LibStub:GetLibrary("LibSharedMedia-3.0");
2 local f = RaidFrameCustomization.frames;
3 local positions = RaidFrameCustomization.positions;
4 local pad = 2;
5 local paddings = {
6     TOPLEFT = {pad, -pad},
7     TOPRIGHT = {-pad, -pad},
8     CENTER = {0, 0},
9     BOTTOMLEFT = {pad, pad},
10     BOTTOMRIGHT = {-pad, pad}
11 };
12 local watchedAuras; -- all watched auras
13 local auraFilters = {"HELPFUL", "HARMFUL"};
14 local DEFAULT_ICON = "Interface\\AddOns\\RaidFrameCustomization\\images\\rhomb";
15 local _;
16
17 -- global functions used every update
18 local GetTime = GetTime;
19 local UnitAura = UnitAura;
20 local UnitIsPlayer = UnitIsPlayer;
21 local UnitIsConnected = UnitIsConnected;
22 local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
23 local CompactRaidFrameContainer_ApplyToFrames = CompactRaidFrameContainer_ApplyToFrames;
24
25 -- list of important auras TODO try to use spellIDs
26 local centerAuras = {
27     "Power Word: Shield"
28 };
29
30 local function configureIndicators(frame, name)
31     local frameName = name or frame:GetName();
32     if not f[frameName] then return end
33
34     local config = RaidFrameCustomization.db.profile;
35     local font = media and media:Fetch('font', config.indicatorFont) or STANDARD_TEXT_FONT;
36     for pos, ind in pairs(f[frameName]) do
37         ind.text:SetFont(font, config[pos]["textSize"]);
38         ind.text:SetTextColor(unpack(config[pos]["textColor"]));
39         ind.icon:SetWidth(config[pos]["iconSize"]);
40         ind.icon:SetHeight(config[pos]["iconSize"]);
41         ind.icon:SetTexture(DEFAULT_ICON);
42         ind.icon:SetVertexColor(unpack(config[pos]["iconColor"]));
43         if config[pos]["showIcon"] then
44             ind.icon:Show();
45         else
46             ind.icon:Hide();
47         end
48     end
49 end
50
51 -- Create the FontStrings used for indicators
52 local function setupCompactUnitFrame(frame, name)
53     f[name] = {};
54     for _, pos in ipairs(positions) do
55         f[name][pos] = {};
56         f[name][pos].text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
57         f[name][pos].text:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
58         f[name][pos].icon = frame:CreateTexture(nil, "OVERLAY");
59         f[name][pos].icon:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
60     end
61     configureIndicators(frame, name);
62 end
63
64 -- Check the indicators on a frame and update the times on them
65 local function updateIndicators(frame)
66     local frameName = frame:GetName();
67     local unit = frame.unit;
68
69     -- Create indicators if needed
70     if not f[frameName] then setupCompactUnitFrame(frame, frameName) end
71     -- Reset current
72     for _, ind in pairs(f[frameName]) do
73         ind.text:SetText("");
74         ind.icon:SetTexture("");
75     end
76     -- Hide if unit is dead/disconnected
77     if (not UnitIsConnected(unit)) or UnitIsDeadOrGhost(frame.displayedUnit) then
78         return;
79     end
80
81     local name, icon, count, debuff, expires, caster, id;
82     local current = GetTime();
83     for _, filter in ipairs(auraFilters) do
84         local i = 1;
85         while true do
86             name, _, icon, count, debuff, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
87             if not id then break end
88             local pos = watchedAuras[name] or watchedAuras[id] or watchedAuras[debuff];
89             if pos then
90                 local config = RaidFrameCustomization.db.profile[pos];
91                 if not config.mine or UnitIsPlayer(caster) then
92                     if config.showIcon and not config.useDefaultIcon then
93                         -- show icon TODO coloring
94                         ind.icon:SetTexture(icon);
95                     end
96                     if config.showText then
97                         -- show text
98                         local text;
99                         local remaining = expires - current;
100                         if remaining > 60 then
101                             text = string.format("%dm", ceil(remaining/60));
102                         else
103                             text = string.format("%d", floor(remaining+0.5));
104                         end
105                         if count > 1 and config.stack then
106                             if text then
107                                 text = count.."-"..text;
108                             else
109                                 text = count;
110                             end
111                         end
112
113                         ind.text:SetText(text);
114                     end
115                 end
116             end
117             i = i + 1;
118         end
119     end
120 end
121
122 -- Update all indicators
123 function RaidFrameCustomization:UpdateAllIndicators()
124     CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", updateIndicators);
125 end
126
127 -- Used to update everything that is affected by the configuration
128 function RaidFrameCustomization:RefreshConfig()
129     self:OnDisable(); -- clear everything
130     if self.db.profile.enabled then
131         CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", configureIndicators);
132         -- Format aura strings
133         watchedAuras = {};
134         for _, pos in ipairs(positions) do
135             for _, aura in ipairs(self.db.profile[pos]["auras"]) do
136                 watchedAuras[aura] = pos; -- TODO single aura only in one position
137             end
138         end
139
140         if next(watchedAuras) ~= nil then
141             self.updateTimer = self:ScheduleRepeatingTimer("UpdateAllIndicators", 0.15);
142         end
143     end
144 end