DataTexts.lua 25.3 KB
Newer Older
Azilroka's avatar
Azilroka committed
1
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
2 3
local DT = E:GetModule('DataTexts')
local TT = E:GetModule('Tooltip')
Simpy's avatar
Simpy committed
4
local LDB = E.Libs.LDB
Azilroka's avatar
Azilroka committed
5
local LSM = E.Libs.LSM
6

7
local _G = _G
8 9
local tostring, format, type, pcall = tostring, format, type, pcall
local tinsert, ipairs, pairs, wipe, sort = tinsert, ipairs, pairs, wipe, sort
Simpy's avatar
Simpy committed
10
local next, strfind, strlen, strsplit = next, strfind, strlen, strsplit
Simpy's avatar
boop <3  
Simpy committed
11
local CloseDropDownMenus = CloseDropDownMenus
Simpy's avatar
stuff  
Simpy committed
12
local CreateFrame = CreateFrame
Simpy's avatar
boop <3  
Simpy committed
13
local EasyMenu = EasyMenu
14
local InCombatLockdown = InCombatLockdown
Simpy's avatar
boop <3  
Simpy committed
15 16
local IsInInstance = IsInInstance
local MouseIsOver = MouseIsOver
Simpy's avatar
Simpy committed
17
local RegisterStateDriver = RegisterStateDriver
Simpy's avatar
boop <3  
Simpy committed
18
local UIDropDownMenu_SetAnchor = UIDropDownMenu_SetAnchor
Simpy's avatar
Simpy committed
19
local UnregisterStateDriver = UnregisterStateDriver
Simpy's avatar
Simpy committed
20 21 22 23
local C_CurrencyInfo_GetCurrencyInfo = C_CurrencyInfo.GetCurrencyInfo
local C_CurrencyInfo_GetCurrencyListSize = C_CurrencyInfo.GetCurrencyListSize
local C_CurrencyInfo_GetCurrencyListInfo = C_CurrencyInfo.GetCurrencyListInfo
local C_CurrencyInfo_GetCurrencyListLink = C_CurrencyInfo.GetCurrencyListLink
Azilroka's avatar
Azilroka committed
24
local C_CurrencyInfo_GetCurrencyIDFromLink = C_CurrencyInfo.GetCurrencyIDFromLink
Simpy's avatar
Simpy committed
25
local C_CurrencyInfo_ExpandCurrencyList = C_CurrencyInfo.ExpandCurrencyList
Azilroka's avatar
Azilroka committed
26 27
local GetNumSpecializations = GetNumSpecializations
local GetSpecializationInfo = GetSpecializationInfo
28
local MISCELLANEOUS = MISCELLANEOUS
Simpy's avatar
boop <3  
Simpy committed
29

Simpy's avatar
Simpy committed
30 31
local LFG_TYPE_DUNGEON = LFG_TYPE_DUNGEON
local expansion = _G['EXPANSION_NAME'..GetExpansionLevel()]
Simpy's avatar
Simpy committed
32
local ActivateHyperMode
Simpy's avatar
<3 beep  
Simpy committed
33
local HyperList = {}
Azilroka's avatar
P I M P  
Azilroka committed
34

35 36
DT.tooltip = CreateFrame('GameTooltip', 'DataTextTooltip', E.UIParent, 'GameTooltipTemplate')
DT.EasyMenu = CreateFrame('Frame', 'DataTextEasyMenu', E.UIParent, 'UIDropDownMenuTemplate')
37

Azilroka's avatar
P I M P  
Azilroka committed
38
DT.SelectedDatatext = nil
Simpy's avatar
<3 beep  
Simpy committed
39
DT.HyperList = HyperList
40 41
DT.RegisteredPanels = {}
DT.RegisteredDataTexts = {}
Simpy's avatar
Simpy committed
42
DT.LoadedInfo = {}
Simpy's avatar
Simpy committed
43 44 45 46 47
DT.PanelPool = {
	InUse = {},
	Free = {},
	Count = 0
}
48

49
DT.FontStrings = {}
Simpy's avatar
Simpy committed
50
DT.AssignedDatatexts = {}
Simpy's avatar
Simpy committed
51 52 53 54 55 56 57 58
DT.UnitEvents = {
	UNIT_AURA = true,
	UNIT_RESISTANCES = true,
	UNIT_STATS = true,
	UNIT_ATTACK_POWER = true,
	UNIT_RANGED_ATTACK_POWER = true,
	UNIT_TARGET = true,
	UNIT_SPELL_HASTE = true
59
}
60

Simpy's avatar
Simpy committed
61
DT.SPECIALIZATION_CACHE = {}
62

Azilroka's avatar
Azilroka committed
63
function DT:SetEasyMenuAnchor(menu, dt)
Azilroka's avatar
Cleanup  
Azilroka committed
64
	local point = E:GetScreenQuadrant(dt)
Simpy's avatar
boop <3  
Simpy committed
65 66
	local bottom = point and strfind(point, 'BOTTOM')
	local left = point and strfind(point, 'LEFT')
Azilroka's avatar
Azilroka committed
67

Simpy's avatar
boop <3  
Simpy committed
68 69
	local anchor1 = (bottom and left and 'BOTTOMLEFT') or (bottom and 'BOTTOMRIGHT') or (left and 'TOPLEFT') or 'TOPRIGHT'
	local anchor2 = (bottom and left and 'TOPLEFT') or (bottom and 'TOPRIGHT') or (left and 'BOTTOMLEFT') or 'BOTTOMRIGHT'
Azilroka's avatar
Azilroka committed
70

Azilroka's avatar
Azilroka committed
71
	UIDropDownMenu_SetAnchor(menu, 0, 0, anchor1, dt, anchor2)
Azilroka's avatar
Azilroka committed
72
end
Simpy's avatar
boop <3  
Simpy committed
73

Azilroka's avatar
Azilroka committed
74 75 76
--> [HyperDT Credits] <--
--> Original Work: NihilisticPandemonium
--> Modified by Azilroka! :)
Azilroka's avatar
Azilroka committed
77

Azilroka's avatar
Cleanup  
Azilroka committed
78
function DT:SingleHyperMode(_, key, active)
Azilroka's avatar
P I M P  
Azilroka committed
79 80
	if DT.SelectedDatatext and (key == 'LALT' or key == 'RALT') then
		if active == 1 and MouseIsOver(DT.SelectedDatatext) then
Azilroka's avatar
Cleanup  
Azilroka committed
81
			DT:OnLeave()
Azilroka's avatar
P I M P  
Azilroka committed
82
			DT:SetEasyMenuAnchor(DT.EasyMenu, DT.SelectedDatatext)
Azilroka's avatar
Azilroka committed
83
			EasyMenu(HyperList, DT.EasyMenu, nil, nil, nil, 'MENU')
Azilroka's avatar
Cleanup  
Azilroka committed
84 85 86 87 88 89
		elseif _G.DropDownList1:IsShown() and not _G.DropDownList1:IsMouseOver() then
			CloseDropDownMenus()
		end
	end
end

Simpy's avatar
merp  
Simpy committed
90
function DT:HyperClick()
Azilroka's avatar
P I M P  
Azilroka committed
91 92
	DT.SelectedDatatext = self
	DT:SetEasyMenuAnchor(DT.EasyMenu, DT.SelectedDatatext)
Azilroka's avatar
Azilroka committed
93
	EasyMenu(HyperList, DT.EasyMenu, nil, nil, nil, 'MENU')
Simpy's avatar
boop <3  
Simpy committed
94 95
end

Simpy's avatar
merp  
Simpy committed
96
function DT:EnableHyperMode(Panel)
Azilroka's avatar
Cleanup  
Azilroka committed
97 98
	DT:OnLeave()

Simpy's avatar
merp  
Simpy committed
99 100
	if Panel then
		for _, dt in pairs(Panel.dataPanels) do
Azilroka's avatar
Azilroka committed
101
			dt.overlay:Show()
Simpy's avatar
boop <3  
Simpy committed
102 103
			dt:SetScript('OnEnter', nil)
			dt:SetScript('OnLeave', nil)
Simpy's avatar
Simpy committed
104
			dt:SetScript('OnClick', DT.HyperClick)
Simpy's avatar
Simpy committed
105
		end
Simpy's avatar
merp  
Simpy committed
106 107 108 109 110 111 112 113 114
	else
		for _, panel in pairs(DT.RegisteredPanels) do
			for _, dt in pairs(panel.dataPanels) do
				dt.overlay:Show()
				dt:SetScript('OnEnter', nil)
				dt:SetScript('OnLeave', nil)
				dt:SetScript('OnClick', DT.HyperClick)
			end
		end
Azilroka's avatar
Azilroka committed
115
	end
Azilroka's avatar
Azilroka committed
116
end
Simpy's avatar
Simpy committed
117 118 119 120

function DT:OnEnter()
	if E.db.datatexts.noCombatHover and InCombatLockdown() then return end

Simpy's avatar
test  
Simpy committed
121
	if self.parent then
Azilroka's avatar
P I M P  
Azilroka committed
122
		DT.SelectedDatatext = self
Simpy's avatar
Simpy committed
123
		DT:SetupTooltip(self)
Simpy's avatar
test  
Simpy committed
124
	end
Azilroka's avatar
Cleanup  
Azilroka committed
125

Simpy's avatar
Simpy committed
126 127 128 129
	if self.MouseEnters then
		for _, func in ipairs(self.MouseEnters) do
			func(self)
		end
Azilroka's avatar
Azilroka committed
130
	end
Simpy's avatar
Simpy committed
131 132

	DT.MouseEnter(self)
Azilroka's avatar
Azilroka committed
133 134
end

Simpy's avatar
Simpy committed
135 136 137 138 139
function DT:OnLeave()
	if self.MouseLeaves then
		for _, func in ipairs(self.MouseLeaves) do
			func(self)
		end
Azilroka's avatar
Azilroka committed
140
	end
Simpy's avatar
Simpy committed
141 142 143

	DT.MouseLeave(self)
	DT.tooltip:Hide()
Azilroka's avatar
Azilroka committed
144 145
end

Simpy's avatar
Simpy committed
146 147
function DT:MouseEnter()
	local frame = self.parent or self
Simpy's avatar
Simpy committed
148
	if frame.db and frame.db.mouseover then
Simpy's avatar
Simpy committed
149
		E:UIFrameFadeIn(frame, 0.2, frame:GetAlpha(), 1)
Azilroka's avatar
Azilroka committed
150 151 152
	end
end

Simpy's avatar
Simpy committed
153 154
function DT:MouseLeave()
	local frame = self.parent or self
Simpy's avatar
Simpy committed
155
	if frame.db and frame.db.mouseover then
Simpy's avatar
Simpy committed
156
		E:UIFrameFadeOut(frame, 0.2, frame:GetAlpha(), 0)
Azilroka's avatar
Azilroka committed
157 158 159
	end
end

Simpy's avatar
Simpy committed
160
function DT:FetchFrame(givenName)
Simpy's avatar
Simpy committed
161 162
	local panelExists = DT.PanelPool.InUse[givenName]
	if panelExists then return panelExists end
Azilroka's avatar
Azilroka committed
163

Simpy's avatar
Simpy committed
164
	local count = DT.PanelPool.Count
Simpy's avatar
Simpy committed
165
	local name = 'ElvUI_DTPanel' .. count
Simpy's avatar
Simpy committed
166 167 168 169 170 171 172
	local frame

	local poolName, poolFrame = next(DT.PanelPool.Free)
	if poolName then
		frame = poolFrame
		DT.PanelPool.Free[poolName] = nil
	else
173
		frame = CreateFrame('Frame', name, E.UIParent, 'BackdropTemplate')
Simpy's avatar
Simpy committed
174 175 176 177 178 179 180 181
		DT.PanelPool.Count = DT.PanelPool.Count + 1
	end

	DT.PanelPool.InUse[givenName] = frame

	return frame
end

Simpy's avatar
Simpy committed
182 183 184 185 186 187
function DT:EmptyPanel(panel)
	panel:Hide()

	for _, dt in ipairs(panel.dataPanels) do
		dt:UnregisterAllEvents()
		dt:SetScript('OnUpdate', nil)
Simpy's avatar
Simpy committed
188
		dt:SetScript('OnEvent', nil)
Simpy's avatar
Simpy committed
189 190 191 192
		dt:SetScript('OnEnter', nil)
		dt:SetScript('OnLeave', nil)
		dt:SetScript('OnClick', nil)
	end
Simpy's avatar
Simpy committed
193

Simpy's avatar
Simpy committed
194 195 196
	UnregisterStateDriver(panel, 'visibility')
	E:DisableMover(panel.moverName)
end
Simpy's avatar
Simpy committed
197

Simpy's avatar
Simpy committed
198 199 200 201
function DT:ReleasePanel(givenName)
	local panel = DT.PanelPool.InUse[givenName]
	if panel then
		DT:EmptyPanel(panel)
Simpy's avatar
Simpy committed
202 203
		DT.PanelPool.Free[givenName] = panel
		DT.PanelPool.InUse[givenName] = nil
Simpy's avatar
Simpy committed
204
		DT.RegisteredPanels[givenName] = nil
205
		E.db.movers[panel.moverName] = nil
Simpy's avatar
Simpy committed
206 207 208
	end
end

209
function DT:BuildPanelFrame(name, db, fromInit)
Azilroka's avatar
Azilroka committed
210
	db = db or E.global.datatexts.customPanels[name] or DT:Panel_DefaultGlobalSettings(name)
Azilroka's avatar
Azilroka committed
211

Simpy's avatar
Simpy committed
212
	local Panel = DT:FetchFrame(name)
Azilroka's avatar
Azilroka committed
213
	Panel:ClearAllPoints()
Simpy's avatar
Simpy committed
214
	Panel:Point('CENTER')
Simpy's avatar
Simpy committed
215
	Panel:Size(db.width, db.height)
Azilroka's avatar
Azilroka committed
216

Simpy's avatar
Simpy committed
217
	local MoverName = 'DTPanel'..name..'Mover'
Simpy's avatar
Simpy committed
218 219 220
	Panel.moverName = MoverName
	Panel.givenName = name

Simpy's avatar
Simpy committed
221 222
	local holder = E:GetMoverHolder(MoverName)
	if holder then
223
		E:SetMoverPoints(MoverName, Panel)
Simpy's avatar
Simpy committed
224
	else
Merathilis's avatar
Merathilis committed
225
		E:CreateMover(Panel, MoverName, name, nil, nil, nil, nil, nil, 'datatexts,panels')
Simpy's avatar
Simpy committed
226 227
	end

Azilroka's avatar
Azilroka committed
228
	DT:RegisterPanel(Panel, db.numPoints, db.tooltipAnchor, db.tooltipXOffset, db.tooltipYOffset, db.growth == 'VERTICAL')
229

230
	if not fromInit then
Simpy's avatar
Simpy committed
231
		DT:UpdatePanelAttributes(name, db)
232
	end
Azilroka's avatar
Azilroka committed
233 234
end

235
local LDBhex, LDBna = '|cffFFFFFF', {['N/A'] = true, ['n/a'] = true, ['N/a'] = true}
Simpy's avatar
Simpy committed
236
function DT:BuildPanelFunctions(name, obj)
Simpy's avatar
Simpy committed
237
	local panel
238

239
	local function OnEnter(dt)
Azilroka's avatar
LDB DT  
Azilroka committed
240
		DT.tooltip:ClearLines()
Simpy's avatar
Simpy committed
241 242
		if obj.OnTooltipShow then obj.OnTooltipShow(DT.tooltip) end
		if obj.OnEnter then obj.OnEnter(dt) end
Azilroka's avatar
LDB DT  
Azilroka committed
243
		DT.tooltip:Show()
244
	end
245

246
	local function OnLeave(dt)
Simpy's avatar
Simpy committed
247
		if obj.OnLeave then obj.OnLeave(dt) end
248
	end
249

250
	local function OnClick(dt, button)
251 252 253
		if obj.OnClick then
			obj.OnClick(dt, button)
		end
254
	end
255

Simpy's avatar
Simpy committed
256
	local function UpdateText(_, Name, _, Value)
Simpy's avatar
Simpy committed
257
		if not Value or (strlen(Value) >= 3) or (Value == Name or LDBna[Value]) then
258
			panel.text:SetText((not LDBna[Value] and Value) or Name)
259
		else
260
			panel.text:SetFormattedText('%s: %s%s|r', Name, LDBhex, Value)
261
		end
262
	end
263

264
	local function OnCallback(Hex)
265
		if name and obj then
266
			LDBhex = Hex
Simpy's avatar
boop <3  
Simpy committed
267
			LDB.callbacks:Fire('LibDataBroker_AttributeChanged_'..name..'_text', name, nil, obj.text, obj)
268 269 270 271
		end
	end

	local function OnEvent(dt)
Simpy's avatar
Simpy committed
272
		panel = dt
Simpy's avatar
boop <3  
Simpy committed
273 274
		LDB:RegisterCallback('LibDataBroker_AttributeChanged_'..name..'_text', UpdateText)
		LDB:RegisterCallback('LibDataBroker_AttributeChanged_'..name..'_value', UpdateText)
275
		OnCallback(LDBhex)
276
	end
277

Simpy's avatar
Simpy committed
278 279
	return OnEnter, OnLeave, OnClick, OnCallback, OnEvent, UpdateText
end
Simpy's avatar
Simpy committed
280

Simpy's avatar
Simpy committed
281 282
function DT:SetupObjectLDB(name, obj)
	local onEnter, onLeave, onClick, onCallback, onEvent = DT:BuildPanelFunctions(name, obj)
Azilroka's avatar
Azilroka committed
283
	local data = DT:RegisterDatatext(name, 'Data Broker', nil, onEvent, nil, onClick, onEnter, onLeave)
Simpy's avatar
Simpy committed
284 285
	E.valueColorUpdateFuncs[onCallback] = true
	data.isLibDataBroker = true
286

287
	-- Update config if it has been loaded
288
	if DT.PanelLayoutOptions then
289 290
		DT:PanelLayoutOptions()
	end
291
end
292

293 294 295 296
function DT:RegisterLDB()
	for name, obj in LDB:DataObjectIterator() do
		DT:SetupObjectLDB(name, obj)
	end
297 298
end

Azilroka's avatar
Azilroka committed
299
function DT:GetDataPanelPoint(panel, i, numPoints, vertical)
300 301 302
	if numPoints == 1 then
		return 'CENTER', panel, 'CENTER'
	else
Azilroka's avatar
Azilroka committed
303 304 305
		local point, relativePoint, xOffset, yOffset = 'LEFT', i == 1 and 'LEFT' or 'RIGHT', 4, 0
		if vertical then
			point, relativePoint, xOffset, yOffset = 'TOP', i == 1 and 'TOP' or 'BOTTOM', 0, -4
306
		end
Azilroka's avatar
Azilroka committed
307

Simpy's avatar
Simpy committed
308
		local lastPanel = (i == 1 and panel) or panel.dataPanels[i - 1]
Azilroka's avatar
Azilroka committed
309
		return point, lastPanel, relativePoint, xOffset, yOffset
310 311 312 313 314
	end
end

function DT:SetupTooltip(panel)
	local parent = panel:GetParent()
Azilroka's avatar
Azilroka committed
315
	DT.tooltip:SetOwner(panel, parent.anchor, parent.xOff, parent.yOff)
Simpy's avatar
Simpy committed
316

317 318
	if not _G.GameTooltip:IsForbidden() then
		_G.GameTooltip:Hide() -- WHY??? BECAUSE FUCK GAMETOOLTIP, THATS WHY!!
319
	end
320 321
end

Azilroka's avatar
Azilroka committed
322
function DT:RegisterPanel(panel, numPoints, anchor, xOff, yOff, vertical)
Simpy's avatar
Simpy committed
323
	local realName = panel:GetName()
Simpy's avatar
Simpy committed
324
	local name = panel.givenName or realName
Simpy's avatar
Simpy committed
325

Azilroka's avatar
Azilroka committed
326 327 328 329 330 331
	if not name then
		E:Print('DataTexts: Requires a panel name.')
		return
	end

	DT.RegisteredPanels[name] = panel
332 333 334 335 336

	panel:SetScript('OnEnter', DT.OnEnter)
	panel:SetScript('OnLeave', DT.OnLeave)
	panel:SetScript('OnSizeChanged', DT.PanelSizeChanged)

Azilroka's avatar
Azilroka committed
337
	panel.dataPanels = panel.dataPanels or {}
338 339 340 341
	panel.numPoints = numPoints
	panel.xOff = xOff
	panel.yOff = yOff
	panel.anchor = anchor
Azilroka's avatar
Azilroka committed
342
	panel.vertical = vertical
Azilroka's avatar
Azilroka committed
343
end
Simpy's avatar
Simpy committed
344

Azilroka's avatar
Azilroka committed
345 346
function DT:Panel_DefaultGlobalSettings(name)
	local db = E:CopyTable({}, G.datatexts.newPanelInfo)
Simpy's avatar
Simpy committed
347

Azilroka's avatar
Azilroka committed
348
	E.global.datatexts.customPanels[name] = db
349

Azilroka's avatar
Azilroka committed
350
	return db
351 352
end

353
function DT:AssignPanelToDataText(dt, data, event, ...)
Azilroka's avatar
@Benik  
Azilroka committed
354 355
	dt.name = data.name or '' -- This is needed for Custom Currencies

Simpy's avatar
Simpy committed
356
	if data.events then
Simpy's avatar
Simpy committed
357
		for _, ev in pairs(data.events) do
358 359 360 361 362
			if data.eventFunc then
				if data.objectEvent then
					if not dt.objectEventFunc then
						dt.objectEvent = data.objectEvent
						dt.objectEventFunc = function(_, ...)
363 364 365
							if data.eventFunc then
								data.eventFunc(dt, ...)
							end
366 367 368 369 370 371
						end
					end
					if not E:HasFunctionForObject(ev, data.objectEvent, dt.objectEventFunc) then
						E:RegisterEventForObject(ev, data.objectEvent, dt.objectEventFunc)
					end
				elseif DT.UnitEvents[ev] then
Simpy's avatar
Simpy committed
372
					pcall(dt.RegisterUnitEvent, dt, ev, 'player')
373
				else
Simpy's avatar
Simpy committed
374
					pcall(dt.RegisterEvent, dt, ev)
375
				end
376 377 378 379
			end
		end
	end

380
	local ev = event or 'ELVUI_FORCE_UPDATE'
381 382 383 384 385
	if data.eventFunc then
		if not data.objectEvent then
			dt:SetScript('OnEvent', data.eventFunc)
		end

Simpy's avatar
Simpy committed
386
		data.eventFunc(dt, ev, ...)
387 388
	end

Simpy's avatar
Simpy committed
389
	if data.onUpdate then
Simpy's avatar
Simpy committed
390 391
		dt:SetScript('OnUpdate', data.onUpdate)
		data.onUpdate(dt, 20000)
392 393
	end

Simpy's avatar
Simpy committed
394
	if data.onClick then
Simpy's avatar
Simpy committed
395
		dt:SetScript('OnClick', function(p, button)
Simpy's avatar
Simpy committed
396
			if E.db.datatexts.noCombatClick and InCombatLockdown() then return end
397
			data.onClick(p, button)
Simpy's avatar
Simpy committed
398
			DT.tooltip:Hide()
399 400 401
		end)
	end

Simpy's avatar
Simpy committed
402
	if data.onEnter then
Simpy's avatar
Simpy committed
403 404 405 406
		tinsert(dt.MouseEnters, data.onEnter)
	end
	if data.onLeave then
		tinsert(dt.MouseLeaves, data.onLeave)
407 408 409
	end
end

Simpy's avatar
Simpy committed
410 411 412 413 414 415 416 417 418 419 420 421 422
function DT:ForceUpdate_DataText(name)
	for dtSlot, dtName in pairs(DT.AssignedDatatexts) do
		if dtName.name == name then
			if dtName.colorUpdate then
				dtName.colorUpdate(E.media.hexvaluecolor)
			end
			if dtName.eventFunc then
				dtName.eventFunc(dtSlot, 'ELVUI_FORCE_UPDATE')
			end
		end
	end
end

423 424 425 426 427 428 429 430 431 432 433
function DT:GetTextAttributes(panel, db)
	local panelWidth, panelHeight = panel:GetSize()
	local numPoints = db and db.numPoints or panel.numPoints or 1
	local vertical = db and db.vertical or panel.vertical

	local width, height = (panelWidth / numPoints) - 4, panelHeight - 4
	if vertical then width, height = panelWidth - 4, (panelHeight / numPoints) - 4 end

	return width, height, vertical, numPoints
end

434 435
-- this is used to make texts show on init load, when the font was added after elvui but registers
-- during the load screen, for some reason blizzard doesnt render the font unless we change the
Simpy's avatar
Simpy committed
436 437
-- text after the first frame? its probably related to the texture not inheriting alpha problem.
-- also, this seems to be a problem with SetJustifyH not triggering a rerender too. ~Simpy
438 439 440 441 442 443
local RerenderFont = function(fs)
	local text = fs:GetText()
	fs:SetText('\10')
	fs:SetText(text)
end

444 445
local FixFonts = function(fontStrings)
	for fs in pairs(fontStrings) do
446 447
		RerenderFont(fs)
	end
448
end
449

Simpy's avatar
Simpy committed
450
function DT:UpdatePanelInfo(panelName, panel, ...)
Simpy's avatar
Simpy committed
451
	if not panel then panel = DT.RegisteredPanels[panelName] end
Azilroka's avatar
Azilroka committed
452
	local db = panel.db or P.datatexts.panels[panelName] and DT.db.panels[panelName]
Azilroka's avatar
Azilroka committed
453 454
	if not db then return end

Simpy's avatar
Simpy committed
455
	local info = DT.LoadedInfo
456
	local font, fontSize, fontOutline = info.font, info.fontSize, info.fontOutline
Simpy's avatar
Simpy committed
457
	if db and db.fonts and db.fonts.enable then
Simpy's avatar
boop <3  
Simpy committed
458
		font, fontSize, fontOutline = LSM:Fetch('font', db.fonts.font), db.fonts.fontSize, db.fonts.fontOutline
Simpy's avatar
Simpy committed
459 460
	end

Simpy's avatar
Simpy committed
461
	local chatPanel = panelName == 'LeftChatDataPanel' or panelName == 'RightChatDataPanel'
Simpy's avatar
Simpy committed
462
	local battlePanel = info.isInBattle and chatPanel and (not DT.ForceHideBGStats and E.db.datatexts.battleground)
Simpy's avatar
Simpy committed
463 464
	if battlePanel then
		DT:RegisterEvent('UPDATE_BATTLEFIELD_SCORE')
Simpy's avatar
Simpy committed
465
		DT.ShowingBattleStats = info.instanceType
Simpy's avatar
Simpy committed
466 467 468 469 470
	elseif chatPanel and DT.ShowingBattleStats then
		DT:UnregisterEvent('UPDATE_BATTLEFIELD_SCORE')
		DT.ShowingBattleStats = nil
	end

471
	local width, height, vertical, numPoints = DT:GetTextAttributes(panel, db)
472

Azilroka's avatar
Azilroka committed
473 474 475
	for i = 1, numPoints do
		local dt = panel.dataPanels[i]
		if not dt then
476
			dt = CreateFrame('Button', panelName..'_DataText'..i, panel)
Simpy's avatar
Simpy committed
477 478
			dt.MouseEnters = {}
			dt.MouseLeaves = {}
Simpy's avatar
boop <3  
Simpy committed
479
			dt:RegisterForClicks('AnyUp')
Azilroka's avatar
Azilroka committed
480

Azilroka's avatar
Azilroka committed
481
			local text = dt:CreateFontString(nil, 'ARTWORK')
Simpy's avatar
boop <3  
Simpy committed
482 483 484
			text:SetAllPoints()
			text:SetJustifyV('MIDDLE')
			dt.text = text
485
			DT.FontStrings[text] = true
Azilroka's avatar
Azilroka committed
486

Simpy's avatar
boop <3  
Simpy committed
487
			local overlay = dt:CreateTexture(nil, 'OVERLAY')
Azilroka's avatar
Azilroka committed
488 489
			overlay:SetTexture(E.media.blankTex)
			overlay:SetVertexColor(0.3, 0.9, 0.3, .3)
Simpy's avatar
boop <3  
Simpy committed
490 491
			overlay:SetAllPoints()
			dt.overlay = overlay
Azilroka's avatar
Azilroka committed
492 493 494 495 496

			panel.dataPanels[i] = dt
		end
	end

497
	panel.ignoreBorderColors = not db.border or nil
Azilroka's avatar
Azilroka committed
498
	panel:SetTemplate(db.backdrop and (db.panelTransparency and 'Transparent' or 'Default') or 'NoBackdrop', true)
499

Simpy's avatar
Simpy committed
500
	--Show Border option
Simpy's avatar
Simpy committed
501 502 503
	if panel.iborder then panel.iborder:SetShown(not panel.ignoreBorderColors) end
	if panel.oborder then panel.oborder:SetShown(not panel.ignoreBorderColors) end
	if panel.ignoreBorderColors then panel:SetBackdropBorderColor(0,0,0,0) end
Azilroka's avatar
Azilroka committed
504

Simpy's avatar
Simpy committed
505 506
	--Restore Panels
	for i, dt in ipairs(panel.dataPanels) do
507
		dt:SetShown(i <= numPoints)
Simpy's avatar
Simpy committed
508
		dt:Size(width, height)
509
		dt:ClearAllPoints()
Simpy's avatar
Simpy committed
510
		dt:Point(DT:GetDataPanelPoint(panel, i, numPoints, vertical))
Simpy's avatar
Simpy committed
511
		dt:UnregisterAllEvents()
512
		dt:EnableMouseWheel(false)
Simpy's avatar
Simpy committed
513
		dt:SetScript('OnUpdate', nil)
Simpy's avatar
Simpy committed
514
		dt:SetScript('OnEvent', nil)
Simpy's avatar
Simpy committed
515
		dt:SetScript('OnClick', nil)
Simpy's avatar
Simpy committed
516 517 518 519 520
		dt:SetScript('OnEnter', DT.OnEnter)
		dt:SetScript('OnLeave', DT.OnLeave)
		wipe(dt.MouseEnters)
		wipe(dt.MouseLeaves)

Simpy's avatar
Simpy committed
521
		dt.overlay:Hide()
Simpy's avatar
<3 beep  
Simpy committed
522
		dt.pointIndex = i
Azilroka's avatar
Azilroka committed
523 524
		dt.parent = panel
		dt.parentName = panelName
Simpy's avatar
Simpy committed
525
		dt.battleStats = battlePanel
Azilroka's avatar
Azilroka committed
526
		dt.db = db
Simpy's avatar
boop <3  
Simpy committed
527

528 529
		E:StopFlash(dt)

530 531 532 533 534
		if dt.objectEvent and dt.objectEventFunc then
			E:UnregisterAllEventsForObject(dt.objectEvent, dt.objectEventFunc)
			dt.objectEvent, dt.objectEventFunc = nil, nil
		end

535
		dt.text:FontTemplate(font, fontSize, fontOutline)
536
		dt.text:SetJustifyH(db.textJustify or 'CENTER')
537
		dt.text:SetWordWrap(DT.db.wordWrap)
538 539
		dt.text:SetText()

540
		RerenderFont(dt.text) -- SetJustifyH wont update without a rerender?
Simpy's avatar
Simpy committed
541

Simpy's avatar
Simpy committed
542 543 544
		if battlePanel then
			dt:SetScript('OnClick', DT.ToggleBattleStats)
			tinsert(dt.MouseEnters, DT.HoverBattleStats)
Simpy's avatar
Simpy committed
545
		else
Simpy's avatar
Simpy committed
546
			local assigned = DT.RegisteredDataTexts[ DT.db.panels[panelName][i] ]
Simpy's avatar
Simpy committed
547
			DT.AssignedDatatexts[dt] = assigned
Simpy's avatar
Simpy committed
548
			if assigned then DT:AssignPanelToDataText(dt, assigned, ...) end
Simpy's avatar
Simpy committed
549 550 551 552
		end
	end
end

553
function DT:LoadDataTexts(...)
Simpy's avatar
Simpy committed
554
	local data = DT.LoadedInfo
Simpy's avatar
boop <3  
Simpy committed
555
	data.font, data.fontSize, data.fontOutline = LSM:Fetch('font', DT.db.font), DT.db.fontSize, DT.db.fontOutline
Simpy's avatar
Simpy committed
556
	data.inInstance, data.instanceType = IsInInstance()
Simpy's avatar
Simpy committed
557
	data.isInBattle = data.inInstance and (data.instanceType == 'pvp' or data.instanceType == 'arena')
Azilroka's avatar
Azilroka committed
558

Simpy's avatar
Simpy committed
559
	for panel, db in pairs(E.global.datatexts.customPanels) do
560
		DT:UpdatePanelAttributes(panel, db, true)
Azilroka's avatar
Azilroka committed
561 562
	end

563
	for panelName, panel in pairs(DT.RegisteredPanels) do
564 565
		local db = DT.db.panels[panelName]
		if db and db.enable then
Simpy's avatar
Simpy committed
566
			DT:UpdatePanelInfo(panelName, panel, ...)
567 568 569
		end
	end

Simpy's avatar
Simpy committed
570
	if DT.ShowingBattleStats then
Azilroka's avatar
Azilroka committed
571
		DT:UPDATE_BATTLEFIELD_SCORE()
572 573 574
	end
end

575 576 577 578 579 580
function DT:PanelSizeChanged()
	if not self.dataPanels then return end
	local db = self.db or P.datatexts.panels[self.name] and DT.db.panels[self.name]
	local width, height, vertical, numPoints = DT:GetTextAttributes(self, db)

	for i, dt in ipairs(self.dataPanels) do
Simpy's avatar
Simpy committed
581
		dt:Size(width, height)
582
		dt:ClearAllPoints()
Simpy's avatar
Simpy committed
583
		dt:Point(DT:GetDataPanelPoint(self, i, numPoints, vertical))
584 585 586
	end
end

587
function DT:UpdatePanelAttributes(name, db, fromLoad)
Simpy's avatar
Simpy committed
588
	local Panel = DT.PanelPool.InUse[name]
Simpy's avatar
Simpy committed
589
	DT.OnLeave(Panel)
590 591 592

	Panel.db = db
	Panel.name = name
Azilroka's avatar
Azilroka committed
593 594 595 596
	Panel.numPoints = db.numPoints
	Panel.xOff = db.tooltipXOffset
	Panel.yOff = db.tooltipYOffset
	Panel.anchor = db.tooltipAnchor
Azilroka's avatar
Azilroka committed
597
	Panel.vertical = db.growth == 'VERTICAL'
Simpy's avatar
Simpy committed
598
	Panel:Size(db.width, db.height)
599 600
	Panel:SetFrameStrata(db.frameStrata)
	Panel:SetFrameLevel(db.frameLevel)
Simpy's avatar
Simpy committed
601

Azilroka's avatar
Azilroka committed
602 603
	E:UIFrameFadeIn(Panel, 0.2, Panel:GetAlpha(), db.mouseover and 0 or 1)

604
	if not DT.db.panels[name] or type(DT.db.panels[name]) ~= 'table' then
605
		DT.db.panels[name] = { enable = false }
Azilroka's avatar
Azilroka committed
606 607
	end

608
	for i = 1, (E.global.datatexts.customPanels[name].numPoints or 1) do
Azilroka's avatar
Azilroka committed
609 610 611 612 613
		if not DT.db.panels[name][i] then
			DT.db.panels[name][i] = ''
		end
	end

Simpy's avatar
Simpy committed
614 615
	if DT.db.panels[name].enable then
		E:EnableMover(Panel.moverName)
Simpy's avatar
boop <3  
Simpy committed
616
		RegisterStateDriver(Panel, 'visibility', db.visibility)
617 618 619 620

		if not fromLoad then
			DT:UpdatePanelInfo(name, Panel)
		end
Simpy's avatar
Simpy committed
621 622 623 624 625
	else
		DT:EmptyPanel(Panel)
	end
end

Azilroka's avatar
P I M P  
Azilroka committed
626
function DT:GetMenuListCategory(category)
Simpy's avatar
boop <3  
Simpy committed
627
	for i, info in ipairs(HyperList) do
Azilroka's avatar
HyperDT  
Azilroka committed
628 629 630 631 632 633
		if info.text == category then
			return i
		end
	end
end

634 635
do
	local function menuSort(a, b)
636 637 638 639 640
		if a.order and b.order then
			return a.order < b.order
		end

		return a.text < b.text
641 642 643 644 645 646 647 648 649 650 651
	end

	function DT:SortMenuList(list)
		for _, menu in pairs(list) do
			if menu.menuList then
				DT:SortMenuList(menu.menuList)
			end
		end

		sort(list, menuSort)
	end
Azilroka's avatar
HyperDT  
Azilroka committed
652 653
end

Simpy's avatar
boop <3  
Simpy committed
654 655
function DT:HyperDT()
	if ActivateHyperMode then
Simpy's avatar
Simpy committed
656
		ActivateHyperMode = nil
Simpy's avatar
boop <3  
Simpy committed
657 658 659 660 661 662 663 664 665
		DT:LoadDataTexts()
	else
		ActivateHyperMode = true
		DT:EnableHyperMode()
	end
end

function DT:RegisterHyperDT()
	for name, info in pairs(DT.RegisteredDataTexts) do
Azilroka's avatar
P I M P  
Azilroka committed
666
		local category = DT:GetMenuListCategory(info.category or MISCELLANEOUS)
Simpy's avatar
boop <3  
Simpy committed
667 668
		if not category then
			category = #HyperList + 1
669
			tinsert(HyperList, { order = 0, text = info.category or MISCELLANEOUS, notCheckable = true, hasArrow = true, menuList = {} } )
Simpy's avatar
boop <3  
Simpy committed
670
		end
Simpy's avatar
<3 beep  
Simpy committed
671

672 673 674 675 676
		tinsert(HyperList[category].menuList, {
			text = info.localizedName or name,
			checked = function() return DT.EasyMenu.MenuGetItem(DT.SelectedDatatext, name) end,
			func = function() DT.EasyMenu.MenuSetItem(DT.SelectedDatatext, name) end
		})
Simpy's avatar
boop <3  
Simpy committed
677 678
	end

679 680 681 682 683
	tinsert(HyperList, {
		order = 100, text = L["NONE"],
		checked = function() return DT.EasyMenu.MenuGetItem(DT.SelectedDatatext, '') end,
		func = function() DT.EasyMenu.MenuSetItem(DT.SelectedDatatext, '') end
	})
Azilroka's avatar
Azilroka committed
684

685
	DT:SortMenuList(HyperList)
Simpy's avatar
<3 beep  
Simpy committed
686
	DT:RegisterEvent('MODIFIER_STATE_CHANGED', 'SingleHyperMode')
Simpy's avatar
boop <3  
Simpy committed
687 688
end

Azilroka's avatar
Azilroka committed
689 690
function DT:PopulateData()
	local Collapsed = {}
Simpy's avatar
Simpy committed
691
	local listSize, i = C_CurrencyInfo_GetCurrencyListSize(), 1
Azilroka's avatar
Azilroka committed
692

Simpy's avatar
Simpy committed
693
	local headerIndex
Azilroka's avatar
Azilroka committed
694
	while listSize >= i do
Simpy's avatar
Simpy committed
695 696
		local info = C_CurrencyInfo_GetCurrencyListInfo(i)
		if info.isHeader and not info.isHeaderExpanded then
Simpy's avatar
Simpy committed
697
			C_CurrencyInfo_ExpandCurrencyList(i, true)
Simpy's avatar
Simpy committed
698 699
			listSize = C_CurrencyInfo_GetCurrencyListSize()
			Collapsed[info.name] = true
Azilroka's avatar
Azilroka committed
700
		end
Azilroka's avatar
Azilroka committed
701 702 703 704
		if info.isHeader then
			G.datatexts.settings.Currencies.tooltipData[i] = { info.name, nil, nil, (info.name == expansion or info.name == MISCELLANEOUS) or strfind(info.name, LFG_TYPE_DUNGEON) }
			E.global.datatexts.settings.Currencies.tooltipData[i] = E.global.datatexts.settings.Currencies.tooltipData[i] or { info.name, nil, nil, G.datatexts.settings.Currencies.tooltipData[i][4] }
			E.global.datatexts.settings.Currencies.tooltipData[i][1] = info.name
Simpy's avatar
Simpy committed
705 706 707

			headerIndex = i
		end
Azilroka's avatar
Azilroka committed
708 709
		if not info.isHeader then
			local currencyLink = C_CurrencyInfo_GetCurrencyListLink(i)
Azilroka's avatar
Azilroka committed
710 711
			local currencyID = currencyLink and C_CurrencyInfo_GetCurrencyIDFromLink(currencyLink)
			if currencyID then
Azilroka's avatar
Azilroka committed
712 713 714 715
				DT.CurrencyList[tostring(currencyID)] = info.name
				G.datatexts.settings.Currencies.tooltipData[i] = { info.name, currencyID, headerIndex, G.datatexts.settings.Currencies.tooltipData[headerIndex][4] }
				E.global.datatexts.settings.Currencies.tooltipData[i] = E.global.datatexts.settings.Currencies.tooltipData[i] or { info.name, currencyID, headerIndex, G.datatexts.settings.Currencies.tooltipData[headerIndex][4] }
				E.global.datatexts.settings.Currencies.tooltipData[i][1] = info.name
Azilroka's avatar
Azilroka committed
716 717 718 719 720 721
			end
		end
		i = i + 1
	end

	for k = 1, listSize do
Simpy's avatar
Simpy committed
722
		local info = C_CurrencyInfo_GetCurrencyListInfo(k)
Simpy's avatar
Simpy committed
723 724 725
		if not info then
			break
		elseif info.isHeader and info.isHeaderExpanded and Collapsed[info.name] then
Simpy's avatar
Simpy committed
726
			C_CurrencyInfo_ExpandCurrencyList(k, false)
Azilroka's avatar
Azilroka committed
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
		end
	end

	wipe(Collapsed)

	for index = 1, GetNumSpecializations() do
		local id, name, _, icon, _, statID = GetSpecializationInfo(index)

		if id then
			DT.SPECIALIZATION_CACHE[index] = { id = id, name = name, icon = icon, statID = statID }
			DT.SPECIALIZATION_CACHE[id] = { name = name, icon = icon }
		end
	end
end

function DT:CURRENCY_DISPLAY_UPDATE(_, currencyType)
	if currencyType and not DT.CurrencyList[tostring(currencyType)] then
Simpy's avatar
Simpy committed
744
		local info = C_CurrencyInfo_GetCurrencyInfo(currencyType)
Simpy's avatar
stuff  
Simpy committed
745
		if info and info.name then
Simpy's avatar
Simpy committed
746 747
			DT.CurrencyList[tostring(currencyType)] = info.name
		end
Azilroka's avatar
Azilroka committed
748 749 750
	end
end

751 752 753 754
function DT:PLAYER_ENTERING_WORLD(_, initLogin)
	DT:LoadDataTexts()

	if initLogin then
755
		E:Delay(1, FixFonts, DT.FontStrings)
756 757 758
	end
end

Azilroka's avatar
HyperDT  
Azilroka committed
759 760 761 762
function DT:Initialize()
	DT.Initialized = true
	DT.db = E.db.datatexts

Azilroka's avatar
Azilroka committed
763 764 765 766 767 768 769 770 771 772
	DT.EasyMenu:SetClampedToScreen(true)
	DT.EasyMenu:EnableMouse(true)
	DT.EasyMenu.MenuSetItem = function(dt, value)
		DT.db.panels[dt.parentName][dt.pointIndex] = value
		DT:UpdatePanelInfo(dt.parentName, dt.parent)

		if ActivateHyperMode then
			DT:EnableHyperMode(dt.parent)
		end

Azilroka's avatar
P I M P  
Azilroka committed
773
		DT.SelectedDatatext = nil
Azilroka's avatar