-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTextures.lua
More file actions
604 lines (511 loc) · 18 KB
/
Textures.lua
File metadata and controls
604 lines (511 loc) · 18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
-- ChatBar: Skin-Based Texture Manager
-- Handles loading skins, creating button/bar textures, and live skin switching
local addonName, ns = ...
-- Create Textures module
local Textures = {}
ns.Textures = Textures
-- Skin system state
Textures.currentSkin = nil
Textures.skinPath = nil
Textures.availableSkins = {}
-- Constants
local ADDON_PATH = "Interface\\AddOns\\ChatBar\\Skins\\"
local BLIZZARD_CIRCLE_MASK = "Interface\\CharacterFrame\\TempPortraitAlphaMask"
--[[
Skin Loading System
]]
-- Get list of available skins from the registry
function Textures:GetAvailableSkins()
local skins = {}
if ns.SkinRegistry then
for skinName, skinData in pairs(ns.SkinRegistry) do
table.insert(skins, {
id = skinName,
name = skinData.name or skinName,
description = skinData.description or "",
author = skinData.author or "Unknown",
})
end
end
-- Sort alphabetically
table.sort(skins, function(a, b)
return a.name < b.name
end)
self.availableSkins = skins
return skins
end
-- Load a skin by name
function Textures:LoadSkin(skinName)
if not skinName then
skinName = "Default"
end
-- Get skin data from registry
local skinData = ns.SkinRegistry and ns.SkinRegistry[skinName]
if not skinData then
-- Fallback to Default if requested skin not found
skinData = ns.SkinRegistry and ns.SkinRegistry["Default"]
skinName = "Default"
if not skinData then
-- Create minimal fallback if no skins registered
skinData = self:CreateFallbackSkin()
end
end
self.currentSkin = skinData
self.skinPath = ADDON_PATH .. skinName .. "\\"
return skinData
end
-- Create fallback skin if none registered
function Textures:CreateFallbackSkin()
return {
name = "Fallback",
author = "ChatBar",
description = "Fallback color-based skin",
shape = "square",
barOpacity = 0.9,
barPadding = 6,
buttonSpacing = 1,
textures = {},
colors = {
background = { r = 0.16, g = 0.16, b = 0.16, a = 0.9 },
border = { r = 0.33, g = 0.33, b = 0.33, a = 1.0 },
highlight = { r = 1.0, g = 1.0, b = 1.0, a = 0.3 },
pushed = { r = 0.1, g = 0.1, b = 0.1, a = 0.9 },
glow = { r = 1.0, g = 0.8, b = 0.0, a = 0.8 },
},
textColor = { r = 1.0, g = 1.0, b = 1.0, a = 1.0 },
textShadow = true,
}
end
-- Get current skin data
function Textures:GetCurrentSkin()
if not self.currentSkin then
self:LoadSkin("Default")
end
return self.currentSkin
end
-- Get texture path for current skin
function Textures:GetTexturePath(textureName)
if not self.skinPath then
self:LoadSkin("Default")
end
return self.skinPath .. textureName
end
--[[
Button Texture Creation
]]
-- Create all texture layers for a button
function Textures:CreateButtonLayers(button, buttonSize)
local skin = self:GetCurrentSkin()
local size = buttonSize or 18
local glowSize = size * 2 -- Glow is larger for soft edges
-- Store size reference
button.textureSize = size
-- Layer order (bottom to top):
-- BACKGROUND: bgTexture (channel-colored fill)
-- BORDER: borderTexture (frame)
-- ARTWORK: centerTexture (optional center detail)
-- OVERLAY: glowTexture (notification flash, hidden by default)
-- HIGHLIGHT: highlightTexture (hover effect)
-- Background texture (main fill, tinted with channel color)
local bgTexture = button:CreateTexture(nil, "BACKGROUND", nil, -8)
bgTexture:SetSize(size, size)
bgTexture:SetPoint("CENTER")
bgTexture:SetSnapToPixelGrid(true)
bgTexture:SetTexelSnappingBias(0)
button.bgTexture = bgTexture
-- Center texture (for additional detail/overlay)
local centerTexture = button:CreateTexture(nil, "ARTWORK", nil, 0)
centerTexture:SetSize(size, size)
centerTexture:SetPoint("CENTER")
centerTexture:SetBlendMode("BLEND")
centerTexture:SetSnapToPixelGrid(true)
centerTexture:SetTexelSnappingBias(0)
button.centerTexture = centerTexture
-- Border texture
local borderTexture = button:CreateTexture(nil, "BORDER", nil, 0)
borderTexture:SetSize(size, size)
borderTexture:SetPoint("CENTER")
borderTexture:SetSnapToPixelGrid(true)
borderTexture:SetTexelSnappingBias(0)
button.borderTexture = borderTexture
-- Highlight texture (hover effect)
local highlightTexture = button:CreateTexture(nil, "HIGHLIGHT", nil, 0)
highlightTexture:SetSize(size, size)
highlightTexture:SetPoint("CENTER")
highlightTexture:SetBlendMode("ADD")
highlightTexture:SetSnapToPixelGrid(true)
highlightTexture:SetTexelSnappingBias(0)
button.highlightTexture = highlightTexture
-- Pushed texture (click effect)
local pushedTexture = button:CreateTexture(nil, "BACKGROUND", nil, -7)
pushedTexture:SetSize(size, size)
pushedTexture:SetPoint("CENTER")
pushedTexture:SetSnapToPixelGrid(true)
pushedTexture:SetTexelSnappingBias(0)
pushedTexture:Hide()
button.pushedTexture = pushedTexture
-- Glow texture (notification flash, larger for soft edges)
local glowTexture = button:CreateTexture(nil, "OVERLAY", nil, 7)
glowTexture:SetSize(glowSize, glowSize)
glowTexture:SetPoint("CENTER")
glowTexture:SetBlendMode("ADD")
glowTexture:Hide()
button.glowTexture = glowTexture
-- Apply mask if round shape
if skin.shape == "round" then
self:ApplyCircleMask(button)
end
-- Apply textures from skin
self:ApplyButtonTextures(button)
-- Setup button scripts for pushed state
self:SetupButtonStateScripts(button)
return button
end
-- Apply circle mask to button textures
function Textures:ApplyCircleMask(button)
local size = button.textureSize or 18
-- Create mask texture
local mask = button:CreateMaskTexture()
mask:SetSize(size, size)
mask:SetPoint("CENTER")
mask:SetTexture(BLIZZARD_CIRCLE_MASK, "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE")
button.maskTexture = mask
-- Apply mask to relevant textures
if button.bgTexture then
button.bgTexture:AddMaskTexture(mask)
end
if button.centerTexture then
button.centerTexture:AddMaskTexture(mask)
end
if button.borderTexture then
button.borderTexture:AddMaskTexture(mask)
end
if button.highlightTexture then
button.highlightTexture:AddMaskTexture(mask)
end
if button.pushedTexture then
button.pushedTexture:AddMaskTexture(mask)
end
-- Note: glow intentionally not masked for soft edge effect
end
-- Apply textures from current skin to button
function Textures:ApplyButtonTextures(button)
local skin = self:GetCurrentSkin()
local colors = skin.colors or {}
-- Try to load texture files, fallback to colors
local bgPath = self:GetTexturePath(skin.textures.button_bg or "button_bg")
local borderPath = self:GetTexturePath(skin.textures.button_border or "button_border")
local highlightPath = self:GetTexturePath(skin.textures.button_highlight or "button_highlight")
local pushedPath = self:GetTexturePath(skin.textures.button_pushed or "button_pushed")
local glowPath = self:GetTexturePath(skin.textures.button_glow or "button_glow")
-- Apply background (will be tinted with channel color later)
if button.bgTexture then
button.bgTexture:SetTexture(bgPath)
-- Fallback to white color if texture doesn't exist (white base allows proper vertex color tinting)
if not button.bgTexture:GetTexture() then
local c = colors.background or { r = 1.0, g = 1.0, b = 1.0, a = 0.9 }
button.bgTexture:SetColorTexture(1.0, 1.0, 1.0, c.a)
button.bgTexture.isColorFallback = true
else
button.bgTexture.isColorFallback = false
end
end
-- Apply border (check skin.hideButtonBorder)
if button.borderTexture then
if skin.hideButtonBorder then
button.borderTexture:Hide()
else
button.borderTexture:Show()
button.borderTexture:SetTexture(borderPath)
if not button.borderTexture:GetTexture() then
local c = colors.border or { r = 0.4, g = 0.4, b = 0.4, a = 1.0 }
button.borderTexture:SetColorTexture(c.r, c.g, c.b, c.a)
end
end
end
-- Apply highlight
if button.highlightTexture then
button.highlightTexture:SetTexture(highlightPath)
if not button.highlightTexture:GetTexture() then
local c = colors.highlight or { r = 1.0, g = 1.0, b = 1.0, a = 0.3 }
button.highlightTexture:SetColorTexture(c.r, c.g, c.b, c.a)
end
end
-- Apply pushed
if button.pushedTexture then
button.pushedTexture:SetTexture(pushedPath)
if not button.pushedTexture:GetTexture() then
local c = colors.pushed or { r = 0.1, g = 0.1, b = 0.1, a = 0.9 }
button.pushedTexture:SetColorTexture(c.r, c.g, c.b, c.a)
end
end
-- Apply glow
if button.glowTexture then
button.glowTexture:SetTexture(glowPath)
if not button.glowTexture:GetTexture() then
local c = colors.glow or { r = 1.0, g = 0.8, b = 0.0, a = 0.8 }
button.glowTexture:SetColorTexture(c.r, c.g, c.b, c.a)
end
end
-- Hide center texture by default (used for optional overlays)
if button.centerTexture then
button.centerTexture:Hide()
end
end
-- Setup button state scripts for pushed appearance
function Textures:SetupButtonStateScripts(button)
button:HookScript("OnMouseDown", function(self)
if self.pushedTexture then
self.pushedTexture:Show()
end
if self.bgTexture then
self.bgTexture:SetAlpha(0.7)
end
end)
button:HookScript("OnMouseUp", function(self)
if self.pushedTexture then
self.pushedTexture:Hide()
end
if self.bgTexture then
self.bgTexture:SetAlpha(1.0)
end
end)
end
-- Apply channel color to button textures
function Textures:ApplyChannelColor(button, chatColor)
if not chatColor then return end
local r, g, b = chatColor.r, chatColor.g, chatColor.b
-- Store for refresh
button.channelColor = chatColor
-- Tint background with channel color
if button.bgTexture then
button.bgTexture:SetVertexColor(r, g, b)
end
-- Tint glow with channel color (matches channel for notification)
if button.glowTexture then
button.glowTexture:SetVertexColor(r, g, b)
end
-- Optional: tint highlight slightly with channel color
if button.highlightTexture then
-- Blend channel color with white for subtle tint
button.highlightTexture:SetVertexColor(
0.7 + r * 0.3,
0.7 + g * 0.3,
0.7 + b * 0.3
)
end
end
-- Refresh button textures (for skin hot-swap)
function Textures:RefreshButtonTextures(button)
if not button then return end
local skin = self:GetCurrentSkin()
-- Update texture paths
self:ApplyButtonTextures(button)
-- Reapply mask if shape changed
if button.maskTexture then
-- Remove old mask
if button.bgTexture then
button.bgTexture:RemoveMaskTexture(button.maskTexture)
end
if button.centerTexture then
button.centerTexture:RemoveMaskTexture(button.maskTexture)
end
if button.borderTexture then
button.borderTexture:RemoveMaskTexture(button.maskTexture)
end
if button.highlightTexture then
button.highlightTexture:RemoveMaskTexture(button.maskTexture)
end
if button.pushedTexture then
button.pushedTexture:RemoveMaskTexture(button.maskTexture)
end
button.maskTexture = nil
end
-- Reapply mask if round shape
if skin.shape == "round" then
self:ApplyCircleMask(button)
end
-- Reapply channel color if stored
if button.channelColor then
self:ApplyChannelColor(button, button.channelColor)
end
end
-- Resize button textures
function Textures:ResizeButtonTextures(button, newSize)
if not button then return end
local glowSize = newSize * 2
button.textureSize = newSize
if button.bgTexture then
button.bgTexture:SetSize(newSize, newSize)
end
if button.centerTexture then
button.centerTexture:SetSize(newSize, newSize)
end
if button.borderTexture then
button.borderTexture:SetSize(newSize, newSize)
end
if button.highlightTexture then
button.highlightTexture:SetSize(newSize, newSize)
end
if button.pushedTexture then
button.pushedTexture:SetSize(newSize, newSize)
end
if button.glowTexture then
button.glowTexture:SetSize(glowSize, glowSize)
end
if button.maskTexture then
button.maskTexture:SetSize(newSize, newSize)
end
end
-- Clean up button textures
function Textures:CleanupButton(button)
if not button then return end
-- Stop and clear flash animation first (it's attached to glowTexture)
if button.flashAnim then
button.flashAnim:Stop()
button.flashAnim = nil
end
button.isFlashing = false
local texturesToClean = {
"bgTexture", "centerTexture", "borderTexture",
"highlightTexture", "pushedTexture", "glowTexture", "maskTexture"
}
for _, texName in ipairs(texturesToClean) do
if button[texName] then
button[texName]:Hide()
button[texName]:ClearAllPoints()
button[texName] = nil
end
end
-- Clear channel color reference
button.channelColor = nil
-- Clear legacy texture references
button.normalTextureBg = nil
button.pushedTextureBg = nil
button.highlightTextureBg = nil
button.borderTextures = nil
end
--[[
Bar Texture Creation
]]
-- Create bar textures
function Textures:CreateBarTextures(bar)
-- Background texture (stretched to fill bar)
local bgTexture = bar:CreateTexture(nil, "BACKGROUND", nil, -8)
bgTexture:SetAllPoints()
bar.bgTexture = bgTexture
-- Border texture (stretched to fill bar)
local borderTexture = bar:CreateTexture(nil, "BORDER", nil, 0)
borderTexture:SetAllPoints()
bar.borderTexture = borderTexture
-- Apply textures
self:ApplyBarTextures(bar)
return bar
end
-- Apply bar textures from current skin
function Textures:ApplyBarTextures(bar)
local skin = self:GetCurrentSkin()
local colors = skin.colors or {}
-- Check if skin wants to hide the bar entirely (buttons only mode)
if skin.showBar == false then
if bar.bgTexture then
bar.bgTexture:Hide()
end
if bar.borderTexture then
bar.borderTexture:Hide()
end
return
end
local bgPath = self:GetTexturePath(skin.textures.bar_bg or "bar_bg")
local borderPath = self:GetTexturePath(skin.textures.bar_border or "bar_border")
-- Apply background
if bar.bgTexture then
bar.bgTexture:Show()
bar.bgTexture:SetTexture(bgPath)
if not bar.bgTexture:GetTexture() then
local c = colors.background or { r = 1.0, g = 1.0, b = 1.0, a = 0.9 }
bar.bgTexture:SetColorTexture(1.0, 1.0, 1.0, c.a)
end
bar.bgTexture:SetAlpha(skin.barOpacity or 0.9)
end
-- Apply border
if bar.borderTexture then
bar.borderTexture:Show()
bar.borderTexture:SetTexture(borderPath)
if not bar.borderTexture:GetTexture() then
local c = colors.border or { r = 0.3, g = 0.3, b = 0.3, a = 1.0 }
bar.borderTexture:SetColorTexture(c.r, c.g, c.b, c.a)
end
end
end
-- Refresh bar textures (for skin hot-swap)
function Textures:RefreshBarTextures(bar)
if not bar then return end
self:ApplyBarTextures(bar)
end
--[[
Flash Animation System
]]
-- Create flash animation group for a button
function Textures:CreateFlashAnimation(button)
if not button.glowTexture then return end
local glow = button.glowTexture
local ag = glow:CreateAnimationGroup()
ag:SetLooping("REPEAT")
-- Phase 1: Fade in + Scale up
local fadeIn = ag:CreateAnimation("Alpha")
fadeIn:SetFromAlpha(0)
fadeIn:SetToAlpha(0.8)
fadeIn:SetDuration(0.4)
fadeIn:SetSmoothing("IN_OUT")
fadeIn:SetOrder(1)
local scaleUp = ag:CreateAnimation("Scale")
scaleUp:SetScaleFrom(0.9, 0.9)
scaleUp:SetScaleTo(1.15, 1.15)
scaleUp:SetDuration(0.4)
scaleUp:SetSmoothing("IN_OUT")
scaleUp:SetOrder(1)
scaleUp:SetOrigin("CENTER", 0, 0)
-- Phase 2: Fade out + Scale down
local fadeOut = ag:CreateAnimation("Alpha")
fadeOut:SetFromAlpha(0.8)
fadeOut:SetToAlpha(0)
fadeOut:SetDuration(0.4)
fadeOut:SetSmoothing("IN_OUT")
fadeOut:SetOrder(2)
local scaleDown = ag:CreateAnimation("Scale")
scaleDown:SetScaleFrom(1.15, 1.15)
scaleDown:SetScaleTo(0.9, 0.9)
scaleDown:SetDuration(0.4)
scaleDown:SetSmoothing("IN_OUT")
scaleDown:SetOrder(2)
scaleDown:SetOrigin("CENTER", 0, 0)
button.flashAnim = ag
return ag
end
-- Start flash animation
function Textures:StartFlash(button)
if not button then return end
-- Create animation if doesn't exist
if not button.flashAnim then
self:CreateFlashAnimation(button)
end
if button.glowTexture and button.flashAnim then
button.glowTexture:SetAlpha(0)
button.glowTexture:Show()
button.flashAnim:Play()
button.isFlashing = true
end
end
-- Stop flash animation
function Textures:StopFlash(button)
if not button then return end
if button.flashAnim then
button.flashAnim:Stop()
end
if button.glowTexture then
button.glowTexture:Hide()
button.glowTexture:SetAlpha(0)
end
button.isFlashing = false
end