PageRenderTime 267ms CodeModel.GetById 100ms app.highlight 67ms RepoModel.GetById 94ms app.codeStats 1ms

/Tukui/core/api.lua

http://github.com/Asphyxia/Tukui
Lua | 483 lines | 407 code | 64 blank | 12 comment | 81 complexity | 886ae5e2f215dd48af4fbd47c8b3995e MD5 | raw file
  1-- Tukui API, see DOCS/API.txt for more informations
  2
  3local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales
  4
  5local noop = T.dummy
  6local floor = math.floor
  7local class = T.myclass
  8local texture = C.media.blank
  9local backdropr, backdropg, backdropb, backdropa, borderr, borderg, borderb = 0, 0, 0, 1, 0, 0, 0
 10
 11-- pixel perfect script of custom ui Scale.
 12local mult = 768/string.match(GetCVar("gxResolution"), "%d+x(%d+)")/C["general"].uiscale
 13local Scale = function(x)
 14    return mult*math.floor(x/mult+.5)
 15end
 16
 17T.Scale = function(x) return Scale(x) end
 18T.mult = mult
 19
 20---------------------------------------------------
 21-- TEMPLATES
 22---------------------------------------------------
 23
 24local function GetTemplate(t)
 25	if t == "Tukui" then
 26		borderr, borderg, borderb = .6, .6, .6
 27		backdropr, backdropg, backdropb = .1, .1, .1
 28	elseif t == "ClassColor" then
 29		local c = T.oUF_colors.class[class]
 30		borderr, borderg, borderb = c[1], c[2], c[3]
 31		backdropr, backdropg, backdropb = unpack(C["media"].backdropcolor)
 32	elseif t == "Elv" then
 33		borderr, borderg, borderb = .3, .3, .3
 34		backdropr, backdropg, backdropb = .1, .1, .1	
 35	elseif t == "Duffed" then
 36		borderr, borderg, borderb = .2, .2, .2
 37		backdropr, backdropg, backdropb = .02, .02, .02
 38	elseif t == "Dajova" then
 39		borderr, borderg, borderb = .05, .05, .05
 40		backdropr, backdropg, backdropb = .1, .1, .1
 41	elseif t == "Eclipse" then
 42		borderr, borderg, borderb = .1, .1, .1
 43		backdropr, backdropg, backdropb = 0, 0, 0
 44	elseif t == "Hydra" then
 45		borderr, borderg, borderb = .2, .2, .2
 46		backdropr, backdropg, backdropb = .075, .075, .075
 47	elseif t == "ThickTransparent" then
 48		borderr, borderg, borderb = unpack(C["media"].bordercolor)
 49		backdropr, backdropg, backdropb = 0,0,0
 50	elseif t == "Thin" then
 51		borderr, borderg, borderb = 0,0,0
 52		backdropr, backdropg, backdropb = unpack(C["media"].backdropcolor)
 53	else
 54		borderr, borderg, borderb = unpack(C["media"].bordercolor)
 55		backdropr, backdropg, backdropb = unpack(C["media"].backdropcolor)
 56	end
 57end
 58
 59---------------------------------------------------
 60-- END OF TEMPLATES
 61---------------------------------------------------
 62
 63local function Size(frame, width, height)
 64	frame:SetSize(Scale(width), Scale(height or width))
 65end
 66
 67local function Width(frame, width)
 68	frame:SetWidth(Scale(width))
 69end
 70
 71local function Height(frame, height)
 72	frame:SetHeight(Scale(height))
 73end
 74
 75local function Point(obj, arg1, arg2, arg3, arg4, arg5)
 76	-- anyone has a more elegant way for this?
 77	if type(arg1)=="number" then arg1 = Scale(arg1) end
 78	if type(arg2)=="number" then arg2 = Scale(arg2) end
 79	if type(arg3)=="number" then arg3 = Scale(arg3) end
 80	if type(arg4)=="number" then arg4 = Scale(arg4) end
 81	if type(arg5)=="number" then arg5 = Scale(arg5) end
 82
 83	obj:SetPoint(arg1, arg2, arg3, arg4, arg5)
 84end
 85
 86local function CreateBackdrop(f, t, tex)
 87	if not t then t = "Default" end
 88
 89	local b = CreateFrame("Frame", nil, f)
 90	b:Point("TOPLEFT", -2, 2)
 91	b:Point("BOTTOMRIGHT", 2, -2)
 92	b:SetTemplate(t, tex)
 93
 94	if f:GetFrameLevel() - 1 >= 0 then
 95		b:SetFrameLevel(f:GetFrameLevel() - 1)
 96	else
 97		b:SetFrameLevel(0)
 98	end
 99
100	f.backdrop = b
101end
102
103local function SetTemplate(f, t, tex)
104	if tex then texture = C.media.normTex else texture = C.media.blank end
105	
106	GetTemplate(t)
107	
108	f:SetBackdrop({
109	  bgFile = texture, 
110	  edgeFile = C.media.blank, 
111	  tile = false, tileSize = 0, edgeSize = mult, 
112	  insets = { left = -mult, right = -mult, top = -mult, bottom = -mult}
113	})
114		
115	if t == "Thin" then
116		f:SetBackdrop({
117			bgFile = texture, 
118			edgeFile = C.media.blank, 
119			tile = false, tileSize = 0, edgeSize = mult, 
120			insets = { left = 0, right = 0, top = 0, bottom = 0 }
121		})
122	else
123		f:SetBackdrop({
124			bgFile = texture, 
125			edgeFile = C.media.blank, 
126			tile = false, tileSize = 0, edgeSize = mult, 
127			insets = { left = -mult, right = -mult, top = -mult, bottom = -mult }
128		})
129	end
130	
131	if t == "ThickTransparent" then
132		outerBorder(f)
133		innerBorder(f)
134		backdropa = 0.8
135	elseif t == "Transparent" then
136		backdropa = 0.7
137	elseif t == "Invisible" then
138		backdropa = 0
139		bordera = 0
140	elseif t == "ThickBorder" then
141		outerBorder(f)
142		innerBorder(f)
143		bordera = 1
144		backdropa = 1
145	else
146		bordera = 1
147		backdropa = 1
148	end
149	
150	f:SetBackdropColor(backdropr, backdropg, backdropb, backdropa)
151	f:SetBackdropBorderColor(borderr, borderg, borderb, bordera)
152	f.bg = f
153end
154
155local function CreatePanel(f, t, w, h, a1, p, a2, x, y, text)
156	GetTemplate(t)
157	
158	if t == "Transparent" then
159		f:CreateBorder(true, true)
160		backdropa = .7
161	else 
162		backdropa = 1
163	end
164	
165	local sh = Scale(h)
166	local sw = Scale(w)
167	f:SetFrameLevel(1)
168	f:SetHeight(sh)
169	f:SetWidth(sw)
170	f:SetFrameStrata("BACKGROUND")
171	f:SetPoint(a1, p, a2, Scale(x), Scale(y))
172	f:SetBackdrop({
173	  bgFile = C["media"].normTex, 
174	  edgeFile = C["media"].blank, 
175	  tile = false, tileSize = 0, edgeSize = mult, 
176	  insets = { left = -mult, right = -mult, top = -mult, bottom = -mult}
177	})
178	
179	f:SetBackdropColor(backdropr, backdropg, backdropb, backdropa)
180	f:SetBackdropBorderColor(borderr, borderg, borderb)
181	
182	if t == "Transparent" then
183		f:CreateShadow()
184	end
185	if text then
186		if f.text then return end
187		local text = T.SetFontString(f, C.media.pixelfont, 12, "MONOCHROMEOUTLINE")
188		text:Point("CENTER", f, 1, 1)
189		text:SetJustifyH("CENTER")
190		f.text = text
191	end
192end
193
194local function CreateShadow(f, t)
195	if f.shadow then return end -- we seriously don't want to create shadow 2 times in a row on the same frame.
196	
197	borderr, borderg, borderb = 0, 0, 0
198	backdropr, backdropg, backdropb = 0, 0, 0
199	
200	if t == "ClassColor" then
201		local c = T.oUF_colors.class[class]
202		borderr, borderg, borderb = c[1], c[2], c[3]
203		backdropr, backdropg, backdropb = unpack(C["media"].backdropcolor)
204	end
205	
206	local shadow = CreateFrame("Frame", nil, f)
207	shadow:SetFrameLevel(1)
208	shadow:SetFrameStrata(f:GetFrameStrata())
209	shadow:Point("TOPLEFT", -3, 3)
210	shadow:Point("BOTTOMLEFT", -3, -3)
211	shadow:Point("TOPRIGHT", 3, 3)
212	shadow:Point("BOTTOMRIGHT", 3, -3)
213	shadow:SetBackdrop( { 
214		edgeFile = C["media"].glowTex, edgeSize = T.Scale(3),
215		insets = {left = T.Scale(5), right = T.Scale(5), top = T.Scale(5), bottom = T.Scale(5)},
216	})
217	shadow:SetBackdropColor(backdropr, backdropg, backdropb, 0)
218	shadow:SetBackdropBorderColor(borderr, borderg, borderb, 0.8)
219	f.shadow = shadow
220end
221
222-- Credits to Eclipse
223local function CreateOverlay(f)
224	if f.overlay then return end
225	
226	local overlay = f:CreateTexture(f:GetName() and f:GetName().."Overlay" or nil, "BORDER", f)
227	overlay:ClearAllPoints()
228	overlay:Point("TOPLEFT", 2, -2)
229	overlay:Point("BOTTOMRIGHT", -2, 2)
230	overlay:SetTexture(C.media.normTex)
231	overlay:SetVertexColor(.05, .05, .05)
232	f.overlay = overlay
233end
234
235local function Kill(object)
236	if object.UnregisterAllEvents then
237		object:UnregisterAllEvents()
238	end
239	object.Show = noop
240	object:Hide()
241end
242
243local function StripTextures(object, kill)
244	for i=1, object:GetNumRegions() do
245		local region = select(i, object:GetRegions())
246		if region:GetObjectType() == "Texture" then
247			if kill then
248				region:Kill()
249			else
250				region:SetTexture(nil)
251			end
252		end
253	end		
254end
255
256-- styleButton function authors are Chiril & Karudon.
257local function StyleButton(b, c) 
258    local name = b:GetName()
259 
260    local button          = _G[name]
261    local icon            = _G[name.."Icon"]
262    local count           = _G[name.."Count"]
263    local border          = _G[name.."Border"]
264    local hotkey          = _G[name.."HotKey"]
265    local cooldown        = _G[name.."Cooldown"]
266    local nametext        = _G[name.."Name"]
267    local flash           = _G[name.."Flash"]
268    local normaltexture   = _G[name.."NormalTexture"]
269	local icontexture     = _G[name.."IconTexture"]
270	
271	local hover = b:CreateTexture("frame", nil, self) -- hover
272	hover:SetTexture(1,1,1, .03)
273	hover:SetHeight(button:GetHeight())
274	hover:SetWidth(button:GetWidth())
275	hover:Point("TOPLEFT",button,2,-2)
276	hover:Point("BOTTOMRIGHT",button,-2,2)
277	button:SetHighlightTexture(hover)
278
279	local pushed = b:CreateTexture("frame", nil, self) -- pushed
280	pushed:SetTexture(1,1,1,0.3)
281	pushed:SetHeight(button:GetHeight())
282	pushed:SetWidth(button:GetWidth())
283	pushed:Point("TOPLEFT",button,2,-2)
284	pushed:Point("BOTTOMRIGHT",button,-2,2)
285	button:SetPushedTexture(pushed)
286 
287 
288if c then
289		local checked = b:CreateTexture("frame", nil, self) -- checked
290		checked:SetTexture(1,1,1,0.4)
291		checked:SetHeight(button:GetHeight())
292		checked:SetWidth(button:GetWidth())
293		checked:Point("TOPLEFT",button,2,-2)
294		checked:Point("BOTTOMRIGHT",button,-2,2)
295		button:SetCheckedTexture(checked)
296	end
297end
298
299local function FontString(parent, name, fontName, fontHeight, fontStyle)
300	local fs = parent:CreateFontString(nil, "OVERLAY")
301	fs:SetJustifyH("LEFT")
302	fs:SetShadowOffset(0,0)
303	fs:SetFont(fontName, fontHeight, fontStyle)
304	
305	if not name then
306		parent.text = fs
307	else
308		parent[name] = fs
309	end
310	
311	return fs
312end
313
314local function HighlightTarget(self, event, unit)
315	if self.unit == "target" then return end
316	if UnitIsUnit('target', self.unit) then
317		self.HighlightTarget:Show()
318	else
319		self.HighlightTarget:Hide()
320	end
321end
322
323local function HighlightUnit(f, r, g, b)
324	if f.HighlightTarget then return end
325	local glowBorder = {edgeFile = C["media"].blank, edgeSize = 1}
326	f.HighlightTarget = CreateFrame("Frame", nil, f)
327	f.HighlightTarget:Point("TOPLEFT", f, "TOPLEFT", -2, 2)
328	f.HighlightTarget:Point("BOTTOMRIGHT", f, "BOTTOMRIGHT", 2, -2)
329	f.HighlightTarget:SetBackdrop(glowBorder)
330	f.HighlightTarget:SetFrameLevel(f:GetFrameLevel() + 1)
331	f.HighlightTarget:SetBackdropBorderColor(r,g,b,1)
332	f.HighlightTarget:Hide()
333	f:RegisterEvent("PLAYER_TARGET_CHANGED", HighlightTarget)
334end
335
336local function CreateBorder(f, i, o)
337	if i then
338		if f.iborder then return end
339		local border = CreateFrame("Frame", f:GetName() and f:GetName() .. "InnerBorder" or nil, f)
340		border:Point("TOPLEFT", mult, -mult)
341		border:Point("BOTTOMRIGHT", -mult, mult)
342		border:SetBackdrop({
343			edgeFile = C["media"].blank, 
344			edgeSize = mult, 
345			insets = { left = mult, right = mult, top = mult, bottom = mult }
346		})
347		border:SetBackdropBorderColor(0, 0, 0)
348		f.iborder = border
349	end
350
351	if o then
352		if f.oborder then return end
353		local border = CreateFrame("Frame", f:GetName() and f:GetName() .. "OuterBorder" or nil, f)
354		border:Point("TOPLEFT", -mult, mult)
355		border:Point("BOTTOMRIGHT", mult, -mult)
356		border:SetFrameLevel(f:GetFrameLevel() + 1)
357		border:SetBackdrop({
358			edgeFile = C["media"].blank, 
359			edgeSize = mult, 
360			insets = { left = mult, right = mult, top = mult, bottom = mult }
361		})
362		border:SetBackdropBorderColor(0,0,0)
363		f.oborder = border
364	end
365end
366
367-- Animation functions
368local function Animate(self, x, y, duration)
369	self.anim = self:CreateAnimationGroup("Move_In")
370	self.anim.in1 = self.anim:CreateAnimation("Translation")
371	self.anim.in1:SetDuration(0)
372	self.anim.in1:SetOrder(1)
373	self.anim.in2 = self.anim:CreateAnimation("Translation")
374	self.anim.in2:SetDuration(duration)
375	self.anim.in2:SetOrder(2)
376	self.anim.in2:SetSmoothing("OUT")
377	self.anim.out1 = self:CreateAnimationGroup("Move_Out")
378	self.anim.out2 = self.anim.out1:CreateAnimation("Translation")
379	self.anim.out2:SetDuration(duration)
380	self.anim.out2:SetOrder(1)
381	self.anim.out2:SetSmoothing("IN")
382	self.anim.in1:SetOffset(Scale(x), Scale(y))
383	self.anim.in2:SetOffset(Scale(-x), Scale(-y))
384	self.anim.out2:SetOffset(Scale(x), Scale(y))
385	self.anim.out1:SetScript("OnFinished", function() self:Hide() end)
386end
387
388local function SlideIn(self)
389	if not self.anim then
390		Animate(self)
391	end
392
393	self.anim.out1:Stop()
394	self:Show()
395	self.anim:Play()
396end
397
398local function SlideOut(self)
399	if self.anim then
400		self.anim:Finish()
401	end
402
403	self.anim:Stop()
404	self.anim.out1:Play()
405end
406
407local function FadeIn(f)
408	UIFrameFadeIn(f, .4, f:GetAlpha(), 1)
409end
410	
411local function FadeOut(f)
412	UIFrameFadeOut(f, .8, f:GetAlpha(), 0)
413end
414
415T.SetUpAnimGroup = function(self)
416	self.anim = self:CreateAnimationGroup("Flash")
417	self.anim.fadein = self.anim:CreateAnimation("ALPHA", "FadeIn")
418	self.anim.fadein:SetChange(1)
419	self.anim.fadein:SetOrder(2)
420
421	self.anim.fadeout = self.anim:CreateAnimation("ALPHA", "FadeOut")
422	self.anim.fadeout:SetChange(-1)
423	self.anim.fadeout:SetOrder(1)
424end
425
426T.Flash = function(self, duration)
427	if not self.anim then
428		T.SetUpAnimGroup(self)
429	end
430
431	self.anim.fadein:SetDuration(duration)
432	self.anim.fadeout:SetDuration(duration)
433	self.anim:Play()
434end
435
436T.StopFlash = function(self)
437	if self.anim then
438		self.anim:Finish()
439	end
440end
441
442local function addapi(object)
443	local mt = getmetatable(object).__index
444	if not object.Size then mt.Size = Size end
445	if not object.Point then mt.Point = Point end
446	if not object.ApplyBorder then mt.ApplyBorder = ApplyBorder end
447	if not object.SetTemplate then mt.SetTemplate = SetTemplate end
448	if not object.CreateBackdrop then mt.CreateBackdrop = CreateBackdrop end
449	if not object.StripTextures then mt.StripTextures = StripTextures end
450	if not object.CreatePanel then mt.CreatePanel = CreatePanel end
451	if not object.CreateShadow then mt.CreateShadow = CreateShadow end
452	if not object.Kill then mt.Kill = Kill end
453	if not object.StyleButton then mt.StyleButton = StyleButton end
454	if not object.Width then mt.Width = Width end
455	if not object.Height then mt.Height = Height end
456	if not object.FontString then mt.FontString = FontString end
457	if not object.CreateOverlay then mt.CreateOverlay = CreateOverlay end
458	if not object.HighlightUnit then mt.HighlightUnit = HighlightUnit end
459	if not object.CreateBorder then mt.CreateBorder = CreateBorder end
460	if not object.Animate then mt.Animate = Animate end
461	if not object.SlideIn then mt.SlideIn = SlideIn end
462	if not object.SlideOut then mt.SlideOut = SlideOut end
463	if not object.FadeIn then mt.FadeIn = FadeIn end
464	if not object.FadeOut then mt.FadeOut = FadeOut end
465	if not object.Flash then mt.Flash = Flash end
466	if not object.StopFlash then mt.StopFlash = StopFlash end
467end
468
469local handled = {["Frame"] = true}
470local object = CreateFrame("Frame")
471addapi(object)
472addapi(object:CreateTexture())
473addapi(object:CreateFontString())
474
475object = EnumerateFrames()
476while object do
477	if not handled[object:GetObjectType()] then
478		addapi(object)
479		handled[object:GetObjectType()] = true
480	end
481
482	object = EnumerateFrames(object)
483end