56591cf - Delete unnecessary libraries
[wowui.git] / OmaRF / Indicators.lua
1 local f = OmaRF.frames;
2 local majorFrames = OmaRF.majorFrames;
3 local positions = OmaRF.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;
13 local majorAuras;
14 local auraFilters = {"HELPFUL", "HARMFUL"};
15 local DEFAULT_ICON = "Interface\\AddOns\\OmaRF\\images\\rhomb";
16 local _;
17
18 -- global functions used every update
19 local C_TimerAfter = C_Timer.After;
20 local GetTime = GetTime;
21 local UnitAura = UnitAura;
22 local UnitIsPlayer = UnitIsPlayer;
23 local UnitIsConnected = UnitIsConnected;
24 local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
25 local CompactRaidFrameContainer_ApplyToFrames = CompactRaidFrameContainer_ApplyToFrames;
26 local format = string.format;
27 local unpack = unpack;
28 local floor = floor;
29 local ceil = ceil;
30
31 local function configureIndicators(frame, name)
32     local frameName = name or frame:GetName();
33     if not f[frameName] then return end
34
35     local config = OmaRF.db.profile.indicators;
36     for pos, ind in pairs(f[frameName]) do
37         ind.text:SetFont(STANDARD_TEXT_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     end
44
45     config = OmaRF.db.profile.majorAuras;
46     for i, ind in ipairs(majorFrames[frameName]) do
47         if i == 1 then
48             ind.icon:ClearAllPoints();
49             ind.icon:SetPoint("CENTER", frame, "CENTER", -config.iconSize, 0);
50         end
51         ind.icon:SetWidth(config.iconSize);
52         ind.icon:SetHeight(config.iconSize);
53         ind.expire:SetFont(STANDARD_TEXT_FONT, config["textSize"], "OUTLINE");
54         ind.stack:SetFont(STANDARD_TEXT_FONT, config["textSize"], "OUTLINE");
55     end
56 end
57
58 -- Create the FontStrings used for indicators
59 local function setupCompactUnitFrame(frame, name)
60     f[name] = {};
61     for _, pos in ipairs(positions) do
62         f[name][pos] = {};
63         f[name][pos].text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
64         f[name][pos].text:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
65         f[name][pos].icon = frame:CreateTexture(nil, "OVERLAY");
66         f[name][pos].icon:SetPoint(pos, frame, pos, paddings[pos][1], paddings[pos][2]);
67     end
68
69     local config = OmaRF.db.profile.majorAuras;
70     majorFrames[name] = {};
71     for i = 1, config.max do
72         majorFrames[name][i] = {};
73         majorFrames[name][i].icon = frame:CreateTexture(nil, "OVERLAY");
74         if i > 1 then
75             majorFrames[name][i].icon:SetPoint("TOPLEFT", majorFrames[name][i-1].icon, "TOPRIGHT");
76         end
77         majorFrames[name][i].expire = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
78         majorFrames[name][i].expire:SetPoint("BOTTOMRIGHT", majorFrames[name][i].icon, "BOTTOMRIGHT");
79         majorFrames[name][i].stack = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall");
80         majorFrames[name][i].stack:SetPoint("TOPLEFT", majorFrames[name][i].icon, "TOPLEFT");
81     end
82
83     configureIndicators(frame, name);
84 end
85
86 local function remaining(expires, current)
87     local remain = expires - current;
88     if remain > 60 then
89         return format("%dm", ceil(remain/60));
90     end
91     return floor(remain+0.5);
92 end
93
94 -- Check the indicators on a frame and update the times on them
95 local function updateIndicators(frame)
96     local frameName = frame:GetName();
97     local unit = frame.unit;
98     if not unit then return end -- possible if the frame is just being hidden
99
100     -- Create indicators if needed
101     if not f[frameName] then setupCompactUnitFrame(frame, frameName) end
102     -- Reset current
103     for _, ind in pairs(f[frameName]) do
104         ind.text:Hide();
105         ind.icon:Hide();
106     end
107     for _, ind in ipairs(majorFrames[frameName]) do
108         ind.icon:Hide();
109         ind.expire:Hide();
110         ind.stack:Hide();
111     end
112     -- Hide if unit is dead/disconnected
113     if (not UnitIsConnected(unit)) or UnitIsDeadOrGhost(frame.displayedUnit) then
114         return;
115     end
116
117     local name, icon, count, debuff, expires, caster, id;
118     local current = GetTime();
119     local majorI = 1;
120     local majorMax = OmaRF.db.profile.majorAuras["max"];
121     for _, filter in ipairs(auraFilters) do
122         local i = 1;
123         while true do
124             name, _, icon, count, debuff, _, expires, caster, _, _, id = UnitAura(unit, i, filter);
125             if not id then break end
126             local pos = watchedAuras[name] or watchedAuras[id] or watchedAuras[debuff];
127             if pos then
128                 local ind = f[frameName][pos];
129                 local config = OmaRF.db.profile.indicators[pos];
130                 if not config.mine or UnitIsPlayer(caster) then
131                     if config.showIcon then
132                         -- show icon
133                         if config.useDefaultIcon then
134                             ind.icon:SetTexture(DEFAULT_ICON);
135                         else
136                             ind.icon:SetTexture(icon);
137                         end
138                         ind.icon:Show()
139                     end
140                     if config.showText then
141                         -- show text
142                         ind.text:SetText(remaining(expires, current));
143                         ind.text:Show();
144                     end
145                 end
146             end
147
148             if majorI <= majorMax and (majorAuras[id] or majorAuras[name]) then
149                 local ind = majorFrames[frameName][majorI];
150                 ind.icon:SetTexture(icon);
151                 ind.icon:Show();
152                 ind.expire:SetText(remaining(expires, current));
153                 ind.expire:Show();
154                 if count > 1 then
155                     ind.stack:SetText(count);
156                     ind.stack:Show();
157                 end
158                 majorI = majorI + 1;
159             end
160             i = i + 1;
161         end
162     end
163 end
164
165 -- Update all indicators
166 function OmaRF:UpdateAllIndicators()
167     CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", updateIndicators);
168     if OmaRF.running then
169         C_TimerAfter(0.15, OmaRF.UpdateAllIndicators);
170     end
171 end
172
173 -- Used to update everything that is affected by the configuration
174 function OmaRF:RefreshConfig()
175     self:OnDisable(); -- clear everything
176     if self.db.profile.enabled then
177         CompactRaidFrameContainer_ApplyToFrames(CompactRaidFrameContainer, "normal", configureIndicators);
178         watchedAuras = {};
179         for _, pos in ipairs(positions) do
180             for _, aura in ipairs(self.db.profile.indicators[pos]["auras"]) do
181                 watchedAuras[aura] = pos; -- TODO single aura only in one position
182             end
183         end
184         majorAuras = {};
185         for _, aura in ipairs(self.db.profile.majorAuras["auras"]) do
186             majorAuras[aura] = true;
187         end
188
189         if next(watchedAuras) ~= nil or next(majorAuras) ~= nil then
190             self.running = true;
191             C_TimerAfter(0.15, self.UpdateAllIndicators);
192         end
193     end
194 end