JukeboxMenu.xaml.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using Content.Shared.Audio.Jukebox;
  2. using Robust.Client.Audio;
  3. using Robust.Client.AutoGenerated;
  4. using Robust.Client.UserInterface;
  5. using Robust.Client.UserInterface.Controls;
  6. using Robust.Client.UserInterface.XAML;
  7. using Robust.Shared.Audio.Components;
  8. using Robust.Shared.Input;
  9. using Robust.Shared.Prototypes;
  10. using Robust.Shared.Timing;
  11. using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
  12. namespace Content.Client.Audio.Jukebox;
  13. [GenerateTypedNameReferences]
  14. public sealed partial class JukeboxMenu : FancyWindow
  15. {
  16. [Dependency] private readonly IEntityManager _entManager = default!;
  17. private AudioSystem _audioSystem;
  18. /// <summary>
  19. /// Are we currently 'playing' or paused for the play / pause button.
  20. /// </summary>
  21. private bool _playState;
  22. /// <summary>
  23. /// True if playing, false if paused.
  24. /// </summary>
  25. public event Action<bool>? OnPlayPressed;
  26. public event Action? OnStopPressed;
  27. public event Action<ProtoId<JukeboxPrototype>>? OnSongSelected;
  28. public event Action<float>? SetTime;
  29. private EntityUid? _audio;
  30. private float _lockTimer;
  31. public JukeboxMenu()
  32. {
  33. RobustXamlLoader.Load(this);
  34. IoCManager.InjectDependencies(this);
  35. _audioSystem = _entManager.System<AudioSystem>();
  36. MusicList.OnItemSelected += args =>
  37. {
  38. var entry = MusicList[args.ItemIndex];
  39. if (entry.Metadata is not string juke)
  40. return;
  41. OnSongSelected?.Invoke(juke);
  42. };
  43. PlayButton.OnPressed += args =>
  44. {
  45. OnPlayPressed?.Invoke(!_playState);
  46. };
  47. StopButton.OnPressed += args =>
  48. {
  49. OnStopPressed?.Invoke();
  50. };
  51. PlaybackSlider.OnReleased += PlaybackSliderKeyUp;
  52. SetPlayPauseButton(_audioSystem.IsPlaying(_audio), force: true);
  53. }
  54. public JukeboxMenu(AudioSystem audioSystem)
  55. {
  56. _audioSystem = audioSystem;
  57. }
  58. public void SetAudioStream(EntityUid? audio)
  59. {
  60. _audio = audio;
  61. }
  62. private void PlaybackSliderKeyUp(Slider args)
  63. {
  64. SetTime?.Invoke(PlaybackSlider.Value);
  65. _lockTimer = 0.5f;
  66. }
  67. /// <summary>
  68. /// Re-populates the list of jukebox prototypes available.
  69. /// </summary>
  70. public void Populate(IEnumerable<JukeboxPrototype> jukeboxProtos)
  71. {
  72. MusicList.Clear();
  73. foreach (var entry in jukeboxProtos)
  74. {
  75. MusicList.AddItem(entry.Name, metadata: entry.ID);
  76. }
  77. }
  78. public void SetPlayPauseButton(bool playing, bool force = false)
  79. {
  80. if (_playState == playing && !force)
  81. return;
  82. _playState = playing;
  83. if (playing)
  84. {
  85. PlayButton.Text = Loc.GetString("jukebox-menu-buttonpause");
  86. return;
  87. }
  88. PlayButton.Text = Loc.GetString("jukebox-menu-buttonplay");
  89. }
  90. public void SetSelectedSong(string name, float length)
  91. {
  92. SetSelectedSongText(name);
  93. PlaybackSlider.MaxValue = length;
  94. PlaybackSlider.SetValueWithoutEvent(0);
  95. }
  96. protected override void FrameUpdate(FrameEventArgs args)
  97. {
  98. base.FrameUpdate(args);
  99. if (_lockTimer > 0f)
  100. {
  101. _lockTimer -= args.DeltaSeconds;
  102. }
  103. PlaybackSlider.Disabled = _lockTimer > 0f;
  104. if (_entManager.TryGetComponent(_audio, out AudioComponent? audio))
  105. {
  106. DurationLabel.Text = $@"{TimeSpan.FromSeconds(audio.PlaybackPosition):mm\:ss} / {_audioSystem.GetAudioLength(audio.FileName):mm\:ss}";
  107. }
  108. else
  109. {
  110. DurationLabel.Text = $"00:00 / 00:00";
  111. }
  112. if (PlaybackSlider.Grabbed)
  113. return;
  114. if (audio != null || _entManager.TryGetComponent(_audio, out audio))
  115. {
  116. PlaybackSlider.SetValueWithoutEvent(audio.PlaybackPosition);
  117. }
  118. else
  119. {
  120. PlaybackSlider.SetValueWithoutEvent(0f);
  121. }
  122. SetPlayPauseButton(_audioSystem.IsPlaying(_audio, audio));
  123. }
  124. public void SetSelectedSongText(string? text)
  125. {
  126. if (!string.IsNullOrEmpty(text))
  127. {
  128. SongName.Text = text;
  129. }
  130. else
  131. {
  132. SongName.Text = "---";
  133. }
  134. }
  135. }