Files
RobustToolbox/Robust.Client/Replays/UI/ReplayControlWidget.cs

112 lines
4.4 KiB
C#

using System;
using Robust.Client.AutoGenerated;
using Robust.Client.Replays.Playback;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Input;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Timing;
namespace Robust.Client.Replays.UI;
/// <summary>
/// This is a simple replay demonstration widget that has basic controls for manipulating a replay.
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class ReplayControlWidget : UIWidget // AKA Tardis - The funny time control box.
{
[Dependency] private IReplayPlaybackManager _playback = default!;
[Dependency] private IConfigurationManager _cfg = default!;
public const string TimeFormat = @"hh\:mm\:ss";
/// <summary>
/// Number of ticks to jump by when using the forward/backward buttons.
/// </summary>
public int SmallJump = 1;
/// <summary>
/// Number of ticks to jump by when using the fast forward/backward buttons.
/// </summary>
public int BigJump = 10;
public ReplayControlWidget()
{
RobustXamlLoader.Load(this);
PlayButton.OnToggled += _ => _playback.Playing = !_playback.Playing;
ResetButton.OnPressed += _ => _playback.SetIndex(0);
SkipForwardButton.OnPressed += _ => _playback.SetIndex(SmallJump + (_playback.Replay?.CurrentIndex ?? 0));
SkipBackButton.OnPressed += _ => _playback.SetIndex(-SmallJump + (_playback.Replay?.CurrentIndex ?? 0));
SkipForwardManyButton.OnPressed += _ => _playback.SetIndex(BigJump + (_playback.Replay?.CurrentIndex ?? 0));
SkipBackwardManyButton.OnPressed += _ => _playback.SetIndex(-BigJump + (_playback.Replay?.CurrentIndex ?? 0));
StopButton.OnPressed += _ => _playback.StopReplay();
DynamicScrubbingCheckbox.Pressed = _cfg.GetCVar(CVars.ReplayDynamicalScrubbing);
DynamicScrubbingCheckbox.OnToggled += args => _cfg.SetCVar(CVars.ReplayDynamicalScrubbing, args.Pressed);
TickSlider.OnKeyBindUp += args =>
{
if (args.Function != EngineKeyFunctions.Use)
return;
_playback.ScrubbingTarget = null;
var time = TimeSpan.FromSeconds(TickSlider.Value);
_playback.SetTime(time);
};
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_playback.Replay is not { } replay)
{
return;
}
TickSlider.MinValue = 0;
TickSlider.MaxValue = (float)replay.ReplayTime[^1].TotalSeconds;
_playback.ScrubbingTarget = null;
var index = replay.CurrentIndex;
if (!TickSlider.Grabbed)
{
TickSlider.SetValueWithoutEvent((float)replay.CurrentReplayTime.TotalSeconds);
}
else
{
var time = TimeSpan.FromSeconds(TickSlider.Value);
index = Array.BinarySearch(replay.ReplayTime, time);
if (index < 0)
index = Math.Max(0, ~index - 1);
if (_cfg.GetCVar(CVars.ReplayDynamicalScrubbing))
_playback.ScrubbingTarget = index;
}
var percentage = (100 * TickSlider.GetAsRatio()).ToString("F2");
var maxIndex = Math.Max(1, replay.Count - 1);
var state = replay.GetState(index);
var replayTime = TimeSpan.FromSeconds(TickSlider.Value);
var end = replay.Duration == null ? "N/A" : replay.Duration.Value.ToString(TimeFormat);
IndexLabel.Text = Loc.GetString("replay-time-box-index-label",
("current", index), ("total", maxIndex), ("percentage", percentage));
TickLabel.Text = Loc.GetString("replay-time-box-tick-label",
("current", state.ToSequence), ("total", replay.LastTick), ("percentage", percentage));
TimeLabel.Text = Loc.GetString("replay-time-box-replay-time-label",
("current", replayTime.ToString(TimeFormat)), ("end", end), ("percentage", percentage));
var serverTime = (replayTime + replay.StartTime).ToString(TimeFormat);
string duration = replay.Duration == null ? "N/A" : (replay.Duration + replay.StartTime).Value.ToString(TimeFormat);
ServerTimeLabel.Text = Loc.GetString("replay-time-box-server-time-label",
("current", serverTime), ("end", duration), ("percentage", percentage));
PlayButton.Pressed = _playback.Playing;
}
}