ad67f41 - Allow MoveAnything to change tooltip location
[wowui.git] / OmaRF / RaidFrame.lua
1 -- RaidFrame.lua
2 local _;
3 local unpack, pairs = unpack, pairs;
4 local format = string.format;
5 local UnitInRange = UnitInRange;
6 local InCombatLockdown = InCombatLockdown;
7 local CreateFrame, RegisterStateDriver, RegisterUnitWatch = CreateFrame, RegisterStateDriver, RegisterUnitWatch;
8 local CTimerAfter = C_Timer.After;
9 local STANDARD_TEXT_FONT = STANDARD_TEXT_FONT;
10 local GameTooltip = GameTooltip;
11 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor;
12
13 local registerEvents = OmaRFEvents.RegisterEvents;
14 local registerUnitEvents = OmaRFEvents.RegisterUnitEvents;
15 local unitEvent = OmaRFEvents.UnitEvent;
16 local setupIndicators = OmaRFIndicators.SetupIndicators;
17
18 local Settings = OmaRFSettings;
19 local baseColor = Settings.BaseColor;
20 local bgColor = Settings.BgColor;
21 local healthColor = Settings.HealthColor;
22 local shieldColor = Settings.ShieldColor;
23 local shieldhlColor = Settings.ShieldhlColor;
24 local healpredColor = Settings.HealpredColor;
25 local healabsorbColor = Settings.HealabsorbColor;
26 local width, height = Settings.Width, Settings.Height;
27 -- placeholders with visible values when error happens
28 local anchorX, anchorY = 10, 10;
29 local attributes = {};
30
31 local CFrame = CreateFrame("Frame", "OmaRFFrame", UIParent);
32 local inheritedFrames = "SecureUnitButtonTemplate,SecureHandlerStateTemplate";
33 local barTexture = "Interface\\AddOns\\OmaRF\\images\\minimalist";
34 local class = nil;
35 local party = {};
36 local raid = {};
37
38 local M = {};
39 OmaRaidFrame = M;
40
41 local function unitUpdate(frame)
42     -- there's no in/out of range event, have to check each frame
43     -- from FrameXML/CompactUnitFrame.lua
44     local inRange, checked = UnitInRange(frame.displayed);
45     if checked and not inRange then
46         frame:SetAlpha(0.55);
47     else
48         frame:SetAlpha(1);
49     end
50 end
51
52 local function frameShow(frame)
53     registerEvents(frame);
54     registerUnitEvents(frame);
55     frame:SetScript("OnUpdate", unitUpdate);
56     unitEvent(frame, "UPDATE_ALL_BARS");
57 end
58
59 local function frameHide(frame)
60     frame:UnregisterAllEvents();
61     frame:SetScript("OnUpdate", nil);
62 end
63
64 local function showTooltip(secure)
65     GameTooltip_SetDefaultAnchor(GameTooltip, secure);
66     GameTooltip:SetUnit(secure:GetAttribute("unit"));
67 end
68
69 local function hideTooltip(secure)
70     GameTooltip:FadeOut();
71 end
72
73 local function setupFrame(frame, secure, unit)
74     secure:SetAttribute("unit", unit);
75     frame:SetAttribute("unit", unit);
76     frame.unit = unit;
77     frame.displayed = unit;
78     -- hide frame to get initial frameShow call
79     frame:Hide();
80     if unit == "player" then frame.vehicle = "vehicle"
81     else frame.vehicle = unit.."pet" end
82     -- create visuals
83     secure:SetWidth(width+2);
84     secure:SetHeight(height+2);
85     frame:SetWidth(width+2);
86     frame:SetHeight(height+2);
87     frame.base = frame:CreateTexture(nil, "BACKGROUND");
88     frame.base:SetAllPoints();
89     frame.base:SetColorTexture(1, 1, 1);
90     frame.base:SetVertexColor(unpack(baseColor));
91     frame.background = frame:CreateTexture(nil, "BACKGROUND", nil, 1);
92     frame.background:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1);
93     frame.background:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
94     frame.background:SetColorTexture(unpack(bgColor));
95     frame.health = frame:CreateTexture(nil, "BORDER");
96     frame.health:SetTexture(barTexture);
97     frame.health:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
98     frame.health:SetPoint("BOTTOMLEFT", frame.background, "BOTTOMLEFT");
99     frame.health:SetVertexColor(unpack(healthColor));
100     frame.mana = frame:CreateTexture(nil, "BORDER");
101     frame.mana:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 2);
102     frame.mana:SetPoint("BOTTOMLEFT", frame.background, "BOTTOMLEFT");
103     frame.mana:SetColorTexture(1, 1, 1);
104     frame.mana:Hide();
105     frame.shield = frame:CreateTexture(nil, "BORDER");
106     frame.shield:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
107     frame.shield:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
108     frame.shield:SetTexture(barTexture);
109     frame.shield:SetVertexColor(unpack(shieldColor));
110     frame.shield:Hide();
111     frame.shieldhl = frame:CreateTexture(nil, "ARTWORK");
112     frame.shieldhl:SetPoint("TOPLEFT", frame.background, "TOPRIGHT", -1, 0);
113     frame.shieldhl:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", 1, 0);
114     frame.shieldhl:SetColorTexture(unpack(shieldhlColor));
115     frame.shieldhl:Hide();
116     frame.healpred = frame:CreateTexture(nil, "ARTWORK");
117     frame.healpred:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
118     frame.healpred:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
119     frame.healpred:SetColorTexture(unpack(healpredColor));
120     frame.healpred:Hide();
121     frame.healabsorb = frame:CreateTexture(nil, "ARTWORK");
122     frame.healabsorb:SetPoint("TOPRIGHT", frame.health, "TOPRIGHT");
123     frame.healabsorb:SetPoint("BOTTOMRIGHT", frame.health, "BOTTOMRIGHT");
124     frame.healabsorb:SetColorTexture(unpack(healabsorbColor));
125     frame.healabsorb:Hide();
126     frame.overlay = frame:CreateTexture(nil, "ARTWORK", nil, 1);
127     frame.overlay:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
128     frame.overlay:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT");
129     frame.overlay:SetColorTexture(1, 1, 1);
130     frame.overlay:Hide();
131     frame.role = frame:CreateTexture(nil, "ARTWORK", nil, 2);
132     frame.role:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", -2, 2);
133     frame.role:SetPoint("TOPLEFT", frame.background, "BOTTOMRIGHT", -14, 14);
134     frame.role:SetTexture("Interface\\LFGFRAME\\LFGROLE");
135     frame.role:Hide();
136     frame.name = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
137     frame.name:SetPoint("CENTER", frame.background, "CENTER", 0, 11);
138     frame.text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
139     frame.text:SetFont(STANDARD_TEXT_FONT, 13);
140     frame.text:SetPoint("CENTER", frame.background, "CENTER", 0, -1);
141     frame.text:Hide();
142     frame.rez = frame:CreateTexture(nil, "OVERLAY");
143     frame.rez:SetPoint("TOPLEFT", frame.background, "CENTER", -12, 12);
144     frame.rez:SetPoint("BOTTOMRIGHT", frame.background, "CENTER", 12, -12);
145     frame.rez:SetTexture("Interface\\RaidFrame\\Raid-Icon-Rez");
146     frame.rez:Hide();
147     frame.ready = frame:CreateTexture(nil, "OVERLAY");
148     frame.ready:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 14);
149     frame.ready:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMLEFT", 14, 0);
150     frame.ready:Hide();
151     frame.targeticon = frame:CreateTexture(nil, "OVERLAY");
152     frame.targeticon:SetPoint("CENTER", frame.background, "TOP");
153     frame.targeticon:SetWidth(12);
154     frame.targeticon:SetHeight(12);
155     frame.targeticon:SetTexture("Interface\\TARGETINGFRAME\\UI-RaidTargetingIcons");
156     frame.targeticon:Hide();
157     -- set up indicators
158     setupIndicators(frame, class);
159     -- set scripts
160     frame:SetScript("OnShow", frameShow);
161     frame:SetScript("OnHide", frameHide);
162     frame:SetScript("OnEvent", unitEvent);
163     secure:SetScript("OnEnter", showTooltip);
164     secure:SetScript("OnLeave", hideTooltip);
165     -- set attributes
166     secure:RegisterForClicks("AnyDown");
167     for attr, val in pairs(attributes) do
168         secure:SetAttribute(attr, val);
169     end
170     -- rest give target and menu
171     secure:SetAttribute("*type1", "target");
172     secure:SetAttribute("*type2", "togglemenu");
173 end
174
175 -- vehicle toggle from Shadowed Unit Frames
176 local vehicletoggle = [=[
177     local unit = self:GetAttribute("unit");
178     if unit and newstate == "vehicle" and not UnitTargetsVehicleInRaidUI(unit) then
179         self:SetAttribute("toggleForVehicle", false);
180     else
181         self:SetAttribute("toggleForVehicle", true);
182     end
183 ]=]
184
185 local function initializeParty(parent)
186     local secure = CreateFrame("Button", "OmaPartySecure0", parent, inheritedFrames);
187     local frame = CreateFrame("Frame", "OmaParty0", parent);
188     local unit = "player";
189     secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
190     frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
191     setupFrame(frame, secure, unit);
192     RegisterStateDriver(frame, "visibility", "[@player,group:raid] hide; show");
193     RegisterStateDriver(secure, "visibility", "[@player,group:raid] hide; show");
194     RegisterStateDriver(secure, "vehicleui", "[vehicleui] vehicle; no");
195     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
196     party[0] = {secure=secure, frame=frame};
197     for i = 1,4 do
198         local secure = CreateFrame("Button", "OmaPartySecure"..i, parent, inheritedFrames);
199         local frame = CreateFrame("Frame", "OmaParty"..i, parent);
200         local unit = "party"..i;
201         secure:SetPoint("TOPLEFT", party[i-1].secure, "TOPRIGHT");
202         frame:SetPoint("TOPLEFT", party[i-1].frame, "TOPRIGHT");
203         setupFrame(frame, secure, unit);
204         local visible = format("[@%s,exists,group:raid] hide; [@%s,exists] show; hide", unit, unit);
205         local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
206         RegisterStateDriver(frame, "visibility", visible);
207         RegisterStateDriver(secure, "visibility", visible);
208         RegisterStateDriver(secure, "vehicleui", vehicle);
209         secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
210         party[i] = {secure=secure, frame=frame};
211     end
212 end
213
214 local function initializeRaid(parent)
215     local secure = CreateFrame("Button", "OmaRaidSecure1", parent, inheritedFrames);
216     local frame = CreateFrame("Frame", "OmaRaid1", parent);
217     local unit = "raid1";
218     secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
219     frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
220     setupFrame(frame, secure, unit);
221     RegisterUnitWatch(frame);
222     RegisterUnitWatch(secure);
223     local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
224     RegisterStateDriver(secure, "vehicleui", vehicle);
225     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
226     raid[1] = {secure=secure, frame=frame};
227     for y = 1,7 do
228         local i = y*5+1;
229         local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
230         local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
231         local unit = "raid"..i;
232         secure:SetPoint("TOPLEFT", raid[i-5].secure, "BOTTOMLEFT");
233         frame:SetPoint("TOPLEFT", raid[i-5].frame, "BOTTOMLEFT");
234         setupFrame(frame, secure, unit);
235         RegisterUnitWatch(frame);
236         RegisterUnitWatch(secure);
237         local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
238         RegisterStateDriver(secure, "vehicleui", vehicle);
239         secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
240         raid[i] = {secure=secure, frame=frame};
241     end
242     for y = 0,7 do
243         for x = 1,4 do
244             local i = y*5+x+1;
245             local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
246             local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
247             local unit = "raid"..i;
248             secure:SetPoint("TOPLEFT", raid[i-1].secure, "TOPRIGHT");
249             frame:SetPoint("TOPLEFT", raid[i-1].frame, "TOPRIGHT");
250             setupFrame(frame, secure, unit);
251             RegisterUnitWatch(frame);
252             RegisterUnitWatch(secure);
253             local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
254             RegisterStateDriver(secure, "vehicleui", vehicle);
255             secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
256             raid[i] = {secure=secure, frame=frame};
257         end
258     end
259 end
260
261 local function initializeFocus(parent)
262     local secure = CreateFrame("Button", "OmaFocusSecure", parent, inheritedFrames);
263     local frame = CreateFrame("Frame", "OmaFocus", parent);
264     local unit = "focus";
265     secure:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
266     frame:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
267     setupFrame(frame, secure, unit);
268     RegisterUnitWatch(frame);
269     RegisterUnitWatch(secure);
270     local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
271     RegisterStateDriver(secure, "vehicleui", vehicle);
272     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
273 end
274
275 local function initialize()
276     _, class = UnitClass("player");
277     anchorX, anchorY = Settings.Character.AnchorX, Settings.Character.AnchorY;
278     attributes = Settings.Character.Clickheal;
279     CFrame:SetFrameStrata("LOW");
280     CFrame:SetPoint("CENTER", nil, "CENTER", anchorX, anchorY);
281     CFrame:SetHeight((height+2)*8);
282     CFrame:SetWidth((width+2)*5);
283     initializeParty(CFrame);
284     initializeRaid(CFrame);
285     initializeFocus(CFrame);
286 end
287
288 -- hiding Blizzard frames somewhat based on ShadowedUF
289 local function hideBlizzardRaidButton()
290     if InCombatLockdown() then return end
291     local manager = CompactRaidFrameManager;
292     -- remove show and unlock buttons from manager
293     manager.displayFrame.hiddenModeToggle:Hide();
294     manager.displayFrame.lockedModeToggle:Hide();
295 end
296
297 local hidden = false;
298 local function hideBlizzardRaid()
299     if hidden then return end
300     hidden = true;
301     local function hide()
302         if InCombatLockdown() then return end
303         CompactRaidFrameContainer:Hide();
304         local shown = CompactRaidFrameManager_GetSetting("IsShown");
305         if shown and shown ~= "0" then
306             CompactRaidFrameManager_SetSetting("IsShown", "0");
307         end
308     end
309
310     CompactRaidFrameContainer:UnregisterAllEvents();
311     -- there may still be frames created at startup getting events
312     for i=1,MAX_RAID_MEMBERS do
313         local frame = _G["CompactRaidFrame"..i];
314         if not frame then break end
315         frame:UnregisterAllEvents();
316     end
317     hooksecurefunc("CompactRaidFrameManager_UpdateShown", hide);
318     hide();
319     CompactRaidFrameContainer:HookScript("OnShow", hide);
320     hooksecurefunc("CompactRaidFrameManager_UpdateOptionsFlowContainer", hideBlizzardRaidButton);
321     hideBlizzardRaidButton();
322
323     -- hide focus frame
324     for _, frame in pairs({FocusFrame, FocusFrameToT, FocusFrameSpellBar}) do
325         frame:UnregisterAllEvents();
326         if frame.healthbar then frame.healthbar:UnregisterAllEvents() end
327         if frame.manabar then frame.manabar:UnregisterAllEvents() end
328         if frame.spellbar then frame.spellbar:UnregisterAllEvents() end
329         if frame.powerBarAlt then frame.powerBarAlt:UnregisterAllEvents() end
330         frame:Hide();
331     end
332 end
333
334 local function updateTooltipFuncs()
335     -- let MoveAnything hook these to anchor tooltip elsewhere
336     GameTooltip = _G["GameTooltip"];
337     GameTooltip_SetDefaultAnchor = _G["GameTooltip_SetDefaultAnchor"];
338 end
339
340 CFrame:RegisterEvent("PLAYER_LOGIN");
341 CFrame:RegisterEvent("PLAYER_ENTERING_WORLD");
342 CFrame:RegisterEvent("PLAYER_REGEN_ENABLED");
343 CFrame:SetScript("OnEvent", function(self, event, addon)
344     if event == "PLAYER_REGEN_ENABLED" then
345         -- if CompactRaidFrameManager_UpdateOptionsFlowContainer was called in combat
346         -- couldn't hide the button
347         hideBlizzardRaidButton();
348     elseif event == "PLAYER_ENTERING_WORLD" then
349         CTimerAfter(0.01, updateTooltipFuncs);
350     elseif event == "PLAYER_LOGIN" then
351         OmaRFLoadChar();
352         hideBlizzardRaid();
353         initialize();
354     end
355 end);