using System.ComponentModel; using System.Runtime.CompilerServices; namespace Futonizer.Models; /// /// Represents one track of a queued MKV file, as shown in the track table. /// The property is user-editable and drives which tracks /// are passed to mkvmerge when stripping. /// public class TrackItem : INotifyPropertyChanged { private bool _copy; public int Id { get; init; } public string Type { get; init; } = string.Empty; public string Codec { get; init; } = string.Empty; public string Language { get; init; } = string.Empty; public string Name { get; init; } = string.Empty; public bool ForcedDisplay { get; init; } /// /// True for the first track of each type group (video/audio/subtitles/ /// chapters) in the track table, computed once when the list is built. /// Used to draw a divider line above the row in the UI. /// public bool IsGroupStart { get; set; } private bool _defaultTrack; /// /// Whether this track should be flagged as the default track of its type /// when stripped. For audio and subtitles this is kept in sync with /// (selecting a track also makes it the default one /// of its type). /// public bool DefaultTrack { get => _defaultTrack; set { if (_defaultTrack == value) return; _defaultTrack = value; OnPropertyChanged(); } } /// /// Text shown in the track table's Name column. /// public string DisplayName => Name; /// /// Video is always kept, and chapters (a synthetic pseudo-track, not a /// real mkvmerge track) are always kept too — neither is user-selectable, /// so their Copy checkbox is shown checked but disabled. /// public bool IsEditable => Type is "audio" or "subtitles"; /// /// Chapters aren't a real track and have no track ID; show a dash /// instead of a meaningless number. /// public string IdDisplay => Type == "chapters" ? "—" : Id.ToString(); public bool Copy { get => _copy; set { if (_copy == value) return; _copy = value; OnPropertyChanged(); } } /// /// Key used to match a track's identity across different queued files /// when propagating an audio/subtitle selection. Matched on "Codec/Name" /// so tracks with the same name but a different codec are treated as /// distinct, even though only the name is shown in the table. /// public string PropagationKey => $"{Codec}/{Name}"; public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] string? name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }