Skip to content

Commit 0f77fd4

Browse files
committed
Merge commit 'c6c684d9cac889b4d4391a537df9a194c76088a0' into test/krathe-stack
2 parents bd8c15a + c6c684d commit 0f77fd4

8 files changed

Lines changed: 86 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* (Text Designer) Text element edits now update **test-mode frames** live, not just real units. (by Krathe)
4242
* (Designers) The Aura/Text Designer **preview now rebuilds to the frame size of the auto layout being edited**, instead of staying stuck at a previous layout's dimensions. (by Krathe)
4343
* (Designers) Text Designer edits (and Aura Designer changes) no longer **stop updating on test-mode frames after switching between auto layouts** — applying a layout's overrides kept the designer's table/preview bindings valid instead of orphaning them. (by Krathe)
44+
* (Frames) Missing textures now fall back to a bundled default instead of rendering black. If a profile you import references a custom or shared-media texture you don't have installed (or the addon that provided it was removed), the affected health bar, background or other bar now uses DandersFrames' default texture and shows a one-time notice — rather than a black/blank bar. (Requires WoW 12.0.7; on earlier versions there is no change.) (by Krathe)
4445

4546
## [4.4.0]
4647

Core.lua

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,73 @@ function DF:LightweightUpdateBackgroundAlpha()
432432
IterateFramesInMode(mode, UpdateBG)
433433
end
434434

435+
-- ============================================================
436+
-- SAFE TEXTURE SETTERS — graceful missing-texture fallback
437+
-- A configured texture can be missing when a profile imported from another user
438+
-- references a 3rd-party/SharedMedia texture this client doesn't have (or the
439+
-- providing addon was removed) — leaving a black/blank bar. C_UIFileAsset
440+
-- (NEW in WoW 12.0.7) — IsKnownFile(asset) reports whether a path is known to
441+
-- the client (shipped OR a known loose addon file); when it says the asset is
442+
-- unknown we substitute a guaranteed-present stock texture. (Note: the API
443+
-- doesn't verify a known loose file still exists on disk, but an uninstalled
444+
-- addon's path is simply not "known", which is exactly the import case we want.)
445+
-- The SetTexture/SetStatusBarTexture `success` bool does NOT work for this —
446+
-- it returns true for any well-formed path even when the file is absent.
447+
-- Feature-detected: on clients without C_UIFileAsset this is INERT (behaves
448+
-- exactly as before), so it's safe to ship now and self-activates on 12.0.7.
449+
-- ============================================================
450+
-- DF's own bundled default bar texture — ships with the addon, so it's always
451+
-- present when our code runs. This is the "fall back to our default" target.
452+
DF.STOCK_BAR_TEXTURE = "Interface\\AddOns\\DandersFrames\\Media\\DF_Minimalist"
453+
local _df_warnedMissingTexture = {}
454+
455+
-- false -> asset (texture path or fileID) is definitively NOT known to the client
456+
-- true -> known/present
457+
-- nil -> validation API unavailable (caller leaves the texture as-is)
458+
local function textureKnown(asset)
459+
if asset == nil then return nil end
460+
local api = C_UIFileAsset
461+
if not (api and api.IsKnownFile) then return nil end
462+
local ok, known = pcall(api.IsKnownFile, asset)
463+
if not ok then return nil end
464+
return known and true or false
465+
end
466+
467+
local function warnMissingTexture(path)
468+
if not path or _df_warnedMissingTexture[path] then return end
469+
_df_warnedMissingTexture[path] = true
470+
if DF.Debug then DF:Debug("TEXTURE", "Missing texture '%s' — using stock fallback", tostring(path)) end
471+
if not DF._warnedAnyMissingTexture then
472+
DF._warnedAnyMissingTexture = true
473+
print("|cff66ccffDandersFrames|r: a configured texture couldn't be loaded and was replaced with a stock texture. Check your texture settings (an imported profile may reference a texture you don't have).")
474+
end
475+
end
476+
477+
-- StatusBar texture with stock fallback. Returns true if the requested texture
478+
-- loaded, false if the stock fallback was substituted, nil if bar was missing.
479+
function DF:SafeSetStatusBarTexture(bar, path, stock)
480+
if not bar then return end
481+
if textureKnown(path) == false then
482+
bar:SetStatusBarTexture(stock or DF.STOCK_BAR_TEXTURE)
483+
warnMissingTexture(path)
484+
return false
485+
end
486+
bar:SetStatusBarTexture(path)
487+
return true
488+
end
489+
490+
-- Plain Texture region with stock fallback (same semantics).
491+
function DF:SafeSetTexture(region, path, stock)
492+
if not region then return end
493+
if textureKnown(path) == false then
494+
region:SetTexture(stock or DF.STOCK_BAR_TEXTURE)
495+
warnMissingTexture(path)
496+
return false
497+
end
498+
region:SetTexture(path)
499+
return true
500+
end
501+
435502
-- Update only health bar texture
436503
function DF:LightweightUpdateHealthTexture()
437504
local mode = DF.GUI and DF.GUI.SelectedMode or "party"
@@ -442,7 +509,7 @@ function DF:LightweightUpdateHealthTexture()
442509

443510
local function UpdateTex(frame)
444511
if frame and frame.healthBar then
445-
frame.healthBar:SetStatusBarTexture(tex)
512+
DF:SafeSetStatusBarTexture(frame.healthBar, tex)
446513
end
447514
end
448515

Frames/Bars.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ function DF:UpdateAbsorb(frame, testIndex)
630630
barTex:SetDrawLayer("ARTWORK", 2)
631631
end
632632
else
633-
customBar:SetStatusBarTexture(tex)
633+
DF:SafeSetStatusBarTexture(customBar, tex)
634634
local barTex = customBar:GetStatusBarTexture()
635635
if barTex then
636636
barTex:SetHorizTile(false)
@@ -1105,7 +1105,7 @@ function DF:UpdateAbsorb(frame, testIndex)
11051105
if type(texture) == "table" then
11061106
texture = texture.path or "Interface\\TargetingFrame\\UI-StatusBar"
11071107
end
1108-
overflowBar:SetStatusBarTexture(texture)
1108+
DF:SafeSetStatusBarTexture(overflowBar, texture)
11091109

11101110
local color = db.absorbBarColor or {r = 1, g = 1, b = 1, a = 0.7}
11111111
overflowBar:SetStatusBarColor(color.r, color.g, color.b, color.a or 0.7)
@@ -1394,7 +1394,7 @@ function DF:UpdateHealAbsorb(frame, testIndex)
13941394
-- Apply texture only if changed to prevent flickering
13951395
if bar.currentTexture ~= tex then
13961396
bar.currentTexture = tex
1397-
bar:SetStatusBarTexture(tex)
1397+
DF:SafeSetStatusBarTexture(bar, tex)
13981398
local barTex = bar:GetStatusBarTexture()
13991399
if barTex then
14001400
barTex:SetHorizTile(false)
@@ -1673,7 +1673,7 @@ end
16731673
local function StyleHealPredSegment(seg, tex, blendMode, color)
16741674
if seg.currentTexture ~= tex then
16751675
seg.currentTexture = tex
1676-
seg:SetStatusBarTexture(tex)
1676+
DF:SafeSetStatusBarTexture(seg, tex)
16771677
local t = seg:GetStatusBarTexture()
16781678
if t then
16791679
t:SetHorizTile(false); t:SetVertTile(false)
@@ -1886,7 +1886,7 @@ function DF:UpdateHealPrediction(frame, testIndex)
18861886
-- Apply texture
18871887
if bar.currentTexture ~= tex then
18881888
bar.currentTexture = tex
1889-
bar:SetStatusBarTexture(tex)
1889+
DF:SafeSetStatusBarTexture(bar, tex)
18901890
local barTex = bar:GetStatusBarTexture()
18911891
if barTex then
18921892
barTex:SetHorizTile(false)

Frames/Core.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ local function SetMissingHealthBarValue(bar, unit, frame)
155155
if not texture or texture == "" then
156156
texture = db and db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar"
157157
end
158-
bar:SetStatusBarTexture(texture)
159-
158+
DF:SafeSetStatusBarTexture(bar, texture)
159+
160160
-- Update color based on color mode
161161
local colorMode = db and db.missingHealthColorMode or "CUSTOM"
162162
local r, g, b, a

Frames/Create.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ function DF:CreateFrameElements(frame, isRaid)
669669
local padding = db.framePadding or 0
670670
frame.missingHealthBar:SetPoint("TOPLEFT", padding, -padding)
671671
frame.missingHealthBar:SetPoint("BOTTOMRIGHT", -padding, padding)
672-
frame.missingHealthBar:SetStatusBarTexture(db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
672+
DF:SafeSetStatusBarTexture(frame.missingHealthBar, db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
673673
frame.missingHealthBar:SetMinMaxValues(0, 1)
674674
frame.missingHealthBar:SetValue(0)
675675
frame.missingHealthBar:SetReverseFill(true)
@@ -684,7 +684,7 @@ function DF:CreateFrameElements(frame, isRaid)
684684
frame.healthBar = CreateFrame("StatusBar", nil, frame)
685685
frame.healthBar:SetPoint("TOPLEFT", padding, -padding)
686686
frame.healthBar:SetPoint("BOTTOMRIGHT", -padding, padding)
687-
frame.healthBar:SetStatusBarTexture(db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
687+
DF:SafeSetStatusBarTexture(frame.healthBar, db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
688688
frame.healthBar:SetMinMaxValues(0, 1)
689689
frame.healthBar:SetValue(1)
690690

@@ -1321,7 +1321,7 @@ function DF:CreateUnitFrame(unit, index, isRaid)
13211321
local padding = db.framePadding or 0
13221322
frame.missingHealthBar:SetPoint("TOPLEFT", padding, -padding)
13231323
frame.missingHealthBar:SetPoint("BOTTOMRIGHT", -padding, padding)
1324-
frame.missingHealthBar:SetStatusBarTexture(db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
1324+
DF:SafeSetStatusBarTexture(frame.missingHealthBar, db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
13251325
frame.missingHealthBar:SetMinMaxValues(0, 1) -- Will be updated dynamically with UnitHealthMax
13261326
frame.missingHealthBar:SetValue(0)
13271327
frame.missingHealthBar:SetReverseFill(true) -- Fill from right side (where health is missing)
@@ -1337,7 +1337,7 @@ function DF:CreateUnitFrame(unit, index, isRaid)
13371337
frame.healthBar = CreateFrame("StatusBar", nil, frame)
13381338
frame.healthBar:SetPoint("TOPLEFT", padding, -padding)
13391339
frame.healthBar:SetPoint("BOTTOMRIGHT", -padding, padding)
1340-
frame.healthBar:SetStatusBarTexture(db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
1340+
DF:SafeSetStatusBarTexture(frame.healthBar, db.healthTexture or "Interface\\TargetingFrame\\UI-StatusBar")
13411341
frame.healthBar:SetMinMaxValues(0, 1)
13421342
frame.healthBar:SetValue(1)
13431343

Frames/Pets.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,8 @@ function DF:ApplyPetFrameStyle(frame)
475475

476476
-- Update health bar texture - use path directly (dropdown saves paths)
477477
local texture = db.petTexture or "Interface\\TargetingFrame\\UI-StatusBar"
478-
frame.healthBar:SetStatusBarTexture(texture)
479-
frame.healthBar.bg:SetTexture(texture)
478+
DF:SafeSetStatusBarTexture(frame.healthBar, texture)
479+
DF:SafeSetTexture(frame.healthBar.bg, texture)
480480

481481
-- Background color
482482
local bgColor = db.petBackgroundColor or {r = 0.1, g = 0.1, b = 0.1, a = 0.8}

Frames/ReducedMaxHealth.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function DF:UpdateReducedMaxHealth(frame)
8787
texturePath = DF:ResolveMediaTexture(texturePath) or texturePath
8888
end
8989
if texturePath then
90-
bar:SetStatusBarTexture(texturePath)
90+
DF:SafeSetStatusBarTexture(bar, texturePath)
9191
end
9292

9393
local c = db.reducedMaxHealthColor or DEFAULT_BAR_COLOR

Frames/Update.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ function DF:ApplyFrameLayout(frame)
402402
else
403403
-- Textured background - only call SetTexture if texture path changed
404404
if frame.dfCurrentBgTexture ~= bgTexture then
405-
frame.background:SetTexture(bgTexture)
405+
DF:SafeSetTexture(frame.background, bgTexture)
406406
frame.background:SetHorizTile(false)
407407
frame.background:SetVertTile(false)
408408
frame.dfCurrentBgTexture = bgTexture
@@ -456,7 +456,7 @@ function DF:ApplyFrameLayout(frame)
456456
else
457457
-- Textured background - only call SetTexture if texture path changed
458458
if frame.dfCurrentBgTexture ~= bgTexture then
459-
frame.background:SetTexture(bgTexture)
459+
DF:SafeSetTexture(frame.background, bgTexture)
460460
frame.background:SetHorizTile(false)
461461
frame.background:SetVertTile(false)
462462
frame.dfCurrentBgTexture = bgTexture
@@ -760,7 +760,7 @@ function DF:UpdateUnitFrame(frame, source)
760760
-- Textured background - only call SetTexture if texture path changed
761761
-- This prevents flickering on every health update
762762
if frame.dfCurrentBgTexture ~= bgTexture then
763-
frame.background:SetTexture(bgTexture)
763+
DF:SafeSetTexture(frame.background, bgTexture)
764764
frame.background:SetHorizTile(false)
765765
frame.background:SetVertTile(false)
766766
frame.dfCurrentBgTexture = bgTexture

0 commit comments

Comments
 (0)