180 lines
5.0 KiB
C#
180 lines
5.0 KiB
C#
using Content.Shared.Audio.Jukebox;
|
|
using Robust.Client.Audio;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Audio.Components;
|
|
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!;
|
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
|
|
|
private AudioSystem _audioSystem;
|
|
|
|
|
|
/// <summary>
|
|
/// True if playing, false if paused.
|
|
/// </summary>
|
|
public event Action<bool>? OnPlayPressed;
|
|
public event Action? OnStopPressed;
|
|
public event Action<ProtoId<JukeboxPrototype>>? OnSongSelected;
|
|
public event Action<float>? SetTime;
|
|
|
|
public event Action<ProtoId<JukeboxPrototype>>? OnSongQueueAdd;
|
|
public event Action<int>? OnQueueRemove;
|
|
|
|
private EntityUid? _audio;
|
|
|
|
private float _lockTimer;
|
|
|
|
public JukeboxMenu()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
_audioSystem = _entManager.System<AudioSystem>();
|
|
|
|
CurrentSong.SetOnPressedStop(args =>
|
|
{
|
|
OnStopPressed?.Invoke();
|
|
});
|
|
|
|
CurrentSong.SetOnPressedPlay((song, playPauseState, args) =>
|
|
{
|
|
OnPlayPressed?.Invoke(playPauseState);
|
|
});
|
|
|
|
PlaybackSlider.OnReleased += PlaybackSliderKeyUp;
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Re-populates the list of jukebox prototypes available.
|
|
/// </summary>
|
|
public void Populate(IEnumerable<JukeboxPrototype> jukeboxProtos)
|
|
{
|
|
MusicList.RemoveAllChildren();
|
|
|
|
foreach (var entry in jukeboxProtos)
|
|
{
|
|
// MusicList.AddItem(entry.Name, metadata: entry.ID);
|
|
var songControl = new JukeboxEntry(entry) {EntryType = JukeboxEntry.JukeboxEntryType.List};
|
|
songControl.SetOnPressedPlay((song, _, args) =>
|
|
{
|
|
if (song == null)
|
|
return;
|
|
OnSongSelected?.Invoke(song.ID);
|
|
OnPlayPressed?.Invoke(true);
|
|
});
|
|
|
|
songControl.SetOnPressedQueue((song, args) =>
|
|
{
|
|
if (song == null)
|
|
return;
|
|
OnSongQueueAdd?.Invoke(song.ID);
|
|
});
|
|
|
|
MusicList.AddChild(songControl);
|
|
}
|
|
}
|
|
|
|
public void SetSelectedSong(ProtoId<JukeboxPrototype>? song, float length)
|
|
{
|
|
if (song == null)
|
|
return;
|
|
|
|
if (!_prototype.TryIndex(song, out var songProto))
|
|
return;
|
|
|
|
SongSelected.Text = Loc.GetString("jukebox-menu-selectedsong");
|
|
PlaybackSlider.Visible = true;
|
|
CurrentSong.Visible = true;
|
|
CurrentSong.SetSong(songProto);
|
|
PlaybackSlider.MaxValue = length;
|
|
PlaybackSlider.SetValueWithoutEvent(0);
|
|
}
|
|
|
|
protected override void FrameUpdate(FrameEventArgs args)
|
|
{
|
|
base.FrameUpdate(args);
|
|
|
|
if (_lockTimer > 0f)
|
|
{
|
|
_lockTimer -= args.DeltaSeconds;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Re-populates the queue with avaiable jukebox prototypes.
|
|
/// </summary>
|
|
public void PopulateQueue(IEnumerable<ProtoId<JukeboxPrototype>> queue)
|
|
{
|
|
MusicListQueue.RemoveAllChildren();
|
|
int i = 0;
|
|
foreach (var song in queue)
|
|
{
|
|
if (!_prototype.TryIndex(song, out var songProto))
|
|
continue;
|
|
|
|
i += 1;
|
|
var songControl = new JukeboxEntry(songProto) {EntryType = JukeboxEntry.JukeboxEntryType.Queue};
|
|
MusicListQueue.AddChild(songControl);
|
|
|
|
songControl.SetOnPressedRemove((source, args) =>
|
|
{
|
|
int index = source.GetPositionInParent();
|
|
OnQueueRemove?.Invoke(index);
|
|
});
|
|
}
|
|
}
|
|
|
|
public void SetIsPlaying(bool isPlaying)
|
|
{
|
|
CurrentSong.PlayPauseState = isPlaying;
|
|
}
|
|
}
|