Raster static text on UI-thread changes and reuse the same transparent BGRA frame in preview and all compositor paths. Cache text frame identity in the frame-pump signature and invalidate static bakes on edits. Follow OBS text-source conventions: https://obsproject.com/kb/text-sources
62 lines
2.2 KiB
C#
62 lines
2.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ytLive.Models;
|
|
using ytLive.Services;
|
|
|
|
namespace ytLive.ViewModels;
|
|
|
|
public partial class MainViewModel
|
|
{
|
|
private readonly TextOverlayRenderer _textOverlayRenderer = new();
|
|
private readonly HashSet<Source> _wiredTextOverlays = new();
|
|
|
|
private void UpdateConfiguredTextOverlays()
|
|
{
|
|
var sources = Scenes.SelectMany(scene => scene.Elements).OfType<Source>()
|
|
.Where(source => source.Type == SourceType.TextOverlay).ToArray();
|
|
RetainTextOverlaySubscriptions();
|
|
_textOverlayRenderer.Retain(sources);
|
|
foreach (var source in sources)
|
|
{
|
|
if (source.Width <= 0) source.Width = 900;
|
|
if (source.Height <= 0) source.Height = 140;
|
|
WireTextOverlaySource(source);
|
|
_textOverlayRenderer.UpdatePreview(source);
|
|
}
|
|
}
|
|
|
|
private void WireTextOverlaySource(Source source)
|
|
{
|
|
if (_wiredTextOverlays.Add(source))
|
|
source.PropertyChanged += OnElementPropertyChanged;
|
|
}
|
|
|
|
private void UpdateTextOverlayPreview(Source source) => _textOverlayRenderer.UpdatePreview(source);
|
|
|
|
private void RemoveTextOverlayPreview(Source source)
|
|
{
|
|
if (_wiredTextOverlays.Remove(source))
|
|
source.PropertyChanged -= OnElementPropertyChanged;
|
|
_textOverlayRenderer.Remove(source);
|
|
}
|
|
|
|
private void RetainTextOverlaySubscriptions()
|
|
{
|
|
var active = Scenes.SelectMany(scene => scene.Elements).OfType<Source>()
|
|
.Where(source => source.Type == SourceType.TextOverlay).ToHashSet();
|
|
foreach (var source in _wiredTextOverlays.ToArray())
|
|
if (!active.Contains(source))
|
|
RemoveTextOverlayPreview(source);
|
|
}
|
|
|
|
private void OnTextOverlayPropertyChanged(Source source, string? propertyName)
|
|
{
|
|
if (propertyName is nameof(Source.TextContent) or nameof(Source.TextFontFamily)
|
|
or nameof(Source.TextFontSize) or nameof(Source.TextColor) or nameof(Source.TextBold)
|
|
or nameof(Source.TextItalic) or nameof(Source.TextUnderline) or nameof(Source.TextAlignment)
|
|
or nameof(Source.Width) or nameof(Source.Height))
|
|
UpdateTextOverlayPreview(source);
|
|
}
|
|
|
|
}
|