Port instrument menu UI to use XAML (#3066)
This commit is contained in:
committed by
GitHub
parent
afb8e5a782
commit
044040effe
169
Content.Client/Instruments/InstrumentMenu.xaml.cs
Normal file
169
Content.Client/Instruments/InstrumentMenu.xaml.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Client.GameObjects.Components.Instruments;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Client.Utility;
|
||||
using Robust.Client.Audio.Midi;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.Interfaces.UserInterface;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timers;
|
||||
|
||||
namespace Content.Client.Instruments
|
||||
{
|
||||
[GenerateTypedNameReferences]
|
||||
public partial class InstrumentMenu : SS14Window
|
||||
{
|
||||
[Dependency] private readonly IMidiManager _midiManager = default!;
|
||||
[Dependency] private readonly IFileDialogManager _fileDialogManager = default!;
|
||||
|
||||
private readonly InstrumentBoundUserInterface _owner;
|
||||
|
||||
protected override Vector2? CustomSize => (400, 150);
|
||||
|
||||
public InstrumentMenu(InstrumentBoundUserInterface owner)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_owner = owner;
|
||||
|
||||
_owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded;
|
||||
|
||||
Title = _owner.Instrument.Owner.Name;
|
||||
|
||||
LoopButton.Disabled = !_owner.Instrument.IsMidiOpen;
|
||||
LoopButton.Pressed = _owner.Instrument.LoopMidi;
|
||||
StopButton.Disabled = !_owner.Instrument.IsMidiOpen;
|
||||
|
||||
if (!_midiManager.IsAvailable)
|
||||
{
|
||||
Margin.AddChild(new PanelContainer
|
||||
{
|
||||
MouseFilter = MouseFilterMode.Stop,
|
||||
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.Black.WithAlpha(0.90f)},
|
||||
Children =
|
||||
{
|
||||
new Label
|
||||
{
|
||||
Align = Label.AlignMode.Center,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||
StyleClasses = {StyleNano.StyleClassLabelBig},
|
||||
Text = Loc.GetString("MIDI support is currently\nnot available on your platform.")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// We return early as to not give the buttons behavior.
|
||||
return;
|
||||
}
|
||||
|
||||
InputButton.OnToggled += MidiInputButtonOnOnToggled;
|
||||
FileButton.OnPressed += MidiFileButtonOnOnPressed;
|
||||
LoopButton.OnToggled += MidiLoopButtonOnOnToggled;
|
||||
StopButton.OnPressed += MidiStopButtonOnPressed;
|
||||
}
|
||||
|
||||
private void InstrumentOnMidiPlaybackEnded()
|
||||
{
|
||||
MidiPlaybackSetButtonsDisabled(true);
|
||||
}
|
||||
|
||||
public void MidiPlaybackSetButtonsDisabled(bool disabled)
|
||||
{
|
||||
LoopButton.Disabled = disabled;
|
||||
StopButton.Disabled = disabled;
|
||||
}
|
||||
|
||||
private async void MidiFileButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi"));
|
||||
var file = await _fileDialogManager.OpenFile(filters);
|
||||
|
||||
// The following checks are only in place to prevent players from playing MIDI songs locally.
|
||||
// There are equivalents for these checks on the server.
|
||||
|
||||
if (file == null) return;
|
||||
|
||||
/*if (!_midiManager.IsMidiFile(filename))
|
||||
{
|
||||
Logger.Warning($"Not a midi file! Chosen file: {filename}");
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (!PlayCheck())
|
||||
return;
|
||||
|
||||
MidiStopButtonOnPressed(null);
|
||||
var memStream = new MemoryStream((int) file.Length);
|
||||
// 100ms delay is due to a race condition or something idk.
|
||||
// While we're waiting, load it into memory.
|
||||
await Task.WhenAll(Timer.Delay(100), file.CopyToAsync(memStream));
|
||||
|
||||
if (!_owner.Instrument.OpenMidi(memStream.GetBuffer().AsSpan(0, (int) memStream.Length)))
|
||||
return;
|
||||
|
||||
MidiPlaybackSetButtonsDisabled(false);
|
||||
if (InputButton.Pressed)
|
||||
InputButton.Pressed = false;
|
||||
}
|
||||
|
||||
private void MidiInputButtonOnOnToggled(BaseButton.ButtonToggledEventArgs obj)
|
||||
{
|
||||
if (obj.Pressed)
|
||||
{
|
||||
if (!PlayCheck())
|
||||
return;
|
||||
|
||||
MidiStopButtonOnPressed(null);
|
||||
_owner.Instrument.OpenInput();
|
||||
}
|
||||
else
|
||||
_owner.Instrument.CloseInput();
|
||||
}
|
||||
|
||||
private bool PlayCheck()
|
||||
{
|
||||
var instrumentEnt = _owner.Instrument.Owner;
|
||||
var instrument = _owner.Instrument;
|
||||
|
||||
_owner.Instrument.Owner.TryGetContainerMan(out var conMan);
|
||||
|
||||
var localPlayer = IoCManager.Resolve<IPlayerManager>().LocalPlayer;
|
||||
|
||||
// If we don't have a player or controlled entity, we return.
|
||||
if (localPlayer?.ControlledEntity == null) return false;
|
||||
|
||||
// If the instrument is handheld and we're not holding it, we return.
|
||||
if ((instrument.Handheld && (conMan == null
|
||||
|| conMan.Owner != localPlayer.ControlledEntity))) return false;
|
||||
|
||||
// We check that we're in range unobstructed just in case.
|
||||
return localPlayer.InRangeUnobstructed(instrumentEnt,
|
||||
predicate: (e) => e == instrumentEnt || e == localPlayer.ControlledEntity);
|
||||
}
|
||||
|
||||
private void MidiStopButtonOnPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
MidiPlaybackSetButtonsDisabled(true);
|
||||
_owner.Instrument.CloseMidi();
|
||||
}
|
||||
|
||||
private void MidiLoopButtonOnOnToggled(BaseButton.ButtonToggledEventArgs obj)
|
||||
{
|
||||
_owner.Instrument.LoopMidi = obj.Pressed;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user