using System.Linq; using Content.Shared.Audio.Jukebox; using Robust.Client.Audio; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared.Audio.Components; using Robust.Shared.Input; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow; namespace Content.Client.Audio.Jukebox; [GenerateTypedNameReferences] public sealed partial class JukeboxMenu : FancyWindow { [Dependency] private readonly IEntityManager _entManager = default!; private AudioSystem _audioSystem; /// /// Are we currently 'playing' or paused for the play / pause button. /// private bool _playState; /// /// True if playing, false if paused. /// public event Action? OnPlayPressed; public event Action? OnStopPressed; public event Action? OnModeChanged; // Frontier public event Action>? OnSongSelected; public event Action? SetTime; private EntityUid? _audio; private float _lockTimer; public JukeboxMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _audioSystem = _entManager.System(); MusicList.OnItemSelected += args => { var entry = MusicList[args.ItemIndex]; if (entry.Metadata is not string juke) return; OnSongSelected?.Invoke(juke); }; PlayButton.OnPressed += args => { OnPlayPressed?.Invoke(!_playState); }; StopButton.OnPressed += args => { OnStopPressed?.Invoke(); }; PlaybackSlider.OnReleased += PlaybackSliderKeyUp; // Frontier: Shuffle & Repeat ShuffleButton.OnToggled += args => { RepeatButton.Pressed = false; OnModeChanged?.Invoke(ShuffleButton.Pressed ? JukeboxPlaybackMode.Shuffle : JukeboxPlaybackMode.Single); }; RepeatButton.OnToggled += args => { ShuffleButton.Pressed = false; OnModeChanged?.Invoke(RepeatButton.Pressed ? JukeboxPlaybackMode.Repeat : JukeboxPlaybackMode.Single); }; // End Frontier: Shuffle & Repeat SetPlayPauseButton(_audioSystem.IsPlaying(_audio), force: true); } public JukeboxMenu(AudioSystem audioSystem) { _audioSystem = audioSystem; } public void SetAudioStream(EntityUid? audio) { _audio = audio; } private void PlaybackSliderKeyUp(Slider args) { SetTime?.Invoke(PlaybackSlider.Value); _lockTimer = 0.5f; } /// /// Re-populates the list of jukebox prototypes available. /// public void Populate(IEnumerable jukeboxProtos) { MusicList.Clear(); var jukeboxProtoList = jukeboxProtos.ToList(); // Frontier: Sort the jukebox list jukeboxProtoList.Sort((p1, p2) => p1.Name.CompareTo(p2.Name)); // Frontier foreach (var entry in jukeboxProtoList) // Frontier: jukeboxProtoList 0f) { _lockTimer -= args.DeltaSeconds; } PlaybackSlider.Disabled = _lockTimer > 0f; if (_entManager.TryGetComponent(_audio, out AudioComponent? audio)) { DurationLabel.Text = $@"{TimeSpan.FromSeconds(audio.PlaybackPosition):mm\:ss} / {_audioSystem.GetAudioLength(audio.FileName):mm\:ss}"; } else { DurationLabel.Text = $"00:00 / 00:00"; } if (PlaybackSlider.Grabbed) return; if (audio != null || _entManager.TryGetComponent(_audio, out audio)) { PlaybackSlider.SetValueWithoutEvent(audio.PlaybackPosition); } else { PlaybackSlider.SetValueWithoutEvent(0f); } SetPlayPauseButton(_audioSystem.IsPlaying(_audio, audio)); } public void SetSelectedSongText(string? text) { if (!string.IsNullOrEmpty(text)) { SongName.Text = text; } else { SongName.Text = "---"; } } // Frontier: Shuffle & Repeat public void UpdateState(BoundUserInterfaceState state) { if (state is not JukeboxInterfaceState convState) return; UpdateJukeboxButtons(convState); } private void UpdateJukeboxButtons(JukeboxInterfaceState state) { ShuffleButton.Pressed = state.PlaybackMode == JukeboxPlaybackMode.Shuffle; RepeatButton.Pressed = state.PlaybackMode == JukeboxPlaybackMode.Repeat; } // End Frontier: Shuffle & Repeat }